《架构设计》-09-分布式服务架构(注册中心、服务发布、服务调用、服务治理)
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<p></p>
文章目录
1. 概述
- RPC架构的意义
- 解决了分布式环境下两个独立进程之间通过网络进行方法调用和数据传输的问题
当我们通过横向拆分方法对系统进行拆分会得到一系列垂直化应用。随着垂直化应用越来越多,应用之间交互不可避免。RPC架构将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心。
-
RPC的困境
- 当服务越来越多时,服务URL配置管理会变得非常困难,负载均衡器的单点压力也越来越大。
- 当服务间依赖关系变得错踪复杂,甚至无法描述应用的架构关系
- 服务的调用量越来越大,服务的容量问题就暴露出来。
-
困境的解决:分布式服务架构
2. 集群容错策略
- 转移失败策略(Failover)
- 当发生服务调用异常时,重新在集群中查找下一个可用的服务提供者。
- 为了防止无限重试,通常对失败重试最大次数进行限制。
- 通知失败策略(Failback)
- 当服务调用失败直接将远程调用异常通知给消费者,由消费者捕获异常进行后续处理。
- 安全失败策略(Failsafe)
- 当获取服务调用异常时,直接忽略。
- 通常用于写入审计日志等操作
- 快速失败策略(Failfast)
- 在获取服务调用异常时,立即报错。
- 在特定场景中可以使用该策略确保非核心业务服务只调用一次
3. 服务路由
3.1 直接路由
- 直接路由:基于配置中心或者数据库中存储的目标服务的具体地址构建链路完成调用
- 缺陷
- 服务提供者地址发生改变时无法在第一时间通知消费者
- 创建和维护配置中心或数据库持久化操作需要成本
3.2 间接路由和注册中心
图,基于发布-订阅模式和注册中心的间接路由实现方案
- 注册中心的作用
- 服务提供者发布服务到注册中心
- 服务消费者订阅感兴趣的服务
- 优势
- 当服务提供者地址发生变化时,注册中心推送服务变化到服务消费者
- 服务消费者可以配备缓存机制
- 提高高路由的效率
- 注册中心不可用是,仍可使用缓存数据
3.3 路由规则
- 作用:实现动态路由
- 使用:
- 通常是黑白名单
- 也可以是条件脚本
3.4 服务路由/负载均衡/集群容错的关系
4. 服务发布
服务发布流程时序图
4.1 发布启动器
- 作用:确定服务发布形式并启动发布平台。
- 常见发布形式
- 配置化
- 做法:通过以XML为代表的配置化工具
- 优势:服务框架对业务代码零侵入,扩展和修改方便,修改能够实时生效
- 使用:倾向于该方法
- API调用
- 缺点:服务框架对业务代码侵入性较强,修改代码之后需要重新编译才能生效
- 使用:系统之间集成
- 使用注解
- 优势:服务框架对业务代码零侵入,扩展和修改也比较方便
- 缺点:修改配置需要重新编译代码
- 配置化
4.2 动态代理
在涉及远程调用时,通常会在本地服务实现的基础上添加动态代理功能。通过动态代理实现对服务发布进行动态拦截,可以对服务发布行为本身进行封装和抽象,也便于扩展和定制化。JDK自带的Proxy机制以及类如javassist的字节码编辑库都可以实现动态代理。
4.3 发布管理器
- 作用
- 获取协议服务器中生成的服务URL信息并发布到注册中心
- 发布器也负责通知发布启动器本次发布是否成功
4.4 协议服务器
- 协议服务器:实现服务器创建和网络通信的组件
- 作用
- 确定发布协议及根据该协议建立网络连接
- 并管理心跳检测、断线重连、端口绑定与释放
- 用于发布服务的常见协议
-
HTTP协议(如图)
-
RMI协议(Remote Method Invocation,如图)
-
Hessian协议(如图)
-
5. 服务调用
- 服务调用流程,如图
- 包含组件
- 调用启动器
- 作用:确定服务的调用形式并启动调用平台
- 使用的策略:同发布启动器
- 动态代理
- 作用:动态代理完成本地接口到远程调用的转换。
- 调用管理器
- 具备缓存功能,保存服务地址的缓存信息
当从注册中心获取服务提供者地址信息时,调用管理器根据需要更新本地缓存,确保在注册中心不可用的情况下,调用启动器仍然可以从本地缓存中获取服务提供者的有效地址信息。
- 具备缓存功能,保存服务地址的缓存信息
- 协议客户端
- 根据服务调用指定的协议类型创建客户端,并发起连接请求。
- 负责与协议服务器进行交互并获取调用结果。
在服务调用过程中,实现了从本地缓存获取服务路由、序列化请求消息封装成协议消息、发送协议请求并同步等待或注册监听器回调、反序列化应答消息并唤醒业务线程或触发监听器等分布式服务的基本步骤。如果调用超时或失败,将采用集群容错机制。至此,整个服务发布和调用过程形成闭环。
- 调用启动器
6. 服务治理
服务调用关系示例:
-
服务监控的思路:日志埋点,即使用跟踪Id作为一次完整应用调用的唯一标识,然后将该次调用的详细信息通过日志的方式进行保存。
- 客户端埋点
- 注于跟踪Id、客户端IP、调用方接口、调用时间等信息
- 服务器端埋点
- 记录跟踪Id、调用方上下文、服务端耗时、处理结果。
- 客户端埋点
-
服务治理
- 目标:保障线上服务运行质量,治理的对象是基于统一分布式服务框架开发的各项业务服务。
- 定位:关注于服务运行时状态、细粒度治理,服务限流/降级、服务动态路由、灰度发布是服务治理的基本策略
- 具体实现:
- 可以采用通过注册中心对服务依赖进行分析,结合运行时调用关系,梳理不合理的依赖和调用路径,优化服务架构;
- 实时收集服务调用日志,分析、汇总、存储和展示,方便开发和运维人员进行实时故障诊断,同时执行服务运行时治理方案,包括限流降级、路由、统一配置等在线调整。