给微服务一个定义吧,普遍认为的微服务就是把什么订单、用户等等系统拆分出来当作一个独立的项目来开发和部署,但是需要注意这个“拆分”只是逻辑上的。
比如我在开发的时候将所有的服务都放在一个项目里面,然后最终只打包出一个可执行文件来,分别在 ABC 机器上面进行部署,然后在 nginx 上面针对请求的 URL 路径转发到不同的机器上。我可以在 ABC 机器上面都分别配置不同数据库,毕竟这台机器只负责部分子集,只会操作部分的数据表,这样一来出现的一个问题就是 ABC 之间数据不互通了,比如订单需要查询用户信息,调用 UserService ,UserService 将不会查询到用户数据,因为这些数据存在于另一台机器和另一个数据库上,一种办法是 ABC 三台机器使用同一个数据库,这样可以解决数据互通的问题。注意自始至终我没有使用到 RPC 以及消息队列,我只是将同一个程序部署到了三台机器上,每一个机器负责部分的 URL 请求,你说这算不算是微服务呢?
如果你认为不算,我们可以改造一下,当某一个机器调用 XXXService.doSomething()的时候,实现不再是通过 JVM 进程内直接调用对象方法,而是通过构造 HTTP 请求另外一台专门负责这服务的机器来进行处理,这样一来,我们就可以将 ABC 三台机器又恢复到使用各自独立的数据库。如果我们拆分得足够好,三台机器应该至始至终只会生产和查询自己负责的那几张表。你说这算不算是一种微服务呢?
注意不管我如何部署,我们的开发结构仍然是一个单体的大项目,所有的代码在变更以后都需要重新打包然后部署到三台机器上面,但是如果我只修改了 A 机器负责的功能,我可以只更新 A 机器那一份,只要接口没有变动,其他两台机器仍然可以正常请求。
既然 ABC 都只负责部分功能,那为什么不在开发的时候就建立 3 个项目呢?这样岂不是更加清晰吗?的确可以这么做,但是我想说的是这样并不是必须的,或者说这不是重点,那么重点是什么?重点就是你如何确定这是 3 个项目而不是 4 个或者 5 个呢?是根据有 3 台机器我们就得有 3 个项目吗?所以重点就是如何找到进行拆分背后所隐含的那些逻辑,这些逻辑就是你的业务组织方式。
早前,我以为开发微服务就是把各种 Service 拆分出来当作一个独立的进程,使用独立的数据库,然后通过 RPC 进行相互调用,成功的把的注意力集中到了各种注册中心,网关,配置中心等等令人眼花缭乱的东西上面去了。在经历各种各样的填坑之后,回过头来再想一下,如果我只是作为一名开发,真的有必要去了解这些东西吗?我把大量的时间浪费在了去研究这些鬼东西上,反而把应该排在第一位的需求给丢到了一边。当服务网格和容器化出现以后,我对微服务这个词有了一些不一样的定义,说到底微服务终究不过是一种部署策略,它不是什么开发架构,它只是一系列指导如何正确开发服务的约定和理念,有了这些理念,我们就可以更容易的开发出适配部署运维的应用服务。微服务的终极目标,不是教我们如何用什么开发框架,用什么中间件,而是为了实现如何使资源利用得更加合理,更加有弹性,更加可伸缩。
夏新 F9 ,6.2 元包邮,2000 毫安电仓,耳机电量连续使用 5 小时。
每天撸一管算不算是一种运动呢,排泄一下应该还是挺有用处的,雄性激素过旺导致我头发溢脂性脱发了,发际线快要变成 M 形状了。
我之前买了一个背包,结果用了一个月之后拉链坏掉了,觉得扔掉之后很可惜,然后我在网上买了十几米的拉链(几块钱包邮),自己一针一线的给换了,除了边角不好缝,其他的还好。花了 3 天时间缝完了,现在使用良好。
事务是基于链接的,也就是说一旦你开启了一个事务,并且希望接下来的调用使用同一个事务,那么就必须使用同一个链接,就必须要把这个链接保存到一个地方,让所有使用数据库的方法都能够以一种相同的方式获取一个链接。
在 Java 中可以使用 ThreadLocal 来保存线程安全的变量,在当前线程的执行过程中,获取到同一个链接实例。如果是异步的,那就必须要考虑到链接的创建与提交,也就是要明确在什么时候开始,什么时候结束,Spring 的注解实现基于 AOP 的拦截,在“同步方法”调用之前开启事务,调用之后结束事务,它在背后实现了我上面第一段说的那些内容。
所以在没有 ThreadLocal 可以使用的时候,你必须要将一个链接进行传递,比如将链接封装到一个 Context 结构中,设计出一套接口标准,让所有使用数据库的代码都遵循这一套接口。不仅如此,还需要考虑到“同步”与“异步”的使用同一个链接将会带来怎样的影响,因为协程本质上也是在一个线程上运行,当多个协程同时运行在不同的线程时,就需要考虑到并发问题,因此不太建议“异步”使用一个事务。我对 Go 不太熟悉,但是背后的逻辑应该是以上这些内容。
看情况
如果大多数情况令牌都足够充裕,第二种实际上是更好的做法,因为直接写了,相比第一种,少了一个读的操作。
如果大多数情况下令牌不够充裕,那么第二种相比第一种多了一个写的操作。
但是很显然,我们大概率无法提前得知哪种情况才是相对常见的,我个人的话会选择第一种。
你有没有想过,有时候可能并不是单纯的技术原因所导致的,而是一次又一次变形的需求?层层加码,而又没有时间回过头来梳理和重构,必定会导致这些问题。
吃褪黑素+1 ,不过第二天起床感觉有点怪怪的,就感觉大脑空白
如果我们的眼光只局限在技术层面,那么 DDD 对你而言有用的就是战术模式那一部分,也就是编码的那一部分。如果我们把眼光放高一些,着手解决整个产品研发生命周期的效率方面,或者 DDD 就能帮大忙。这不仅仅使我们工作更加轻松,更加快乐,也使得我们不会把时间浪费在一些经常反复出现并且很愚蠢的事情上面。当然这个愿望很美好,但是不一定每个人都想做得这么美好。
总的来说,DDD 分为两个部分,一个是技术实践的战术模式,一个是工程架构的战略模式。
其中,战术模式仅作为实现的部分参考,总结的是以面向对象范式编程语言的一些常用技巧与原则,提炼出了一些可以跟非技术人员沟通的构建单元,也就是你可以跟产品直接聊的一些东西,比如实体、值对象、仓库等等。
其实最重要的是战略模式,这部分也是大多数接触 DDD 的人觉得云雾缭绕的东西,看不见摸不着。团队规模小了,搞这些觉得繁琐,团队规模大了,面对已经成熟的 CRUD 基本上都有一套成熟的流程方案了。所以这个东西真正有价值的还是回归本质,解决软件核心中的复杂性。
首先你得是一个团队,否则的话一个人还搞什么 DDD 对吧?其次对团队里面的人也要有一定的要求,起码在沟通上,要明确价值。也就是说哪些信息对于不同岗位的人来说是明确的,是可以沟通的和达成共识的,哪些信息对开发或者产品来说就是废话,要把能够体现出真正用意的这部分提炼出来,在整个团队中进行传播和理解。
其次,有了高效的沟通和统一的理解以后,才能对同一个事物进行拓展(研发),需要在前者的基础之上,搭建一套能够迅速有效解决问题的工作流程,对产品进行高效的迭代。DDD 的战略部分就是基于前者,然后再结合一些准则和经验,帮助你如何解决更大规模的软件工程问题。
以上这些当然都是很美好的初衷,但是我个人认为,关键变量不在于每次迭代能否更进一步,而在于对人的管理,什么意思呢?人的不确定性才是最大的不确定性,人这个变量的影响范围如果能够控制住,培训也好,工作范围的划分也好,只要能够达到一种“柔性”的状态,终归会回归正轨。
说得有点多了,尽信书,不如无书,要有自己的思考。
nosql 大多都是分布式数据库,如果引入自增的这种特性,意味着每一次插入都需要协调维护一个计数器,这会引入额外的同步开销,因此最好是自己在应用层去维护这个计数器,而不是依靠数据库本身提供类似的功能。
语言用 C++是有优势,但是相比较之下,良好的架构更加重要,要兼顾到日常逻辑开发的便利性,如何权衡取决于公司的用人成本。用 Java 配合 Netty 已经足够承载绝大多数游戏类型了,并且招人也很方便。
游戏服务端一般是有状态的,而 web 开发大多数是无状态的,有状态就意味着容易出现单点事故,比如网络不可靠,机房出现故障,服务端宕机等等,因此就需要通过日志的方式来存储状态变更操作,尽量减少事故带来的影响。类似于 redis 的 AOF ,mysql 的 binlog 。
要知道大多数在线游戏后端主要是计算密集型的应用,跟 web 开发的区别之一就在于基本上所有的状态都会保存在进程内存中,目的就是尽量避免 IO 操作。数据库的作用仅仅只是用于存档落地,甚至简单的来讲都可以不要数据库,直接二进制文件也可以。比如我经常在开发调试的过程中将整个玩家对象序列化为一个 JSON 文本,特别方便用于测试的时候,设置各种玩家的快照还原。
还有很多关于游戏后端开发的知识要点,一次也说不完,比如线程模型,元数据(配置)管理,网络 IO ,二进制消息协议,GM 管理后台,第三方系统集成等等,是一个很庞大的内容。
值得庆幸的是,随着用户的爆炸增长,现代的服务部署以及运维都比以前要好上太多了,使用云服务和容器成本更低,更有保障,但一切的前提是要根据游戏类型选择合适的技术架构。
我用的阿里云的,223.5.5.5 、223.6.6.6 ,有没有大佬说一下优缺点?
如果你的表有几千万的数据,并且值是稀疏的,可枚举的,使用 int 会比 varchar 要少占用很多的存储空间,量变决定质变。
干嘛一定要刻意的去戒呢,想起来了就放下嘛,主要是怕想不起来,比如在一条腿上面系上一本书啥的。
如果是游戏,还需要出版号,否则不能进行收费,这个已经很久没有发了。