我们都被告知,并且倾向于认为,失败是一件不好的事情。
本次我们来开一个新坑,聊聊服务器分布式架构的那点事 。首先看看微服务管理中的服务依赖管理。
微服务
经典的分布式架构是典型三层架构:
各层各司其职:
- 负载均衡服务器接受大量客户端的连接
- 应用服务器集群处理客户端的逻辑请求
- 存储层在最后,供应用服务器存储数据,存储层往往又分为缓存和数据库,需要一定的缓存策略保证数据的写入性能和一致性
随着项目规模的提升和理念发展,原有经典架构遇到了问题。
- 项目规模提升,一个大团队可能几十、几百甚至上千人,不太可能将所有业务放在一个应用服务中处理,怎么合作开发,提高开发效率是个大问题
- 不同团队熟悉的技术栈和语言不同,需要有区分又要能合作
- 产品面对的用户数量庞大,业务众多,客观上需要从业务上进行拆分,出问题时不能影响所有业务及所有用户
于是,满足这些需求的微服务出现。
有了微服务:
- 大的团队可以各自负责一部分服务,互相之间没有耦合
- 不同团队可以使用不同的语言或技术栈,通过网络来互相通信
- 部分服务出现问题,不影响其他服务,也只影响一部分用户
游戏服务器在做架构设计的时候也大量应用了微服务的思想。
服务器可以将很多功能拆成了一个个微服务,各个微服务组合给玩家提供服务,典型的有 game、battle、guild、social、rank、name、mail 等,分别提供基础游戏逻辑、战斗、工会、社交、排行、名字、邮件服务。
微服务架构解决了我们上面提到的问题,但是其本身也新增了一堆问题,而对于这些新增的问题,还会衍生出更多的子问题,这就需要我们不断地用各式各样的技术和手段来解决这些问题。所谓任何技术方案都不会是银弹,都是处理问题的 trade-off:权衡。
本文要讨论的依赖管理就是其中的一个问题:
在之前的经典分层分布式架构中,应用服务器内部的状态由其构成的多个模块来做协调,都是在服务内部;
到了微服务架构中,服务之间是相互独立的,微服务之间需要通过网络通信来等待或者通知自身的状态,可能会有互相依赖的情况,这就需要依赖管理。
微服务状态
一个微服务进程对外服务之前,需要做一些事情,在这些事情做完之后才可以正常服务。在做每件事情时,就会处于不同的状态。
一个典型的微服务在其整个生命周期内的状态可能有:
- 初始状态
- 等待服务状态。因为有个进程涉及主备,备进程通常处于等待状态。
- 组网状态
- 等待依赖的服务状态
- 加载数据状态
- 可服务状态
- 热更新状态
- 准备下线状态
- 停止服务状态
为什么要设计不同状态呢?
-
比如微服务之间 TCP 连接组网还未完成,如果要去 DB 微服务加载需要的数据,必然失败;
-
某微服务还未进入可对外服务状态,其他服的请求就过来了,很可能发生异常;
-
某 A 微服务依赖的 B、C 微服务还未启动或未准备好,从 A 到 B、C 的请求,必然失败或异常;
-
整个服务器系统还未进入可对外服务状态,玩家进来了,很可能发生异常;
依赖管理
微服务之间是存在依赖关系的。
举个很简单的例子,gateserver 是网关服务器,在对玩家开放之前,必须等待 gameserver 处于可服务状态。因此我们可以配置其依赖关系:
类似的,gameserver 上承担主逻辑,其上的玩法依赖于其他微服务,如战斗服务、工会服务、邮件服务、数据存储服务等。
如何查询以及标记依赖关系呢?
比较直观的想法是直接通过消息来发起查询及同步。
但是,很多服务不是直连的,可能通过 proxy 转发,发消息及互相同步(如 gossip 协议)会比较繁琐。
一个比较合理的方式是借助公用的第三方组件来做同步。我们可以借助服务发现组件(之后的文章会讨论),不管什么服务及互相之间的连接关系,都统一向服务发现写入自己及定时查询所依赖的服务的状态:
状态切换流程
单个微服务内部状态的切换流程如下:
业务钩子
进程状态的流程切换是统一的,不可更改。
很多情况下,上层的业务也需要依赖该微服务当前的状态:例如,一个模块可能需要知道什么时间适合去发起该模块的数据拉取请求。
为了方便业务使用,各个状态在进入前,会提供业务钩子(hook) 给各个业务订阅自己要做的逻辑。例如:
Data 订阅自己的表格同步逻辑:
Go
commonfsm.SubscribeLoad(func() error {
// load data logic
...
})
Game 订阅对外服务时的逻辑:
C++
CCommonFsm::Instance()->SubscribeInService([] {
// logic business, timer logic
// ...
})
好了,有关微服务中的服务依赖管理,我们就说这么多,希望能为你提供一点参考。希望你方便的话点个免费的赞,感谢!
作者:我是码财小子,会点编程代码,懂些投资理财;期待你的关注,不要错过我后续的文章更新。