当我们谈注册中心时谈什么?

当我们谈注册中心时谈什么?

閱讀本文約花費: 11 (分鐘)

最近工作重心转向了注册中心,于是想来写一篇关于注册中心的文章

概念

什么是注册中心,以大多数人熟悉的RPC框架来说,通常RPC中有三种角色:

  • provider 服务提供者
  • consumer 服务消费者,即调用方
  • registry 注册中心,让consumer能发现provider的关键

注册中心对于服务提供者需要具备服务注册、注销的能力,对于服务消费者需要提供查询服务、感知服务变化的功能。当然还需要解决一些其他问题才能成为一个优秀的注册中心,如高可用、高性能、水平扩展能力、服务探活能力、路由功能、多机房(多活)能力等。

特性详解

存储

可以将注册中心理解为一个存储系统,存储着服务名与服务提供方的映射表。由此可见DNS是目前使用最广泛的注册中心。一般注册中心对存储没有什么要求,甚至你可以基于数据库来实现一个注册中心。

高可用

在聊高可用前,假定你了解分布式CAP理论,如果不知道可以稍微网上查一下,这里就不赘述。

其中对注册中心的高可用要求尤其高,它有如下几层含义,首先肯定是集群部署,无单点问题,其次就算整个集群挂掉了,也不能影响现有服务的调用,只不过现有的调用关系无法及时改变而已。

在分布式理论CAP中,注册中心更理想的应该是AP模式。(此结论更多讨论参考文末的《阿里巴巴为什么不用ZooKeeper做服务发现》),可以简单的从以下两个场景来理解:​

  • 注册中心挂掉一个节点无任何影响,如果注册中心是CP模式(强一致),像ZAB、raft协议,它们存在一个“选主”的过程,通常选主时集群是不可写的
  • 如果集群出现“脑裂”的情况,假设5个的节点脑裂为3+2,CP模式下2个节点将完全不可用,如果牺牲一致性,至少保证节点都可访问,对服务的影响应该比完全不可用要小很多

水平扩展

水平扩展说的是如果规模上去后,能否通过加机器的方式来解决性能问题,从这点来说,AP模式也比CP模式更容易扩展,CP模式一般写发生在主节点,所以扩展变得很麻烦,如果写能分散到不同节点,就是可扩展的,以最简单的数据库实现来说,就可以认为是可以水平扩展的,毕竟数据库的写可以通过分库分表或者分布式数据库来解决。

服务探活

在说服务探活前需要介绍一下服务注册的维度,维度影响到探活。一般来说,服务注册的维度有两个:服务维度和应用维度。

  • 服务维度:注册的是接口到ip、port的映射关系,如dubbo(dubbo新版本也支持应用级服务发现,但大多数还是在以服务维度的服务发现在使用),优点是注册信息跟应用无关,可以方便地拆分服务,缺点是粒度太细,注册数据量大。
  • 应用维度:注册的是应用到ip、port的映射关系,如spring cloud,优点是注册数据量小,缺点是拆分服务困难

通常探活也有两种方式,一种是服务端主动探活,另一种是客户端上报心跳。对于应用级的服务探活很简单,只要确定端口是否存活就可以判断应用的存活,所以服务端主动探活即可解决;但服务维度就不行,一般没有现有的方法知道服务是否存活,所以如果想要服务端主动探活,需要RPC框架暴露接口来告知服务端存活的服务,要么就是采取客户端主动上报心跳来告知有哪些服务是存活的。

通常客户端主动上报可以很明确知道服务是否存活,但服务端主动探活不行,有时候端口在,不一定就代表服务是活的。这又是一个问题,探活探死的问题,探死通常很直接,探活很困难,端口不在就一定是死的,但端口在不一定是活的。

关于探活还要说的是方式的选择,通常不同的业务要求也不一样,检查端口是否存在,尝试建立一次连接,请求一次健康检查接口等等,这块nacos做的比较好,可根据需求扩展探活方式,也内置了很多探活方式。

路由功能

此项不是必选,但有了就会很强。

比如很多公司都有多套环境,如开发、测试,预发,线上环境,通常开发和测试的环境是单独部署,但线上和预发就不一定会单独部署。试想没有路由能力的注册中心,如果想线上只调用线上,预发只调用预发时,是不是必须得部署两套注册中心(以zk为例)。但如果给注册中心增加一个路由功能,线上consumer只消费线上provider,预发consumer只消费预发provider,那这样就只需要部署一套环境。

当然路由能力不仅限于此,还可以解决多机房就近调用问题,甚至可以完成很多更有想象力,更有意思的事情。

多机房支持

其实从上面的描述中已经发现,如果需要支持多机房,CP是更好的选择,最好能用路由能力解决多机房就近调用问题,假设有A、B两个机房,X服务只在A机房部署,Y服务在A、B机房都有部署,如果X调用Y,最好的选择是调用A机房的Y而不是更远的B机房。

多机房是部署一套注册中心,还是每个机房都部署一套注册中心?其实两种方案都可以,部署一套注册中心需要保证每个机房的服务注册都要请求这个注册中心,存储数据是一份,这样的问题是跨机房调用时延高,但如果是专线,这个问题也不是太大。如果每个机房都部署一个注册中心,就没有时延问题,但不可能每个机房都不需要感知其他机房的服务,这样就需要有数据同步的机制,数据同步就意味着注册与发现有时延,而且多中心的数据一致性保证比较复杂。

如何做技术选型

如果选择开源产品,是否符合公司技术栈、能否cover住将是第一选择要点,例如使用dubbo,哪些注册中心对dubbo的支持比较友好?哪些注册中心是java技术栈?

其次是对注册中心特殊能力的需求,如业务在高速发展中,需要考虑下性能和水平扩展能力;如想在注册中心上做一些流量的控制,可以考虑选型的注册中心是否有路由能力;如想快速准确的摘除故障机器,那么需要考虑下注册中心的服务探活能力能否满足需求;如有多机房建设的需求,需要考虑注册中心对多机房的支持是否友好,是否支持“就近调用”等特性。

当然开源产品各有千秋,常见的像zookeeper、nacos、eureka、consul等,大厂遇到的场景通常比较复杂,一般会定制自己的注册中心,如蚂蚁的sofa-registry、饿了么的Huskar、美团的MNS、有赞的Haunt。

这里介绍下zk和nacos来作为结尾。

zookeeper

zk是在dubbo中使用最多的注册中心,但它本身不是为了服务发现而生。

它是一个基于ZAB协议实现的可靠的分布式协调系统,它是强一致(CP)、使用基于TCP的私有协议通信。由于ZAB协议中写入是只能由主节点发起,所以写入只能是在单机上完成,故水平扩展困难,也不支持多机房、路由管理等功能。

zk中的数据类似文件系统的树形结构,节点分为两种,一种是临时节点,一种是永久节点,临时节点不可保存数据,永久节点可以保存数据,临时节点在服务端与客户端的长连接断开后一段时间会被摘除。

一句话总结:dubbo的第一选择,中小企业适用

nacos

nacos是阿里开源的注册中心&配置中心,作为注册中心它使用的是自研的distro协议,一种AP的协议,具体可以看之前的文章《nacos的一致性协议distro介绍》

目前可以使用http和dns协议来访问nacos,未来可能可以通过grpc来访问,可以水平扩展,但目前的性能不高,未来实现长连接后会有所改善,多机房可以通过扩展其CMDB模块来实现,支持权重、保护阈值等负载均衡策略。

社区也提供了nacosSync工具来迁移其他注册中心到nacos注册中心,有关迁移实践可以查看这篇文章《zookeeper到nacos的迁移实践 》

一句话总结:特性比zk丰富,但开源不久,稳定性、性能不够。

参考

Rate this post

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注