基于Consul做ServiceMesh风格的服务发现架构

之前的方案

《基于OpenResty与Consul实现服务网格ServiceMesh》 一文是2019年对服务网络架构的一个实践,里边有一些不完美的地方,比如每个服务节点上要装OpenResty + Consul client两个组件来做代理,OpenResty上要装微博开源的upsync插件来更新上游服务的upstream配置,且只能更新现有upstream的节点横向扩缩容,如果新增或者删除stream的话,需要使用远程的shell脚本执行来改OpenResty里的nginx.conf文件再执行reload操作。
2021年初笔者基于Ribbon + Spring Cloud Config,修改了Ribbon源码做自定义开发,做了一个客户端负载均衡组件:Ribbon向Config来获取服务列表,通过Pinger机制来对各个服务节点做健康检查,Config管理端修改了服务配置之后通过Spring Bus(kafka)来通知节点上的Config客户端库来重新获取配置。
做了这个项目之后,熟悉了负载均衡的玩法。后面笔者又做了OpenResty + Redis + RocketMQ的一个秒杀架构。又看了一些关于蚂蚁金服ServiceMesh架构的一些文章。又想起了自己曾经做了的这个ServiceMesh小Demo,决定重新优化一下架构。

新方案

下面说下新的优化思路:

  • Consul分Server和Client端,Server端3节点高可用集群、客户端装在每个业务服务器节点上,共同组成了一个服务配置共享的网络。
  • 去掉OpenResty,把代理程序缩到每个业务服务进程里边,以SpringBoot Starter作为一个Lib让每个业务应用引用,这个库作为Proxy。
  • Consul client作为边车,Proxy负责为所在业务应用连接边车,从边车获取可用服务列表,然后直连调用服务端。

1、跟之前的边车不同,这次边车只负责给客户端提供服务列表,并没有负责转发客户端的请求。客户端与服务端是直连调用的。
2、客户端进程内的Proxy库,可以基于spring-cloud-starter-consul-discovery来做封装和定制化二次开发。

本文原来标题叫《基于Consul做ServiceMesh服务网格架构》,但仔细想象这个架构跟服务网格还是有不同的,只是Consul Client也可以看作是另一种边车模式的一个实现吧。只用来提供可用服务列表,不做请求转发。客户端、也就是服务调用者做进程内客户端侧负载均衡,实际调用方式是直连。

优缺点:

  • 与原来的OpenResty + Consul的方案相比,业务应用里边要引入1个封装的依赖,然后服务调用使用封装过的带负载均衡功能的HttpClient工具。但是好处是服务调用是直连调用了,不需要像原来一样用OpenResty做中间代理了。也就绕开了前文提到的这块不完美的几个地方。
  • 与Ribbon + Config的方案相比,业务应用引入封装Jar包、服务调用工具用新客户端类这点是一样的。搭建Config变为搭建Consul,前者之前使用的是JDBC模式存储服务节点信息,用Consul后更为方便。另外不需要搭建Kafka来做Spring Bus通知服务节点变化,Consul网络会通过Gossip协议扩散到各个服务节点里的边车中、客户端去边车定时查就可以了,相比原来架构简单了不少。(节点配置变化通知及时应该确实是原来的更及时,变化后立即通过kafka通知客户端,客户端收到通知立刻调用rest接口到Config查询。通过Consul的Gossip扩散到客户端旁边的Consul Client边车本身就会有一定的延迟,然后客户端又是定时轮询边车的。但考虑到延迟个最多10几秒应该可以接受)
    再一个,各个服务的健康检查可以通过Consul统一来做了,不需要客户端都去做轮询来健康检查的调用。
  • 与比较通用的Eureka + Ribbon的方式相比,多了一个好处在于业务应用里不需要去配置注册中心的地址了,可以直接写死成固定的localhost + 约定的一个固定的Consul Client端口。
原文地址:https://www.cnblogs.com/lyhero11/p/15775426.html