服务调度
这里的服务调度就是指除开流量调度外的服务治理。主要有以下几点。
- 服务关键程度
- 服务依赖关系
- 服务发现
- 架构版本管理
- 服务应用声明周期全管理
服务关键程度和服务依赖关系程度
服务关键程度要通过对业务的梳理来发现。服务依赖关系用Spring Cloud的一套方法就能够非常好的解决,但是千万不要出现循环依赖,解决方式是通过第三方的消息队列来解耦,此外还有Zipkin这个服务跟踪工具来展示这张地图。
服务状态和服务生命周期管理
我们需要一个统一的服务注册中心,来做到
- 整个架构中有多少种服务?
- 这些服务的版本是怎么样的?
- 每个服务的实例数有多少个?它们的状态是怎么样的?
- 每个服务的状态是怎么样的?是在部署中、运行中、升级中、还是在回滚,伸缩中,或是在下线中 有了这些状态,就能对生命周期进行管理了,主要有以下几个状态
- Provision,代表在供应一个新的服务
- Ready, 表示启动成功了
- Run, 表示通过了服务健康检查
- Update,表示正在升级中
- Rollback,表示正在回滚中
- Scale,表示正在伸缩中
- Destroy, 表示正在销毁中
- Failed,表示失败的状态
有了生命周期的管理,一个纷乱无比的世界就可以干干净净的管理起来了
架构版本管理
除了各个项目的版本管理外,还需要在上面再覆盖一层版本管理。比如A服务的1.2版本只能和B服务的2.2版本一起工作,如果架构中存在不兼容的情况,可以把整个架构回滚掉。所以,就需要一个架构清单,包括但不限于
- 服务的软件版本
- 服务的运行环境--环境变量、CPU、内存、可运行的结点、文件系统等
- 服务运行的最大和最小实例数 而每一次对这个清单的变更都需要记录下来,算是一个架构版本管理。而我们这个集群控制系统需要解读并执行这个清单中的变更,以操作和管理整个集群中的相关变更。
资源/服务调度
服务和资源调度有点类似操作系统。操作系统一方面把用户进程在硬件资源上进行调度,另一方面提供进程间通信方式,可以让不同进程在一起协同工作。 而服务调度有以下一些关键技术。
- 服务状态的维持和拟合
- 服务的弹性伸缩和故障迁移。
- 作业的应用调度。
- 作业的工作流编排。
- 服务编排。
服务状态的维持和拟合
服务状态包括上述服务生命周期中的状态- Provision, Ready,Run, Scale, Rollback, Update, Destory, Failed...而服务状态的变化包括预期和不预期的变化
- 一种是不预期的变化。比如,如果有服务挂掉了,或是什么原因服务不健康的状态。如果是一个好的集群管理,应该能摘除不健康的服务,同时又启动新的服务,强行维护健康服务的实例数。
- 另一种是预期的变化。比如需要发布新版本,需要伸缩,回滚。集群管理控制器就因该把集群从现有状态迁移到新的状态。这个过程叫“拟合”,举个栗子,我们需要对集群做Scale的时候,需要 a) 先扩展几个节点 b) 再往上部署服务 c) 然后启动服务 d) 再检查服务的健康情况 e) 最后把扩展出来的服务实例加入服务发现中提供服务 这个过程会比较“慢”,一方面,需要对其它操作排它;另一方面,整个过程必须努力逼近最终状态。此外,正在运行的服务也有可能出现问题,离开了我们想要的状态,而控制系统检测到后,会强行维持服务状态。 Kubernetes就是干这个的,没有这种控制系统的都不能称之为PaaS。
服务的弹性伸缩和故障迁移
有了服务状态拟合的基础工作后,我们就可以很容易的管理服务的声明周期了,具体到弹性伸缩,包括下列步骤:
- 底层资源的伸缩;
- 服务的自动化部署;
- 服务的健康检测
- 服务的发现和注册
- 服务的流量调度
而对于故障迁移,我们需要自动地恢复它,对于服务来说,有两种模式,一种是宠物模式,一种是奶牛模式
- 所谓宠物模式,就是一定要救活,对应有状态的服务。比如消息服务,redis缓存等
- 而奶牛模式,就是不救活了,重新生成一个。
对于这两种模式,会涉及到
- 服务的健康监控(APM)
- 如果宠物模式。需要服务的重新启动和服务的监控报警(如果重试不成功就需要人工介入)
- 如果是奶牛模式。需要服务的资源申请,服务的自动化部署,服务发现的注册,以及服务的流量调度。
很幸运的是Kubernetes和Docker都帮我们做掉了,只需要把传统的服务迁移上来,虽然这可能是一个艰巨的任务。
服务工作流和编排
一个好的操作系统需要能够通过一定的机制把一堆独立工作的进程给协同起来。在分布式服务调度中,这个工作就叫做"Orchestration",国内叫做"编排"
传统的SOA架构是通过ESB来完成的,其主要功能是通信路由、协议转换、服务编制和业务规则应用等。
而编排的意思是一个服务像乐队指挥一样,告诉大家该怎么交互。在微服务中,这需要一个API Gateway或一个简单的消息队列来做编排的工作,在Spring Cloud中,所有的请求都是通过Zuul网关来访问内部服务,这个和Kubernetes中的Ingress类似。