知识卡片
服务发现的两种实现方式:自理式与代理式的风险取舍
内容
服务发现要解决的问题是:微服务种类数量庞大,如果节点信息全靠手工配置写进每个微服务节点,配置文件可能要写几百上千行、几十个节点加起来就是几万几十万行,人工维护是灾难;而且节点经常变化(扩容、故障隔离部分节点、灰度升级新老版本共存),这些变化需要及时同步给所有依赖的微服务,手工配置根本做不到实时生效,因此需要一套自动化的服务注册与发现系统。服务发现有两种主流实现方式。自理式是每个微服务自己完成服务发现——比如服务实例A先访问服务注册表拿到服务注册信息,再直接访问服务实例B;这种方式实现相对简单,因为服务发现的逻辑一般通过统一的程序库或包提供给各微服务调用,不需要每个微服务重复造轮子,而且每个微服务都自己承担了服务发现的工作,访问压力天然分散到了各个节点,性能和可用性上都没有明显的集中风险。代理式是在微服务之间加一个负载均衡系统,由它统一完成服务发现——微服务本身实现变简单了,但这种集中化设计有两个明显风险:一是可用性风险,负载均衡系统一旦故障,会波及所有微服务之间的调用;二是性能风险,所有微服务间的调用流量都要经过这个负载均衡系统,压力会随微服务数量和流量增长而不断累积、最终可能成为性能瓶颈——为了应对这两个风险,负载均衡系统通常还得再设计成集群模式,而这本身又给系统引入了新的复杂性。不管走自理式还是代理式,服务发现的核心都是一份服务注册表,记录所有服务节点的配置和状态,每个微服务启动后要把自己的信息注册进去,之后由微服务自己(自理式)或负载均衡系统(代理式)到注册表里查询可用的服务。
结构图:
flowchart TB
A["服务发现的两种实现方式"]
A --> B["自理式:微服务自己查注册表<br/>直接访问目标服务"]
B --> B1["优点:逻辑封装成公共库,无需重复实现<br/>访问压力分散到各节点,无集中风险"]
A --> C["代理式:负载均衡系统统一负责服务发现"]
C --> C1["优点:微服务本身实现更简单"]
C --> C2["风险①可用性:负载均衡故障<br/>影响所有微服务间调用"]
C --> C3["风险②性能:所有流量经过负载均衡<br/>压力随节点/流量增长累积成瓶颈"]
C2 --> C4["应对:负载均衡需设计成集群<br/>但又引入新的复杂性"]
C3 --> C4
参考来源
- 位置:《从零开始学架构》第36讲《微服务架构最佳实践 - 基础设施篇》"服务发现"(源文件:_epub-src/OEBPS/text00003.html)
- 结论依据:原文说明自理式"实现比较简单……并且由于每个微服务都承担了服务发现的功能,访问压力分散到了各个微服务节点,性能和可用性上不存在明显的压力和风险",代理式"这个方案风险较大。第一个风险是可用性风险……第二个风险是性能风险……因此 LOAD BALANCER 系统需要设计成集群的模式,但 LOAD BALANCER 集群的实现本身又增加了复杂性",直接支撑本卡片结论与结构图。
- 原始内容:自理式服务发现实现比较简单……访问压力分散到了各个微服务节点,性能和可用性上不存在明显的压力和风险……代理式的方式看起来更加清晰……第一个风险是可用性风险……第二个风险是性能风险。