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.

Revisions

  1. ScienJus revised this gist Apr 14, 2019. 1 changed file with 10 additions and 0 deletions.
    10 changes: 10 additions & 0 deletions sofa-consul-registry.md
    Original file line number Diff line number Diff line change
    @@ -70,6 +70,16 @@ Consul 注册一个服务的定义主要分为四部分:
    | 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` 的方式拼接)。
  2. ScienJus revised this gist Feb 27, 2019. 1 changed file with 10 additions and 0 deletions.
    10 changes: 10 additions & 0 deletions sofa-consul-registry.md
    Original file line number Diff line number Diff line change
    @@ -40,6 +40,16 @@ Sofa Consul Registry 的实现,介绍 consul 服务注册发现 API、数据

    `service` 见数据结构定义中的 `Name`

    ### Watch 服务的实例变更信息

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

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

    `service` 见数据结构定义中的 `Name`

    ## 数据结构定义

    Consul 注册一个服务的定义主要分为四部分:
  3. ScienJus revised this gist Feb 22, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion sofa-consul-registry.md
    Original file line number Diff line number Diff line change
    @@ -55,7 +55,7 @@ Consul 注册一个服务的定义主要分为四部分:

    | Consul 中的字段 | 描述 | 在 SOFA 中的字段 | 默认值 | 是否允许用户配置 | 在其他注册中心的实现 |
    | --- | --- | --- | --- | --- | --- |
    | Id | 服务实例的唯一标识 | host + port | host + port | 否 | etcd: `serviceName:protocol:uniqueId:uuid`<br>zk: `bolt://192.168.1.100:22000?xxx=yyy`<br>nacos: 推测是通过 host + port + clusterName
    | Id | 服务实例的唯一标识 | interfaceId + uniqueId + host + port | interfaceId + uniqueId + host + port | 否 | etcd: `serviceName:protocol:uniqueId:uuid`<br>zk: `bolt://192.168.1.100:22000?xxx=yyy`<br>nacos: 推测是通过 interfaceId + host + port + clusterName
    | Name | 服务名 | interfaceId | interfaceId || 均为 interfaceId |
    | Address | 服务地址 | host | host || 均为 host |
    | Port | 服务端口 | port | port || 均为 port |
  4. ScienJus revised this gist Feb 22, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion sofa-consul-registry.md
    Original file line number Diff line number Diff line change
    @@ -55,7 +55,7 @@ Consul 注册一个服务的定义主要分为四部分:

    | Consul 中的字段 | 描述 | 在 SOFA 中的字段 | 默认值 | 是否允许用户配置 | 在其他注册中心的实现 |
    | --- | --- | --- | --- | --- | --- |
    | Id | 服务实例的唯一标识 | host + port | host + port | 否 | etcd: `serviceName:protocol:uniqueId:uuid/zk: `bolt://192.168.1.100:22000?xxx=yyy`/nacos: 推测是通过 host + port + clusterName`
    | Id | 服务实例的唯一标识 | host + port | host + port | 否 | etcd: `serviceName:protocol:uniqueId:uuid`<br>zk: `bolt://192.168.1.100:22000?xxx=yyy`<br>nacos: 推测是通过 host + port + clusterName
    | Name | 服务名 | interfaceId | interfaceId || 均为 interfaceId |
    | Address | 服务地址 | host | host || 均为 host |
    | Port | 服务端口 | port | port || 均为 port |
  5. ScienJus revised this gist Feb 22, 2019. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions sofa-consul-registry.md
    Original file line number Diff line number Diff line change
    @@ -54,6 +54,7 @@ Consul 注册一个服务的定义主要分为四部分:
    ### 服务基本信息

    | Consul 中的字段 | 描述 | 在 SOFA 中的字段 | 默认值 | 是否允许用户配置 | 在其他注册中心的实现 |
    | --- | --- | --- | --- | --- | --- |
    | Id | 服务实例的唯一标识 | host + port | host + port | 否 | etcd: `serviceName:protocol:uniqueId:uuid/zk: `bolt://192.168.1.100:22000?xxx=yyy`/nacos: 推测是通过 host + port + clusterName`
    | Name | 服务名 | interfaceId | interfaceId || 均为 interfaceId |
    | Address | 服务地址 | host | host || 均为 host |
  6. ScienJus revised this gist Feb 22, 2019. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions sofa-consul-registry.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Sofa Consul Registry

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

    ## Consul API

    @@ -12,15 +12,15 @@ Sofa Consul Registry 的实现,介绍 consul 服务注册发现 API、数据

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

    参数见数据结构定义
    参数见数据结构定义

    ### 服务取消注册

    ```
    /v1/agent/service/deregister/:service_id
    ```

    `service_id` 见数据结构定义
    `service_id` 见数据结构定义中的 `Id`

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

    @@ -36,9 +36,9 @@ Sofa Consul Registry 的实现,介绍 consul 服务注册发现 API、数据
    /v1/health/service/:service
    ```

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

    `service` 见数据结构定义
    `service` 见数据结构定义中的 `Name`

    ## 数据结构定义

  7. ScienJus created this gist Feb 22, 2019.
    82 changes: 82 additions & 0 deletions sofa-consul-registry.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    # 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` 见数据结构定义

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

    ```
    /v1/catalog/services
    ```

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

    ### 发现一个服务的所有实例

    ```
    /v1/health/service/:service
    ```

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

    `service` 见数据结构定义

    ## 数据结构定义

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

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

    在此我们只关注前三者

    ### 服务基本信息

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

    ### 元信息

    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...