服务治理
服务治理应该关注下面的几个问题:
- 服务关键程度
- 服务依赖关系
- 服务发现
- 整个架构的版本管理
- 服务应用生命周期全管理
服务关键程度和服务的依赖关系
服务的关键程度跟技术没啥关系,还是需要架构师本身对于技术的了解去设定,比如某个业务为该项目的核心操作,核心业务,那么这个服务必然就是关键技术,比如某个服务只是一种辅助方案,比如是一个数据分析的服务,那么它必定被划分为非关键服务。
微服务是讲究任何服务之间都不应该有依赖关系,但是实际上某些底层的公有服务不可避免的被其它服务使用,所以这只是一个理想的状态,不过该公有服务必须健壮,否则该调用链条上的所有服务都将极大的受到影响,所以我们要梳理服务的调用链条,必须降低服务的依赖广度和深度,最底线的服务依赖关系是,绝对不要有依赖环这会带来极强的耦合关系,非常可能出现递归错误
通常我们使用依赖倒置的设计模式 (通过抽象解耦模块间的依赖关系,使系统更灵活、可维护) 去规避依赖环这个问题,比如引入一个第三方中间件,例如消息队列,数据库等去解耦两者的依赖关系。
我们可以使用链路追踪来查看服务调用关系,来规避服务的依赖关系。
服务状态和生命周期的管理
我们需要一个服务注册的组件去管理服务的状态,以及服务的生命周期。因为服务是是非常动态的,有的服务会新加进来,有的会离开,有的会增加更多的实例,有的会减少,有的服务在维护过程中 (发布、伸缩等)
我们需要注册中心 (实现服务发现的关键组件) 去管理整个架构中有多少种服务?这些服务的版本是什么样的?每个服务的实例数有多少个,它们的状态是什么样的?每个服务的状态是什么样的?是在部署中,运行中,故障中,升级中,还是在回滚中,伸缩中,或者是在下线中。
服务的生命周期通常有以下状态:
- Provision,代表在供应一个新的服务;
- Ready,表示启动成功了;
- Run,表示通过了服务健康检查;
- Update,表示在升级中;
- Rollback,表示在回滚中;
- Scale,表示正在伸缩中 (可以有 Scale-in 和 Scale-out 两种);
- Destroy,表示在销毁中;
- Failed,表示失败状态。
更多信息可以查看服务发现这一章节
整个架构的版本管理
在整个架构中,我们不仅要在各个服务中制定版本控制,比如服务 A,本身版本号是多少,它的依赖是多少,这属于项目版本,同时整个架构我们也需要制定一个版本,比如架构版本号,A 服务 1.30 版本依赖 B 服务 1.11 版本,A 服务 2.10 版本依赖 B 服务 2.13 版本,当 A 服务回滚时,相应的 B 服务也是要根据规则回滚的,虽然我们不希望多服务之间有依赖,不过还是那句话,没有依赖基本上不太可能,所以做好整个架构的版本控制还是有必要的。
整个架构版本控制基本上我们要记录以下内容
- 各个服务的软件版本
- 各个服务的运行环境,多少 CPU 环境变量,内存,文件系统,可以运行的节点等
- 服务运行的最大和最小的实例
资源 / 服务调度
资源调度的核心意义就是让各个服务按照一定的规则进行合理的运行,让不同的服务进行协同工作。
服务状态的维持和拟合
服务的状态不是值得服务中数据的状态,比如你输出的 API 数值是多少啊,这个跟服务状态无关,服务状态指的就是服务本身的状态,比如服务是否在运行中,服务是否在维护中,服务是否在升级中,服务是否在回滚中,服务是否在伸缩中,服务是否在销毁中等。
服务的运行状态一般分为两种情况,首先就是非预期的状态,比如你并没有回滚,并没有升级,并没有做任何的操作,你只是期待它的状态是运行中,结果,它的状态变成了故障中,那么我们就需要控制器在对于某个服务的一些实例进行监控时,发现不健康的实例直接剔除,然后新建来维持正常的服务状态。
另外一种状态是预期状态,比如服务的升级,或者回滚,通常我们改变服务的众多实例的状态时,无法一蹴而就,而是慢慢的改变,这个慢慢改变的过程其实就是拟合,拟向我们要的状态,比如我们要升级,那么拟合的过程就是一点一点的去改变某个服务的众多节点实例,按照多个顺序的步骤去改变,直到全部改变完成,就是完成了拟合。
比如我们要对某个服务进行弹性伸缩时,我们需要多个步骤去拟合:
- 先扩展出几个节点
- 往上面部署服务实例
- 启动服务
- 检查服务状态
- 把新扩展的服务实例节点添加到注册中心中进行去提供服务。
k8s 控制器的设计就是使用了状态的维持和拟合,整个思路就是上面那个描述。
服务的弹性伸缩和故障迁移
拥有服务状态维持和拟合功能之后,我们就可以通过这两个功能去实现服务的弹性伸缩和故障迁移
服务伸缩更加复杂的操作如下:
- 底层资源的伸缩
- 服务的自动化创建和部署
- 服务的健康检查
- 服务发现操作
- 流量的控制
对于故障转移,通常有两种模式,1 就是必须救活该服务,2 就是直接舍弃某个服务实例,然后重新部署一个服务节点。
- 救活模式:服务的监控报警,服务的重新启动
- 舍弃模式::服务的监控报警,服务的资源申请,服务的自动化部署,服务发现的注册,以及服务的流量调度
实际上这些操作根本无需我们自己操作,k8s 已经完美的解决了这些问题。
服务工作流和编排
服务编排是指将多个服务按照一定的业务逻辑和顺序进行协调执行的过程。它可以帮助我们实现复杂的业务流程自动化,提高系统的灵活性和可扩展性。
通常如果是简单的编排,你可以使用一个消息队列作为编排,稍微复杂一点,你可以使用一个 API 网关去做编排。
但是实际上你如果使用了 k8s,那么你其实不需要去考虑编排的问题,k8s 已经帮你实现了编排
更多的内容可以参考服务编排这一章节