(5)分布式系统关键技术:服务调度

概要:

一、服务关键程度和服务的依赖关系、

二、服务状态和生命周期的管理、

三、整个架构的版本管理、

四、资源 / 服务调度(服务状态的维持和拟合、弹性伸缩和故障迁移、工作流和编排)

一、服务关键程度和服务的依赖关系

服务治理上的一些关键技术以下几点:

    服务关键程度。

    服务依赖关系。

    服务发现。

    整个架构的版本管理。

    服务应用生命周期全管理。

服务关键程度和服务的依赖关系“没有依赖,就没有伤害”。传统的SOA 希望通过 ESB 来解决服务间的依赖关系,微服务中希望服务间是没有依赖的,而让上层或是前端业务来整合这些个后台服务。只能是降低服务依赖的深度和广度Spring boot 的微服务开发框架给开了一个好头。千万不要有依赖环,极强的耦合,会导致服务部署相当复杂和难解,而且会导致无穷尽的递归故障和一些你意想不到的的问题。

解决服务依赖环的方案一般是,依赖倒置的设计模式。使用第三方。比如,订阅或发布消息到一个消息中间件,或是把其中的依赖关系抽到一个第三方的服务中,由这个第三方的服务来调用。

二、服务状态和生命周期的管理

有了上面这张关联地图后,还需要服务发现的中间件,来知道这么几个事:

    整个架构中有多少种服务?

    这些服务的版本是什么样的?

    每个服务的实例数有多少个,它们的状态是什么样的?

    每个服务的状态是什么样的?是在部署中,运行中,故障中,升级中,还是在回滚中,伸缩中....

有了这些服务的状态和运行情况之后,你就需要对这些服务的生命周期进行管理了。服务的生命周期通常会有以下几个状态:

    Provision,代表在供应一个新的服务;

    Ready,表示启动成功了;

    Run,表示通过了服务健康检查;

    Update,表示在升级中;

    Rollback,表示在回滚中。

    Scale,表示正在伸缩中(可以有 Scale-in 和 Scale-out 两种)。

    Destroy,表示在销毁中。

    Failed,表示失败状态。

有服务的状态和生命周期的管理,以及服务的重要程度和服务的依赖关系,再加上一个服务运行状态的拟合控制(后面会提到),就有了管理整个分布式服务的手段了。纷乱无比的世界就可以管理起来了。

三、整个架构的版本管理

需要一个架构的版本,控制版本兼容。比如,A服务的 1.2 版本只能和 B 服务的 2.2 版本一起工作,A 服务的上个版本 1.1 只能和 B 服务的 2.0 一起工作。这就是版本兼容性。这样,如果我们要回滚一个服务的版本,就可以把与之有版本依赖的服务也一起回滚掉。需要一个架构的 manifest,一个服务清单包括但不限于:

    服务的软件版本;

    服务的运行环境——环境变量、CPU、内存、可以运行的结点、文件系统等;

    服务运行的最大最小实例数。

每一次对这个清单的变更都需要被记录下来,算是一个架构的版本管理。而我们上面所说的那个集群控制系统需要能够解读并执行这个清单中的变更,以操作和管理整个集群中的相关变更。

四、资源 / 服务调度

服务和资源的调度有点像操作系统。操作系统一方面把用户进程在硬件资源上进行调度,另一方面提供进程间的通信方式,可以让不同的进程在一起协同工作。主要有以下一些关键技术:

(1)服务状态的维持和拟合。

(2)服务的弹性伸缩和故障迁移。

(3)作业和应用调度。

(4)作业工作流编排。

(5)服务编排。

4.1、服务状态的维持和拟合

服务状态不是数据状态,是运行状态(Provision,Ready,Run,Scale,Rollback,Update,Destroy,Failed……)

服务运行过程中状态变化有两种:

1.不预期的变化。一些服务挂掉。好的集群管理控制器应该能够强行维护服务的状态(健康的服务实例数)。健康的实例数变少时,控制器会把不健康的服务给摘除,而又启动几个新的。

2.预期的变化。发布新版本,需要伸缩,需要回滚。集群管理控制器就应该把集群从现有状态迁移到新状态。这个过程并不是一蹴而就的,集群控制器需要一步一步地向集群发送若干控制命令。这个过程叫“拟合”,不断地拟合,直到达到目的。需要对集群进行一系列的操作。比如,当需要对集群进行 Scale 的时候,我们需要:

先扩展出几个结点;

再往上部署服务;

然后启动服务;

再检查服务的健康情况;

最后把新扩展出来的服务实例加入服务发现中提供服务。集群控制器往生产集群中进行若干次操作。过程一定是“慢”的:

(1)对其它操作排它;

(2)在整个过程中,我们的控制系统需要努力地逼近最终状态,直到完全达到。

(3)正在运行的服务可能也会出现问题,离开了我们想要的状态,而控制系统检测到后,会强行地维持服务的状态。Kubernetes 调度控制系统思路就是这个样子的。

4.2、服务的弹性伸缩和故障迁移

拟合的基础工作之后,很容易地管理服务的生命周期了,甚至可以通过底层的支持进行便利的服务弹性伸缩和故障迁移。弹性伸缩,在上面我已经给出了一个服务伸缩所需要的操作步骤。还是比较复杂的,其中涉及到了:

    底层资源的伸缩;

    服务的自动化部署;

    服务的健康检查;

    服务发现的注册;

    服务流量的调度。

故障迁移,服务的某个实例出现问题时,自动地恢复它

两种模式

(1)宠物模式,一定要救活,主要是对于 stateful 的服务。

(2)奶牛模式,不救活了,重新生成一个实例。

服务的健康监控(这可能需要一个 APM 的监控)。

宠物模式,需要:服务的重新启动和服务的监控报警(如果重试恢复不成功,需要人工介入)。

奶牛模式,需要:服务的资源申请,服务的自动化部署,服务发现的注册,以及服务的流量调度。

把传统的服务迁移到 Docker 和 Kubernetes 上来,再加上更上层的对服务生命周期的控制系统的调度,我们就可以做到一个完全自动化的运维架构了。

4.3、服务工作流和编排

在分布式的服务调度中,这个工作叫做 Orchestration,国内把这个词翻译成“编排”。

SOA 是通过 ESB服务、通信路由、协议转换、服务编制和业务规则应用等。

注意,ESB 的服务编制叫 Choreography,与Orchestration 不一样。

Orchestration 的意思是,一个服务像大脑一样来告诉大家应该怎么交互,就跟乐队的指挥一样。

Choreography 的意思是,在各自完成专属自己的工作的基础上,怎样互相协作,就跟芭蕾舞团的舞者一样。

微服务中,希望使用更轻量的中间件来取代 ESB 的服务编排功能。需要API Gateway 或简单的消息队列来编排。

SpringCloud 中,所有的请求都统一通过 API Gateway(Zuul)来访问内部的服务。和 Kubernetes中的 Ingress 相似。服务的编排会直接导致一个服务编排的工作流引擎中间件的产生。这就是所谓的 Orchestration 中的 conductor 指挥了。

你可能感兴趣的:((5)分布式系统关键技术:服务调度)