[微服务感悟] 服务发现与常见架构

什么是服务发现

既然要调用其他服务,首先知道每个调用的服务的ip和端口。怎么知道服务的地址,这个就是服务发现的作用。

服务发现原始架构

以前的做法是让运维给每个服务都配置一个域名,把域名映射到对应的每个节点服务器上,开发在项目的配置文件中写上每个服务和其域名,代码中拿配置文件的配置的域名进行远程调用。硬编码读配置文件获得域名地址,网关解析域名做负载均衡转发到对应服务节点这个功能,我认为就是服务发现。

A域名
B域名
生产服务, 项目配置文件中存在其他服务信息
网关, 负载均衡
A服务节点1
A服务节点2
A服务节点3
网关B
B服务节点1
B服务节点2
服务内集成网关架构

随着业务进一步发展,服务越来越多,服务的节点服务器也越来越多,这时改变服务的域名,改变域名对应的分发节点就成了一个很麻烦的事情。这时就需要一个服务中心来统一管理这些服务相关的配置文件,它需要同步每份配置文件;如果有新的服务加入进来,能自动的添加服务信息(服务注册);对于连不上的服务节点,要将它从服务列表中去除;提供一个查询接口或者查询页面方便用户直观的查询。这就出现了一个基本的服务中心的需求,由于所有的业务都需要与这个服务中心交互,如果这个服务中心挂了,其他服务就不能感知到存在的新的服务变化,所以它一定要高可用。

准确说用过服务中心来同步每个项目中的服务配置实现的是CP,它有不一致的风险;同时这个需要项目代码支持修改配置文件,或者使用统一的框架处理,这又导致一定的耦合性,不好扩展。spring cloud采用的就是这套架构,eureka是服务注册中心,spring cloud框架中集成了服务信息的同步,如果你想使用go语言的服务集成到spring cloud中来,就非常复杂,可能要实现一套支持服务信息同步的功能。对微服务中的每个服务随便采用什么语言的愿景没有实现。

这套架构中,每个应用都保存了所有服务,所有节点的数据,所以不用ngnix再做一层网关做某个服务的分发和负载均衡。服务分发,负载均衡都集成在程序框架中。

[微服务感悟] 服务发现与常见架构

统一网关架构(总线架构)

上面的架构,网关在每个服务中,主要靠服务中心同步所有节点数据。同步就一定会出现同步不及时的情况,所以说它的设计是一种CP的架构,一致性较弱;而且每个服务应用代码中集成网关,有一定的代码耦合。

另一种架构是网关在一个服务中心,其他服务把所有的请求都发送给服务中心,服务中心做负载均衡找到对应的服务节点并把请求转发过去。

服务关键字
转发
客服端服务
服务中心
服务A节点1
服务A节点2
服务B节点1

我工作中的某家公司,用的就是这套架构。做法是这样的,所有请求都是http请求,在请求头中加一个系统code,所有请求都要发给middleware的服务做转发,middleware中存有所有服务IP地址;每个服务启动时都会向middleware服务发送注册信息;middleware定期向所有服务发送心跳监控服务是否在线;middleware提供统一的负载均衡策略,熔断策略;middleware提供统一的http接口以供其查询服务器信息,middleware在内网中。

这套的好处是,每个服务之间代码没有啥耦合,只用注意在请求头中加请求服务code就行,在那套框架下,既跑了ssm的老项目,也跑了springboot的新项目,也跑了go语言的项目。

缺点是每个请求都要穿透一次服务中心,有性能损耗;而且服务中心作用太大,不能有问题,一有问题所有业务都会挂掉。

PS:当时设计这套的架构师称为总线架构,后来被绿厂高薪挖过去搞架构了,他说过去推广这一套。

架构如下,不过我已经离职有段时间了,这个架构应该还能再拆拆,合合。如open-Platform、face功能重合,没有合并的原因是历史原因;如middleware可以拆成柜机基本服务和服务中心。

[微服务感悟] 服务发现与常见架构

service mesh微服务架构

service mesh是现在比较火的概念,它的思想和服务内集成网关架构有点像,把每个网关都放到每个节点中,不过它的做法是把网关组件即成到系统镜像中去,而不是代码集成。它配合来使用docker会非常方便。

[微服务感悟] 服务发现与常见架构