微服务注册中心和三种服务发现模式
为何需要在我们日常开发中,需要调用另一个服务时,一般都是通过 API 接口发送请求,解析响应,再处理后续的业务逻辑,在这个过程中有没有思考过下面这些问题:如果我们调用的某个下游服务某个节点挂了,该怎么办?调用方如何确定调用的是哪个节点?下游服务进行上线操作时,如何保证上游能够正常调用?K8s 集群内节点的网络地址都是动态分配的,上游调用时如何找到新上线的节点?我们今天的主角,注册中心提供的服务发现
目录
为何需要
在我们日常开发中,需要调用另一个服务时,一般都是通过 API 接口发送请求,解析响应,再处理后续的业务逻辑,在这个过程中有没有思考过下面这些问题:
- 如果我们调用的某个下游服务某个节点挂了,该怎么办?
- 调用方如何确定调用的是哪个节点?
- 下游服务进行上线操作时,如何保证上游能够正常调用?
- K8s 集群内节点的网络地址都是动态分配的,上游调用时如何找到新上线的节点?
注册中心
我们今天的主角,注册中心提供的服务发现能力,就可以解决上述问题。
服务上线时,通过管控平台触发上线指令,调度中心下载代码仓库,根据服务对应的 k8s 模板进行容器资源编排调度,部署到对应的节点上,同时将节点的 IP 地址和端口号 提交到注册中心,通过心服务提供的健康监测接口进行心跳检测;服务调用时,消费者集群请求注册中心,根据负载均衡算法,选择多个节点中的一个,发起调用。
服务发现
我们上面提到,消费者调用时,需要请求注册中心,获取服务注册表,也就是可用服务实例的 “数据库” ,这个过程我们称之为服务发现。服务发现请求 API 用于发现可用的服务实例,依据进行发现操作的主体来区分服务发现模式,一共有三种:服务端发现、客户端发现、服务网格发现,三种模式,下面分别介绍。
服务端发现(代理模式)
代理模式又称服务端发现模式,采用 Facade 门面模式,借助网关实现:
工作流程如下:
- 启动时,服务提供方将自己注册到服务注册中心,并通过心跳保持和服务注册中心的连接
- 代理网关通过服务注册中心获取服务的可用节点列表
- 服务调用方通过指定的域名或者 IP+Port 向代理网关请求指定的服务
- 代理网关接到请求后,从相应服务的可用节点列表中,根据制定的路由及负载均衡策略,选择一个最终访问的节点建立连接并发起请求,获得相应
- 代理网关将结果返回给服务调用方,完成请求
代理模式优点:
- 服务路由和负载均衡策略都由代理网关实现,服务调用方无需关注发现细节,只需要简单地向网关发送请求
- 代理网关可以根据实际需要选择通信协议,在调用方便和效率之间做平衡
- 相关服务监控、安全控制、治理策略等,均可在网关实现,有效地降低监控治理的复杂度
- 服务调用方从代理网关上看到的就像一个统一完整的服务,代理网关屏蔽了后台服务的复杂性,同时屏蔽了后台服务的升级和变化,对调用方友好
有得必有失,缺点如下:
- 由于代理网关的存在,需要单独的团队进行开发、部署、管理
- 由于所有请求都需要经过网关转发,网络请求多了一次,所以效率略低
- 所有服务集中由网关转发,网关成为单点隐患,如果网关宕机,所有业务线都会受影响
客户端发现(直连模式)
客户端发现由客户端自己实现:
工作流程如下:
- 服务提供方在启动时,通过服务框架提供的 SDK 或 RPC 调用,注册到服务注册中心,并通过心跳或者长链接保持和服务注册中心的联系。
- 客户端通过服务框架提供的 SDK 或 RPC 调用,获取要调用的所有已注册的可用节点列表,并对服务注册中心进行监听,一旦服务注册中心有服务的新节点注册,服务调用方会及时更新节点列表。
- 发起调用时,服务调用方根据一定的路由及负载均衡策略计算后,选定一个最终的服务提供节点,并直接发起远程调用。
- 服务提供方接收到调用请求后,进行业务逻辑处理,并把最终的结果返回给服务调用方。
相比代理模式,有如下优点:
- 不存在代理网关,部署架构更加简化。
- 客户端可以根据自身业务特点选择更合适的负载均衡算法。
- 减少了网关层的一次转发,效率更高一些。
直连模式存在以下缺点:
- 服务提供方和调用方都需要集成服务框架的 SDK ,也就是说它们都要接受服务框架的强约束,负载均衡要由调用方在客户端执行,运算逻辑比较重。
- 客户端要维护所有调用方地址,一旦节点变动,路由及负载均衡再平衡会比较复杂。
- 日志收集、服务监控等服务治理能力,需要在每个服务方自己实现。
- 不同语言的客户端需要开发单独的 SDK 。
边车模式(Sidecar)
在直连模式中,微服务和 SDK 的强耦合导致胃服务的开发受到一定限制,包括技术选型都要考虑与微服务框架的 SDK 兼容,相互影响。为了解决这些问题,SerivceMesh 出现了。
ServiceMesh 可以简单理解为将直连模式中的 SDK 拆分出来,以独立进程的模式和应用部署在同一个节点上,通过修改操作系统的底层网络配置(比如 linux 的 iptables),对本地网络的调用链路进行调整。
服务调用方将微服务应用发出的所有网络调用通过本地环回接口或地址(Loopback),直接发送到本机的本地代理程序 ServiceMesh,ServiceMesh 再根据请求的路由和负载均衡算法,最终决定向哪个远程网络节点发起真正的网络请求,每个节点上的微服务进程+ServiceMesh 组成当前服务的一个节点。
思考
本人所在的上一家公司是通过代理网关实现的服务端发现,目前所在的公司是基于框架 SDK 实现的客户端发现,你所在的公司是用的什么架构和开源组件呢。
更多推荐
所有评论(0)