服务注册发现

服务注册就是维护一个登记簿,它管理系统内所有的服务地址。当新的服务启动后,它会向登记簿交待自己的地址信息。服务的依赖方直接向登记簿要 Service Provider 地址就行了。当下用于服务注册的工具非常多 ZooKeeper,Consul,Etcd, 还有 Netflix 家的 eureka 等。服务注册有两种形式:客户端注册和第三方注册。

客户端注册(zookeeper)

客户端注册是服务自身要负责注册与注销的工作。当服务启动后向注册中心注册自身,当服务下线时注销自己。期间还需要和注册中心保持心跳。心跳不一定要客户端来做,也可以由注册中心负责(这个过程叫探活)。这种方式的缺点是注册工作与服务耦合在一起,不同语言都要实现一套注册逻辑。

image-20231221194243240

第三方注册(独立的服务 Registrar)

第三方注册由一个独立的服务Registrar负责注册与注销。当服务启动后以某种方式通知Registrar,然后 Registrar 负责向注册中心发起注册工作。同时注册中心要维护与服务之间的心跳,当服务不可用时,向注册中心注销服务。这种方式的缺点是 Registrar 必须是一个高可用的系统,否则注册工作没法进展。

image-20231221194329637

客户端发现

客户端发现是指客户端负责查询可用服务地址,以及负载均衡的工作。这种方式最方便直接,而且也方便做负载均衡。再者一旦发现某个服务不可用立即换另外一个,非常直接。缺点也在于多语言时的重复工作,每个语言实现相同的逻辑。

image-20231221194356887

服务端发现

服务端发现需要额外的 Router 服务,请求先打到 Router,然后 Router 负责查询服务与负载均衡。这种方式虽然没有客户端发现的缺点,但是它的缺点是保证 Router 的高可用。

image-20231221194423712

Consul

Consul 是 service mesh(服务网格)的一个解决方案,它提供了诸如服务发现,配置和隔离等功能的一整套控制平面(control plane)。开发人员可以根据需要单独使用这些功能点,也可以将他们整合成为一个完整的service mesh。

Consul 需要一个数据平面(data plane),并支持代理和本地集成模型。Consul 自带了一个简单的代理以实现开箱即用的功能,不过它也支持集成第三方代理框架,比如Envoy。Consul 的核心功能如下:

服务发现: Consul 客户端可以注册一个服务,比如 api 接口或者 mysql 服务,其他的客户端可以通过 Consul 来发现这些服务的提供方。通过 DNS 或者 HTTP,引用可以很方便地找到它所依赖的服务。

健康检查: Consul 客户端可以提供任意数量的健康检查,无论是特定服务(服务是否返回200状态)还是本地节点(比如内存使用率是否大于90%)。运维人员可以通过这些信息管理集群的健康情况,服务发现组件也可以使用这些信息过滤掉不健康节点。

KV 存储: 应用可以使用 Consul 的树状 key/value 存储做很多事情,比如动态配置,开关,协作,leader 选举等等。KV 存储使用的是 HTTP 接口,非常简单易用。

**服务通信加密:**Consul 可以生成并分发 TLS 证书给服务,从而保证服务之间使用 TLS 通信。我们可以使用intentions 组件来自定义允许哪些服务访问。使用 intentions 可以实时地操作服务隔离,这比使用复杂的网络拓扑和静态防火墙规则要简单很多。

多数据中心 Consul 支持开箱即用的多数据中心功能。这意味着当工作区域扩展至多个的时候,用户不需要费心去创建额外的抽象层来满足多中心需求。
Consul 设计时就考虑到了对 DevOps 社区和应用开发者友好,这让它非常适合新兴的弹性架构。

Eureka

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。

SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

Eureka包含两个组件:Eureka Server和Eureka Client。

Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。

在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。

Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

SmartStack

SmartStack是一个服务自动发现和注册的框架。它通过透明地处理你组织中运行代码的创建、删除、异常及维修工作使工程师的日常工作更便利。我们相信这是处理这类问题最好的方案之一:概念简单,易于操作,相比同类 工具 提供更多的可配置性。SmartStack过去一年中一直在Airbnb内部测试,并已在许多大大小小的组织中广泛地应用。

Etcd

image-20231221195041570

你可以看到,按照分层模型,etcd可分为Client层、API网络层、Raft算法层、逻辑层和存储层。这些层的功能如下:

  • Client层:Client层包括client v2和v3两个大版本API客户端库,提供了简洁易用的API,同时支持负载均衡、节点间故障自动转移,可极大降低业务使用etcd复杂度,提升开发效率、服务可用性。
  • API网络层:API网络层主要包括client访问server和server节点之间的通信协议。一方面,client访问etcd server的API分为v2和v3两个大版本。v2 API使用HTTP/1.x协议,v3 API使用gRPC协议。同时v3通过etcd grpc-gateway组件也支持HTTP/1.x协议,便于各种语言的服务调用。另一方面,server之间通信协议,是指节点间通过Raft算法实现数据复制和Leader选举等功能时使用的HTTP协议。
  • Raft算法层:Raft算法层实现了Leader选举、日志复制、ReadIndex等核心算法特性,用于保障etcd多个节点间的数据一致性、提升服务可用性等,是etcd的基石和亮点。
  • 功能逻辑层:etcd核心特性实现层,如典型的KVServer模块、MVCC模块、Auth鉴权模块、Lease租约模块、Compactor压缩模块等,其中MVCC模块主要由treeIndex模块和boltdb模块组成。
  • 存储层:存储层包含预写日志(WAL)模块、快照(Snapshot)模块、boltdb模块。其中WAL可保障etcd crash后数据不丢失,boltdb则保存了集群元数据和用户写入的数据。

概念术语:

  • Raft:etcd所采用的保证分布式系统强一致性的算法。
  • Node:一个Raft状态机实例。
  • Member: 一个etcd实例。它管理着一个Node,并且可以为客户端请求提供服务。
  • Cluster:由多个Member构成可以协同工作的etcd集群。
  • Peer:对同一个etcd集群中另外一个Member的称呼。
  • Client: 向etcd集群发送HTTP请求的客户端。
  • WAL:预写式日志,etcd用于持久化存储的日志格式。
  • snapshot:etcd防止WAL文件过多而设置的快照,存储etcd数据状态。
  • Proxy:etcd的一种模式,为etcd集群提供反向代理服务。
  • Leader:Raft算法中通过竞选而产生的处理所有数据提交的节点。
  • Follower:竞选失败的节点作为Raft中的从属节点,为算法提供强一致性保证。
  • Candidate:当Follower超过一定时间接收不到Leader的心跳时转变为Candidate开始竞选。
  • Term:某个节点成为Leader到下一次竞选时间,称为一个Term。
  • Index:数据项编号。Raft中通过Term和Index来定位数据。
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐