Skip to content

Instantly share code, notes, and snippets.

@ScienJus
Last active April 16, 2020 09:43
Show Gist options
  • Save ScienJus/f0c08baab99fe8feb06c1042c78bdf48 to your computer and use it in GitHub Desktop.
Save ScienJus/f0c08baab99fe8feb06c1042c78bdf48 to your computer and use it in GitHub Desktop.
SOFA Consul Registry

Sofa Consul Registry

Sofa Consul Registry 的实现,介绍 consul 服务注册发现 API、数据模型、健康检查等设计。

Consul API

服务注册

/v1/agent/service/register	

官方推荐使用 agent api 而不是 catalog api,保证应用直连 consul agent,不会经过负载均衡,确保 register 和 deregister 为同个 agent。

参数见数据结构定义。

服务取消注册

/v1/agent/service/deregister/:service_id

service_id 见数据结构定义中的 Id

发现所有服务(SOFA 未使用)

/v1/catalog/services

返回所有服务名和 metadata 信息,SOFA 不需要使用这个 API。

发现一个服务的所有实例

/v1/health/service/:service

因为 Consul 可以通过 agent 进行 health check 并标识服务的健康状态,所以这个 API 只会返回健康的实例(符合预期)。

service 见数据结构定义中的 Name

Watch 服务的实例变更信息

/v1/health/service/:service?index=:index&wait=300s&passing

Consul 通过 Blocking Queries 实现基于长轮训的 Watch 功能。在每次请求时都会返回 X-Consul-Index 标识当前资源的版本状态,之后的请求携带上对应值将会阻塞该请求。直到数据发生变更时(即 Index 发生变化时)或是超过了设置的最长阻塞时间,请求才会返回。

service 见数据结构定义中的 Name

数据结构定义

Consul 注册一个服务的定义主要分为四部分:

  1. 服务的基本信息(name/id/host/port)
  2. 服务的元信息(meta/tags)
  3. 服务的健康检查信息(ttl/tcp/http)
  4. 一些配置信息

在此我们只关注前三者

服务基本信息

Consul 中的字段 描述 在 SOFA 中的字段 默认值 是否允许用户配置 在其他注册中心的实现
Id 服务实例的唯一标识 interfaceId + uniqueId + host + port interfaceId + uniqueId + host + port etcd: serviceName:protocol:uniqueId:uuid
zk: bolt://192.168.1.100:22000?xxx=yyy
nacos: 推测是通过 interfaceId + host + port + clusterName
Name 服务名 interfaceId interfaceId 均为 interfaceId
Address 服务地址 host host 均为 host
Port 服务端口 port port 均为 port

问题

在 SOFA 中,interface id 是一个 java interface 的完整类名(例如 com.alipay.sofa.rpc.HelloService),但是 Consul 不推荐 service name 中包含 .,虽然 HTTP API 的服务注册发现能够使用,但是会造成 DNS 功能失效(因为 DNS 功能同样使用了 . 区分 tags),需要考虑几种场景:

  1. 用户的 Consul 只为 SOFA RPC 使用,且只使用 sofa-registry-consul,则 service name 可以使用类名,因为 HTTP API 不会受到影响
  2. 用户的 Consul 会注册其他服务,并使用一些其他组件(例如 Consul Template + Nginx),考虑 . 是否会破坏其他组件的功能,需要提供配置将 . 转义成 -,或是只使用最后一截类名(例如 HelloService)作为 service name
  3. 用户同时使用 Consul DNS 暴露 SOFA 服务,则同样不能出现 .,方案同上。

元信息

Consul 的服务实例元信息提供了两个字段:Meta 和 Tags,前者为 KV 形式,后者为 List 形式(但是也可以通过 key=val 的方式拼接)。

目前看区别主要在于 Tags 可以用于在 Consul 侧进行过滤,而 Meta 只提供存储功能。

所以 unionId 字段可以注册到 tags 中,直接在 Consul 侧过滤所有符合实例,但是这不是必须的,拉取所有实例并通过 RegistryUtils#matchProviderInfos 可能更容易保证逻辑统一。

Meta 可以直接通过 RegistryUtils#convertProviderToMap 生成,和 nacos 实现保持统一。

健康检查信息

Consul 主要提供了三种健康检查方式,TTL 心跳、服务端主动 TCP 探活和服务端主动 HTTP 探活。

  1. TTL 心跳是目前提供的方式,实现简单,但是心跳可能未必准确反映服务健康状态
  2. TCP 探活能至少保证服务暴露的端口可用,但是也无法反映出服务详细健康状态
  3. HTTP 心跳在使用 Web 应用(尤其是 Spring Boot Actuator 或是 SOFA Boot)时,可以实现类似 Readiness 功能,在这些场景下是首选。

个人倾向为三种方式均可通过配置项配置,默认采用第一种或是第二种方式。

TBD...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment