二、分布式服务框架入门

1 分布式服务框架诞生背景

1.1 集中式到分布式

  1. 业务发展、应用规模变大,大型复杂应用的开发维护成本高,部署效率低,应用数量膨胀,数据库连接数变高。
  2. 代码复用低:由于公共模块都是进程内部的本地 API 调用,开发者按需开发,导致大量相同功能的 API 被重复开发。一旦涉及到公共模块的功能变更,所有重复实现都需要重新修改、编译和测试。
  3. 敏捷持续交付:想要在一个架构师都无法理解的巨无霸业务中新增或者修改一个功能,难度是非常大的。业务模块之间的循环依赖、重复 API 定义和开发、不合理的调用、冗长复杂的业务流程对新特性的上线简直是梦魇。

大规模系统架构的设计一般就是尽可能的拆分,以达到更好的独立扩展、部署、开发效率等。
具体的拆分策略大体上可以分为横向拆分和纵向拆分。

纵向拆分:不同业务模块独立部署,例如一个 CRM 系统就可以根据客户域、产品域、资源域、营销管理域等拆分。由大变小、分而治之。

横向拆分:将核心的、公共的业务拆分出来,通过分布式服务框架对业务进行服务化,消费者通过标准的契约来消费这些服务。服务提供者独立打包、部署,与消费者解耦。

1.2 引入服务治理

使用 RPC 框架对业务进行拆分之后,随着服务数的增多,急需一个服务治理框架,有效管控服务,提升服务运行期质量,防止业务服务代码架构腐化。因为,服务治理的主要应用如下:

  1. 生命周期管理:服务上线下线通知机制规范化。
  2. 服务容量规划。
  3. 运行期治理:对非核心服务采取降级、限流措施;缓存失效时,系统压力转移到数据库,服务调用时延突然增大,业务失败率升高,需要在线调大服务调用超时时间,保证业务成功率。
  4. 服务安全。

典型的 SOA 服务治理生命周期如下:

  1. 计划:确定服务治理的重点。
  2. 定义:定义服务治理模型。
  3. 启用:实现并实施服务治理。
  4. 度量:根据实施效果,改进服务治理模型。

2 业务分布式服务框架介绍

2.1 阿里 Dubbo

架构图如下:

功能总结:

  1. 根据服务提供者配置的 XML 文件将服务按照指定协议发布,完成服务的初始化工作。
  2. 服务提供者根据配置的服务注册中心地址连接服务注册中心,将服务提供者信息发布到服务注册中心。
  3. 消费者根据服务消费者 XML 配置文件的服务引用信息,连接注册中心,获取指定服务的地址等路由信息。
  4. 服务注册中心根据服务订阅关系,动态地向指定消费者推送服务地址信息。
  5. 消费者调用远程服务时,根据路由策略,从本地缓存的服务提供者地址列表中选择一个服务提供者,然后根据协议类型建立链路,跨进程调用服务提供者。

原理图如下:

2.2 淘宝 HSF

架构图如下:

功能总结:

  1. 配置 XML 方式发布和消费服务。
  2. 插件管理体系:平台与应用分开部署,运行期依赖,外部采用与应用独立的 classloader 隔离,内部采用 OSGI 隔离。
  3. 异步 NIO 通信。多种序列化方式。服务提供者和消费者之间采用长连接通信。
  4. 灵活的路由能力:客户端软负载,随机、轮询等多种路由策略,支持容灾和失效恢复等。
  5. 多协议支持:WebService、PB(Protocol buffer)和 Hession(HTTP)等。

整体结构图如下:

2.3 亚马逊 Coral Service

3 分布式服务框架设计

本章介绍分布式服务框架的架构原理和概要设计。

3.1 架构原理


通常分布式服务框架的架构可以抽象为三层:

  1. RPC 层:包括底层通信框架(例如 NIO 框架的封装、公有协议的封装等)、序列化和反序列化框架、用于屏蔽底层通信协议细节和序列化方式差异的 Remoting 框架。
  2. Filter Chain 层:服务调用职责链,提供多种服务调用切面供框架自身和使用者扩展,例如负责均衡、服务调用性能统计、服务调用完成通知机制、失败重发等。
  3. Service 层:主要包括 Java 动态代理,消费者使用,主要用于将服务提供者的接口封装成远程服务调用:Java 反射,服务提供者使用,根据消费者请求消息中的接口名、方法名、参数列表反射调用服务提供者的接口本地实现类。

从功能角度看,分布式服务框架通常会包含另外两个重要功能:服务治理中心和服务注册中心。

3.2 功能特性

  1. 服务订阅发布之配置化发布和引用服务:支持通过 XML 配置的方式发布和导入服务,降低对业务代码的侵入。
  2. 服务订阅发布之服务自动发现机制:由注册中心推送服务地址,消费者不需要配置服务提供者地址,服务地址透明化。
  3. 服务订阅发布之服务在线注册和去注册:支持运行态注册新服务,也支持运行态取消某个服务的注册。
  4. 服务路由之默认提供随机路由、轮询、基于权重的路由策略等。
  5. 服务路由之粘滞连接:总是向同一个提供方发起请求,除非此提供方挂掉,再切换到另一台。
  6. 服务路由之路由定制:支持用户自定义路由策略。
  7. 集群容错之 FailOver:失败自动切换,常用读操作;也可用于幂等性写操作。
  8. 集群容错之 Failback:失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作。
  9. 集群容错之 Failfast:快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作。
  10. 服务调用之同步调用:消费者发起服务调用之后,同步阻塞等待服务端响应。
  11. 服务调用之异步调用:消费者发起服务调用之后,不阻塞立即返回,由服务端返回应答后异步通知消费者。
  12. 服务调用之并行调用:消费者同时对多个服务提供者批量发起服务调用请求,批量发起请求,集中等待应答。
  13. 多协议之私有协议:支持二进制等私有协议,支持自定义。
  14. 多协议之公有协议:支持 Web Service 等公有协议,用于外部服务对象。
  15. 序列化方式之二进制类序列化:支持 Thrift、Protocol buffer 等二进制协议,提升序列化性能。
  16. 序列化方式之文本类序列化:支持 JSON、XML 等文本类型的序列化方式。
  17. 统一配置之本地静态配置:安装部署一次,运行态不修改的配置,可以存放到本地配置文件中。
  18. 统一配置之基于配置中心的动态配置:运行态需要调整的参数,统一放到配置中心,修改之后统一下发,实时生效。

3.3 服务治理

  1. 服务运行态管控之服务路由:业务高峰期,通过动态修改路由策略实现导流。
  2. 服务运行态管控之服务限流:资源成为瓶颈时,服务端和消费者的动态流控。
  3. 服务运行态管控之服务迁入迁出:实现资源的动态分配。
  4. 服务运行态管控之服务降级:服务提供者故障时或者业务高峰期,进行服务强制或者容错降级,执行本地降级逻辑,保证系统平稳运行。
  5. 服务运行态管控之服务超时控制:动态调整超时时间,在业务高峰期保障业务调用成功率。
  6. 服务监控之性能统计:统计项包括服务调用时延、成功率、调用次数等。
  7. 服务监控之统计报表:提供多维度、实时和历史数据报表,同比、环比等性能对比数据,供运维、运营等使用。
  8. 服务监控之告警:指标异常,根据告警策略发送告警,包括但不限于短信、E-mail、记录日志等。
  9. 服务生命周期管理之上线审批:服务提供者不能随意线上发布服务,需要通过正规的审批流程批准之后才能上线。
  10. 服务生命周期管理之下线通知:服务提供者在下线某个服务之前一段时间,需要根据 SLA 策略,通知消费者。
  11. 服务生命周期管理之服务灰度发布:灰度环境划分原则、接口前向兼容性策略,以及消费者如何路由,都需要灰度发布引擎负责管理。
  12. 故障快速定界定位之分布式日志采集:支持在大规模分布式环境中实时采集容器、中间件和应用的各种日志。
  13. 故障快速定界定位之海量日志在线检索:支持分布式环境海量日志的在线检索,支持多维度索引和模糊查询。
  14. 故障快速定界定位之调用链可视化展示:通过分布式消息跟踪系统输出调用链,可视化、快速地进行故障定界。
  15. 故障快速定界定位之运行日志故障定位:通过调用链的故障关键字,在日志检索界面快速检索故障日志,用于故障的精确定位。
  16. 服务安全之敏感服务的授权策略:敏感服务如何授权,防止恶意调用。
  17. 服务安全之链路的安全防护“消费者和服务提供者之间的长连接,需要增加安全防护,例如基于 Token 的安全认证机制。

4 个人总结

分布式服务框架在原理、目标是类似的,因此不同的分布式服务框架原理也是相似的。