5.3. 节点伸缩与故障转移

容器化部署是微服务非常理想的选择,它可以实现上文提到的快速发布及本节要谈的自动化节点伸缩与故障转移。

自动化的节点伸缩也叫弹性伸缩,它在节点服务压力上升到指定阀值时自动增加一个或多个新的节点,在压力下降到指定阀值时又能自动回收节点,它的目标是最大化地控制资源利用率。自动故障转移指的是在某个节点或服务故障时可以自动启用备用节点或服务,确保服务实例数量大于等于设定的最小值,类似于分布式文件系统,如HDFS的副本策略。

要实现这两个目标的基础有2个:1)节点服务无状态,不持有数据(缓存除外),2)需要让运维系统感知到特定指标的值,这就用到了上一节的服务指标,节点伸缩需要的指标一般有CPU、内存、网络IO、JVM内存、核心接口TPS及平均响应时长,尤其是“核心接口TPS及平均响应时长”,这是最关键的指标,需要应用系统提供。故障转移最先判断是的节点的连通性,节点本身的硬件或系统故障、IP段所在交换机故障都有可能导致连接丢失,这时需要在与故障节点/网段尽可能远的地方(异地机房/其它机架等)启动备用服务,确定网络的连通性后还需要使用服务健康度相关指标,如果健康指标中反馈某个中件间有问题那要执行抢修(一般的中间件都是高可用的,如果应用服务连接中间件异常那多半是因为中间件发生了网络中断或比较严重的问题,中间件不像应用服务,它可能持有重要的数据,比较难实现故障转移),如果是某些应用接口故障,那同上文启动备用服务。

上述操作的核心在于运维工具上,目前与微服务最契合是工具当属Kubernetes,也称k8s,Kubernetes是Google开源的容器管理系统,同Prometheus一样,也是CNCF成员(Kubernetes是元老级的)。

Kubernetes可以很轻松地实现节点的伸缩,使用Horizontal Pod Autoscaler(HPA)来定时监控CPU或我们自定义的指标,如官网示例:

kubectl autoscale rc foo --min=2 --max=5 --cpu-percent=80

设置foo这个控制器,HPA将通过增加或者减少Pod副本的数量(2到5之间)以保持所有Pod的平均CPU利用率在80%以内。自定义指标的伸缩可参考。Kubernetes默认支持连通性问题导致的故障转移,但健康度判断的故障转移需要自定义开发。

Kubernetes本身也实现或扩展了微服务的众多功能,如服务的注册发现、配置管理、负载均衡、调用跟踪等,这也使得有人提出了微服务使用Spring Cloud还是Kubernetes的讨论,实际上两者各有优劣,也都在彼此学习,比如spring-cloud-kubernetes 就是Spring Cloud与Kubernetes协同的集成方案,而kubeflix则是Kubernetes集成Netflix OSS的方案。

单从笔者的观点看以Kubernetes为代表的微服务架构试图让开发者用更简单的编程模型开发微服务化的系统是未来的趋势,本书最后会介绍的Service Mesh服务网格正是这种理念下的新生微服务架构。

下一节:微服务的特点决定了它会存在较长的调用链路,一个请求一般会跨3个以上的服务(网关->应用聚合层->服务化层)而跟踪它的调用情况是异常定位及性能优化的关键之一。要能跟踪我们势必需要在日志中记录每个请求唯一的跟踪Id,我们可以在HTTP请求或MQ接收时判断消息Header是否存在Trace_Id,如果不存在则认为是新的请求,进而生成一个UUID作为Trace_Id,如果存在则沿用这个Trace_Id,然后在打日志时加上这个Trace_Id。最后通过日志收集工具将这个本地日志收集到一个聚合平台上进行查询。这能解决问题,实际上这也是Google Dapper(《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》)的核心思路,Google Dapper是Google的日志追踪服务。