Service Mesh学习(2)——注册中心

目录

服务注册发现

服务注册中心

注册中心的健康检查设计

服务主动探活

注册中心主动发起健康检查

注册中心不进行任何健康检查,由调用方负载均衡器进行健康检查。

注册中心选型

总结


服务注册发现是为服务架构引进最先需要解决的问题。服务注册与发现就是保证当服务上下线发生变更时,服务消费者和服务提供者能够保持正常通信。在分布式架构中,服务会注册到注册中心,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。注册中心时微服务中的最重要的内容,也是和SOA架构(面向服务的架构SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来)中的集中总线通信最大的区别点。

服务注册发现

在单体服务架构中,假设只有一个服务,这个服务前面就是像nginx这样的网关系统,负责负载均衡,而后端的机器节点也是我们手动配置上去的,比如:

upstream backend{
  server 10.0.0.1:80
  server 10.0.0.2:80
}

如果机器不够用了,就增加一个节点,然后reload nginx就好了。但是当这个项目不断扩大,继续开发2期、3期...,新老项目共用一个用户体系,很多服务使用同一个数据库,数据库压力也会越来越大,我们这时候会将用户模块拆成一个单独的服务,这样单体服务演进到微服务。

第一个问题来了,单体服务和用户服务怎么通信呢?可以选择RPC协议或HTTP协议来通信。

那如何保证服务的高可用(系统所能提供无故障服务的一种能力,即避免因服务器宕机而造成的服务不可用的情况)呢?

我们或许会这样做,和单体服务一样,给用户服务配置一个内部网关用作负载均衡。因为内部服务数量不多,比较容易应付增加机器带来的网关配置变动。

随着项目越来越复杂,修正 Bug 和正确地添加新功能变得更加困难,我们就会继续拆分服务,当服务数量上升到两位数,我们就会发现每次因为机器负载瓶颈而增加j机器

时,需要修改很多份内网网关配置,理所当然,修改配置带来的维护成本和出错的概率都会呈指数级增加。服务注册发现应运而生

通过示意图我们知道:服务在启动时,将自己的信息注册到服务发现组件中,服务发现组件会存储这些信息。服务消费者可从服务发现组件查询服务提供者的网络地址,并使用该地址调用服务提供者接口。而当服务提供者网络地址发生变更时,会重新注册到服务发现组件。使用这种方式,服务消费者就无须人工修改提供者的网络地址了。

服务注册发现最大的用处就是解决需要在网关或者 LB 中,手动配置服务地址的问题。你可以无须手动配置,自动地让调用端服务发现被调用端服务的机器节点。

服务注册中心

怎样利用服务注册发现解决多个服务间的通信问题呢?

举一个简单的例子,刚进入一个新公司尚未认识其他部门同事,但是你的业务完成需要跨部门协作,这时你该怎么联系这些人?一般来说你的公司会用钉钉或者是飞书,整个公司有一个通讯录,组织架构中的所有联系人都会在列表中,当你联系其他部门同事时,就可以通过这个列表私聊他们。你用这个列表解决了与其他部门成员通信的问题,而解决多个服务间通信问题的工具,我们称之为服务注册中心。所以有些人也会把注册中心叫作名字服务,顾名思义,也就是通过服务名查找对应的服务地址的服务,这有点像手机中的“通讯录”——通过人名查找手机号。在分布式架构中,注册中心承接了服务的地址录入和查找功能。

想解决多个服务间的通信问题,只要实现一个注册中心服务,让业务服务在启动的时候调用注册接口注册上来,再由注册中心服务把注册上来的机器信息存储起来,当其他服务调用时,通过 watch 服务名发现这个服务的后端机器节点,就可以了。

注册中心的健康检查设计

注册中心,健康检查功能是必不可少的。我们需要有一定的健康检查机制来确保服务节点的健康状态。大致有三种不同的健康检查方式。

服务主动探活

服务通过定时发送续租信息到注册中心,以表明自己节点的存活。这种方式使用最多。

适用场景:若服务集群规模不大,或者选用了类似 Eureka 这样的最终一致性的注册中心,服务主动探活绝对是最优的选择。

优点:能最大程度避免了在Kubernetes环境中,因为 IP 重用导致节点在旧的服务上依然存活的问题,毕竟续租信息都是带着服务信息上报到注册中心的。

缺点:造成注册中心的写操作变多和主动租约。特别是在服务发布时,节点会产生比较大的变动,注册中心的写压力也就会变大。而且强一致性的注册中心,节点变化一定要主节点确认,如果没有做注册中心的读写分离,就会产生大量的通知事件,对带宽、CPU 来说都是灾难性的问题,这个时候注册中心已经完全没有办法响应 TTL 的租约请求,也会导致大量的节点失效。主动租约,其实并不足以说明服务是健康的,毕竟有些情况下,服务虽然无法对外提供服务了,但还是可以对外发送租约请求的。

注册中心主动发起健康检查

服务在进行服务注册时,向注册中心表明自己的健康检查接口,比如 /ping 或者 TCP 端口,注册中心通过定时访问的方式,探明节点是否存活。

优点:在一定程度上解决了服务主动探活并不能说明服务健康的问题,毕竟通过 /ping 这种健康检查接口很大程度上可以说明服务的健康度。在Kubernetes环境中,也是通过对 Pod 进行主动健康检查来判定 Pod 的健康度的。

缺点: IP 重用问题。如果两个服务都用了 /ping 接口做健康检查,并且端口一致,就很容易发生节点在旧服务被重新激活的问题。当然可以参考 Envoy 做服务名称的 check来解决。

注册中心不进行任何健康检查,由调用方负载均衡器进行健康检查。

注册中心不进行任何探活机制,全部由调用方的负载均衡器进行主动和被动探活。这种方式有些极端,它不做任何健康检查,完全靠负载均衡器的能力。

使用场景:使用了 gRPC 这样比较完善的 RPC 库。一般都有自动摘除节点的能力。

缺点:如果 IP 被重用,节点很大概率会一直存在在旧服务中,这样的脏数据随时都是风险点。

优化:此方案可以在做健康检查的同时,注册中心下发包含健康节点和非健康节点的数据到服务节点,并针对健康检查未通过的删除节点设置一个较长的过期时间,这样就可以解决 IP 重用产生脏数据的问题了。

优化过后的方案是稳定性最高的方案,也是最容易实现的方案。

注册中心选型

特征NacosEurekaZookeeperConsulEtcd
一致性协议APAPCPCPCP
健康检查

TCP/HTTP/MYSQL

/Client Beat

Client BeatKeep Alive

TCP/HTTP/

gRPC/Cmd

TTL
网络异常保护支持支持不支持支持不支持
语言实现JavaJavaJavaGo

Go

详细对比,见微服务:注册中心ZooKeeper、Eureka、Consul 、Nacos对比

根据CAP 理论,一致性(Consistency 所有节点在同一时间具有相同的数据)、可用性(Availability 保证每个请求不管成功或者失败都有响应)、分区容错性(Partition tolerance 系统中任意信息的丢失或失败不会影响系统的继续运作),这三者不可能都取,只能取其中2个。在注册中心这个场景中,一致性要求并不是很高,只要达到最终的一致性即可。毕竟涉及节点的注册和反注册,我们通知到客户端,也需要一定时间,一致性本身就是几乎不可能达到的事情。

在注册中心这个场景中,一致性要求并不是很高,只要达到最终的一致性即可。毕竟涉及节点的注册和反注册,我们通知到客户端,也需要一定时间,一致性本身就是几乎不可能达到的事情。

所以在选型的时候,优先选择 AP 的系统。如果技术栈是 Go ,但又担心 Java 的组件不好维护,你也可以考虑自研注册中心,当然 CP 的注册中心并非不可用,在服务集群规模比较小的情况下,也是可以选择的。

总结

在做服务注册发现的时候,一定要坚持一个原则——不要陷入过度重视时效性的误区。作为一个程序员,肯定特别重视程序的性能,就容易陷入推送时效性的竞赛中,但在注册中心这个场景,保证微服务集群的稳定性是第一优先级。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值