上一篇文章,我们了解到了微服务基础设施建设中的:自动化测试,自动化部署,配置中心,接口框架和API网关。接下来我们了解一下,服务管理的一些能力的建设,主要包括:服务发现,服务路由,服务注册,服务监控,服务跟踪和服务安全。
服务发现
微服务种类和数量很多,如果这些信息全部通过手工配置的方式写入各个微服务节点,首先配置工作量很大,配置文件可能要配几百上千行,几十个节点加起来后配置项就是几万几十万行了,人工维护这么大数量的配置项是一项灾难;其次是微服务节点经常变化,可能是由于扩容导致节点增加,也可能是故障处理时隔离掉一部分节点,还可能是采用灰度升级,先将一部分节点升级到新版本,然后让新老版本同时运行。不管哪种情况,我们都希望节点的变化能够及时同步到所有其他依赖的微服务。如果采用手工配置,是不可能做到实时更改生效的。因此,需要一套服务发现的系统来支撑微服务的自动注册和发现。服务发现的实现,通常分为两种:自理式和代理式。
自理式
自理式结构就是指每个微服务自己完成服务发现。如下图中 SERVICE INSTANCE A 访问 SERVICE REGISTRY 获取服务注册信息,然后直接访问 SERVICE INSTANCE B。自理式服务发现实现比较简单,因为这部分的功能一般通过统一的程序库或者程序包提供给各个微服务调用,而不会每个微服务都自己来重复实现一遍;并且由于每个微服务都承担了服务发现的功能,访问压力分散到了各个微服务节点,性能和可用性上不存在明显的压力和风险。
自理式架构图:
代理式
代理式结构就是指微服务之间有一个负载均衡系统(图中的 LOAD BALANCER 节点),由负载均衡系统来完成微服务之间的服务发现。代理式的方式看起来更加清晰,微服务本身的实现也简单了很多,但实际上这个方案风险较大。第一个风险是可用性风险,一旦 LOAD BALANCER 系统故障,就会影响所有微服务之间的调用;第二个风险是性能风险,所有的微服务之间的调用流量都要经过 LOAD BALANCER 系统,性能压力会随着微服务数量和流量增加而不断增加,最后成为性能瓶颈。因此 LOAD BALANCER 系统需要设计成集群的模式,但 LOAD BALANCER 集群的实现本身又增加了复杂性。不管是自理式还是代理式,服务发现的核心功能就是服务注册表,注册表记录了所有的服务节点的配置和状态,每个微服务启动后都需要将自己的信息注册到服务注册表,然后由微服务或者 LOAD BALANCER 系统到服务注册表查询可用服务。
代理式架构图:
服务路由
有了服务发现后,微服务之间能够方便地获取相关配置信息,但具体进行某次调用请求时,我们还需要从所有符合条件的可用微服务节点中挑选出一个具体的节点发起请求,这就是服务路由需要完成的功能。服务路由和服务发现紧密相关,服务路由一般不会设计成一个独立运行的系统,通常情况下是和服务发现放在一起实现的。对于自理式服务发现,服务路由是微服务内部实现的;对于代理式服务发现,服务路由是由 LOAD BALANCER 系统实现的。无论放在哪里实现,服务路由核心的功能就是路由算法。常见的路由算法有:随机路由、轮询路由、最小压力路由、最小连接数路由等。
服务容错
系统拆分为微服务后,单个微服务故障的概率变小,故障影响范围也减少,但是微服务的节点数量大大增加。从整体上来看,系统中某个微服务出故障的概率会大大增加。专栏第 34 期我在分析微服务陷阱时提到微服务具有故障扩散的特点,如果不及时处理故障,故障扩散开来就会导致看起来系统中很多服务节点都故障了,因此需要微服务能够自动应对这种出错场景,及时进行处理。否则,如果节点一故障就需要人工处理,投入人力大,处理速度慢;而一旦处理速度慢,则故障就很快扩散,所以我们需要服务容错的能力。常见的服务容错包括请求重试、流控和服务隔离。通常情况下,服务容错会集成在服务发现和服务路由系统中。
服务监控
系统拆分为微服务后,节点数量大大增加,导致需要监控的机器、网络、进程、接口调用数等监控对象的数量大大增加;同时,一旦发生故障,我们需要快速根据各类信息来定位故障。这两个目标如果靠人力去完成是不现实的。举个简单例子:我们收到用户投诉说业务有问题,如果此时采取人工的方式去搜集、分析信息,可能把几十个节点的日志打开一遍就需要十几分钟了,因此需要服务监控系统来完成微服务节点的监控。服务监控的主要作用有:实时搜集信息并进行分析,避免故障后再来分析,减少了处理时间。服务监控可以在实时分析的基础上进行预警,在问题萌芽的阶段发觉并预警,降低了问题影响的范围和时间。通常情况下,服务监控需要搜集并分析大量的数据,因此建议做成独立的系统,而不要集成到服务发现、API 网关等系统中。
服务跟踪
服务监控可以做到微服务节点级的监控和信息收集,但如果我们需要跟踪某一个请求在微服务中的完整路径,服务监控是难以实现的。因为如果每个服务的完整请求链信息都实时发送给服务监控系统,数据量会大到无法处理。服务监控和服务跟踪的区别可以简单概括为宏观和微观的区别。例如,A 服务通过 HTTP 协议请求 B 服务 10 次,B 通过 HTTP 返回 JSON 对象,服务监控会记录请求次数、响应时间平均值、响应时间最高值、错误码分布这些信息;而服务跟踪会记录其中某次请求的发起时间、响应时间、响应错误码、请求参数、返回的 JSON 对象等信息。
服务监控和服务追踪之间的差异简单来说就是,服务监控可以理解成对服务调用信息的汇总,而服务追踪则是对服务调用明细的记录。
服务安全
系统拆分为微服务后,数据分散在各个微服务节点上。从系统连接的角度来说,任意微服务都可以访问所有其他微服务节点;但从业务的角度来说,部分敏感数据或者操作,只能部分微服务可以访问,而不是所有的微服务都可以访问,因此需要设计服务安全机制来保证业务和数据的安全性。服务安全主要分为三部分:接入安全、数据安全、传输安全。通常情况下,服务安全可以集成到配置中心系统中进行实现,即配置中心配置微服务的接入安全策略和数据安全策略,微服务节点从配置中心获取这些配置信息,然后在处理具体的微服务调用请求时根据安全策略进行处理。由于这些策略是通用的,一般会把策略封装成通用的库提供给各个微服务调用。基本架构如下: