服务路由
在生产环境上,微服务都是多实例部署,服务路由决定了服务消费者如何从服务地址列表中选择服务提供者进行调用。gRPC-Nebula 服务治理框架的服务路由以下三大机制构成:
(1)负载均衡机制
gRPC-Nebula 服务治理框架支持连接负载均衡和请求负载均衡两种模式,默认连接负载均衡,同时提供了四种负载均衡算法可供选择:随机策略、轮询策略、权重配置优先策略、一致性哈希策略。
随机策略即随机地选择服务提供者进行调用;轮询策略即遍历服务地址列表,每次调用时依次选择一个服务提供方进行调用;权重配置优先策略可根据配置文件或管理门户对每个服务节点配置的权重比来选择服务提供者;一致性哈希策略中,相同参数的网络请求总由同一个服务提供者处理,当某个服务提供者的节点宕机时,系统基于一致性哈希算法来选择其他的节点;
图 4 gRPC-Nebula 负载均衡配置
(2)黑白名单机制
通过设置服务端实例的黑名单、白名单,可以动态实现请求流程的转移以及服务端实例的访问控制。如果将某 IP 加入一个服务的黑名单,部署在这个 IP 上的服务消费者无法从注册中心获取到这个服务的地址列表。
图 5 黑白名单设置
(3)权重配置
gRPC-Nebula 能够对服务提供者实例设置不同的服务权重,框架根据权重进行流量分发,这样可以达到根据不同的后端资源能力进行动态平衡。
图 6 服务权重列表
图 7 服务权重设置
(4)动态分组机制
每个微服务实例都有一个分组属性存放在注册中心,分组属性既可以通过配置文件预先设定,也可以通过管理平台动态配置。通过分组一个微服务的集群可以被划分为多个集合,服务消费者可以按优先级调用某几个特定分组的服务,动态分组机制可以灵活实现同机房调用和业务隔离等场景。
服务端配置:
客户端配置:
图 8 动态分组配置
机房调用场景,在数据机房安全性越来越得到重视的今天,多机房灾备方案被各类企业广泛使用,但是跨机房调用的高耗时可能造成系统的容量降低。如图 8 所示,假设所有服务实例均部署在 A、B 两个异地机房,服务消费者希望优先调用属于同机房的服务提供者,使用 IP 段定义机房的策略灵活性和扩展性不足,服务分组策略可以有效满足这一需求。例如将机房 A 的服务提供者定义为 a 分组,将机房 A 的服务消费者配置成优先调用 a 分组的节点,同时机房 B 的服务也进行类似配置。这样,机房 A 的服务消费者会优先调用机房 A 的服务提供者,避免高耗时的跨机房调用,当 Server1 和 Server2 全部宕机时,机房 A 的服务消费者会把请求自动切换到机房 B 的 Server3 和 Server4 上。
图 9 机房调用场景
业务隔离场景,业务隔离是避免微服务系统雪崩效应的常用策略,当一个服务提供者被多个消费者调用时,个别消费者的流量激增可能导致整个服务提供者集群超负荷运作,从而影响所有消费者的调用。服务治理平台的服务分组功能可以将服务提供者集群划分为一个个独立集合,消费者只调用特定分组的实例,这样每个消费者的调用相互隔离、互不影响,可以有效保证整个系统的高可用性。如图 9 所求,后端服务通过设置 tc、wmp、matrix 分组,可对交易接入、财富销售中心、东方睿等系统分别提供不同服务等级保障,达到业务隔离诉求。
图 10 业务隔离场景
集群容错
当服务提供者无法正常为消费者提供服务时,如连接被拒绝、请求超时、后台服务异常等,服务框架需要进行集群容错,重新进行路由选择和调用,gRPC-Nebula 服务治理框架支持快速失败(Failfast)和失效转移(Failover)两种策略:
快速失败是指如果服务提供者返回异常,消费者不用重试直接报错。这种策略适合一些非核心的服务,可以为重要的核心服务节约宝贵的资源。
失效转移是指当服务调用异常时,重新进行路由选择,查找下一个可用的服务提供者来发起新的调用请求。当调用一个节点连续多次失败或在一段时间内失败率超过限制时,框架认为这个节点当前已不适合再对外提供服务,服务消费者会将其从服务地址列表中剔除,保证一段时间内都不会调用到这个异常节点。这个机制的目的是降低系统对网络抖动的敏感性,不会因为一次偶然的调用失败而调整流量分配,保持服务器负载的稳定性。和服务分组属性一样,连续失败次数和一段时间内失败率的阈值都可以通过配置文件和管理平台配置。
图 11 集群容错配置
流量控制
历史上券商核心系统事故都是由流量冲击引起的,当网络流量瞬间爆发性增长时,对服务器 CPU 和 IO 资源的抢占会造成系统出现瓶颈,服务错误率迅速上升,此时上游或用户的重试行为又进一步加大了网络流量,最终使得服务彻底崩溃且长时间难以恢复,这即是雪崩效应。为了防止雪崩,需要对服务调用过程进行控制,通过一些策略削减流量,保证后台服务接收的请求在可承受的范围内。
gRPC-Nebula 服务治理框架通过设置请求数和连接数限制,动态实现对各服务接口的流控管理。请求数限制即当单位时间内请求数过多时,丢弃多余的请求;连接数限制即控制每个 IP 连接到服务提供者的连接数,在框架内服务间调用通过 gRPC 的 HTTP/2 协议保持长连接,当连接数达到阈值时,服务提供者会拒绝建立新连接的请求。
图 12 流量控制配置
访问保护状态
访问保护状态功能是服务治理平台控制服务端节点上下线的方式,可以用于无损发布和快速摘除故障节点等场景。例如系统上线更新时,服务的关闭或重启会导致一段时间内调用失败率升高,为了避免失败产生,可以通过服务治理平台将待操作实例设置为不可访问,注册中心会通知所有消费者不再调用不可访问节点。待确认服务端实例无调用请求后,运维人员实施更新操作,更新成功后再将实例重新设置为可以访问。更新过程中流量会平滑地从实例移除和返回,不会产生调用失败。
图 13 访问保护流程
图 14 访问保护设置
多注册中心支持
出于安全管控需求,很多企业将网络划分为多个网段,每个网段部署独立的注册中心。GRPC-Nebula 框架支持将服务同时注册到多个注册中心,并且可以将自定义的服务端 IP 端口注册到注册中心,这个特性为了适配多网段间可能存在的 IP 地址映射或代理的场景。
图 15 多注册中心支持
主备服务支持
gRPC-Nebula 框架支持主备服务,能够对实例设置主服务器和备服务器。当主服务器可用时客户端只能调用主服务器,不调用备服务器;当所有主服务器不可用时,客户端自动切换到备服务器进行服务调用。
图 16 主备服务示意图
图 17 主备服务设置
内外部服务
gRPC-Nebula 框架支持同一项目不同类型的 grpc 服务具有不同的可见性。服务提供者实现的接口可以划分为两类服务,对于内部项目间 gRPC 调用服务,此类服务并不对外暴露,因此应该避免外部项目可见;对于项目对外提供的 gRPC 服务则需要允许外部系统可见。
图 18 内外部服务
原生 gRPC 框架优化断线重连指数退避算法支持
当 gRPC 连接到服务端发生失败时,通常希望不要立即重试 (以避免泛滥的网络流量或大量的服务请求),而是做某种形式的指数退避算法。参考链接如下:
https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
但这种形式往往会造成服务端失败后,客户端不断的退化重连时间,长时间会退化成一个非常大的时间,当服务端重新启动成功后,客户端反而长时间不能连接成功,故此 gRPC-Nebula 修改了原生框架,客户端可以自行配置最大的重连时间,规避此类风险。
图 19 退避算法设置
Keepalive 心跳gRPC 原生逻辑具备 keepalive 心跳机制,客户端心跳默认关闭,服务端心跳 2 小时发送一次,参考链接如下:
https://github.com/grpc/grpc/blob/master/doc/keepalive.md。
但在实际生产网络环境中,防火墙通常设置为 15 分钟就会主动断开无请求的 TCP 连接,证券行业的特点造成了服务请求主要集中在 9:15-15:30 这个时间段,这样在非交易时间会有大量 TCP 连接断开,为此我们修改了 gRPC 框架,使客户端和服务端都可自行配置心跳时间。
图 20 客户端心跳设置
图 21 服务端心跳设置
星辰服务治理平台建设目标
由于业务的实际需求和技术发展,开发部门和供应商通常会根据需要选择不同的微服务框架,呈现多样化选型。如何管理好这些服务,成为研发和运维部门需要面对的问题。如果可以将这些框架和服务对接到统一的服务治理平台,将可以大大降低协作开发的成本,并提升整体的版本迭代效率,因此东方证券星辰服务治理平台的建设目标包括:
通用治理能力:引入中间层设计,兼容多框架的通用治理能力,采用分发器和治理组件协调工作统一多框架通用治理能力,由分发器下发任务至不同的治理组件,由理组件完成平台纳管多框架,完成分发器下发治理任务。平台自服务:平台本身采用微服务架构及容器平台集成,提供更深度的治理功能,提供平台应用生命周期、组件部署管理、灰度、弹性和统一配置支持。
多框架兼容的应用管理:兼容基于 gRPC、Spring Cloud、Dubbo 三种微服务框架,帮助客户快速部署或迁移微服务应用。
业务服务架构防腐化:通过服务注册中心对服务强弱依赖进行分析,结合运行时服务调用链关系分析,梳理不合理的依赖和调用路径,优化服务化架构,防止代码腐化。
快速故障定界定位:通过服务调用链日志、服务性能 KPI 数据、服务接口日志、运行日志等,实时汇总和分析,实现故障的自动发现、自动分析和在线条件检索,方便运维人员进行故障诊断。
服务微管控:运行态服务治理,包括限流降级、服务迁入迁出、服务超时控制、智能路由、统一配置等,通过一系列细粒度的治理策略,在故障发生时可以多管齐下,在线调整,快速恢复业务。服务生命周期管理:包括服务的上线审批、下线通知,服务的在线升级,以及上线、下线,自动弹性伸缩,资源扩容。