Skip to content
Permalink
Browse files
correct some typos in application-discovery-blog (#904)
  • Loading branch information
plusmancn committed Aug 26, 2021
1 parent ed61707 commit 08688890c53b4e61f93846ecbb07f30d8e6e804a
Showing 1 changed file with 14 additions and 14 deletions.
@@ -62,7 +62,7 @@ dubbo://192.168.0.104:20880/org.apache.dubbo.samples.basic.api.GreetingService?a

192.168.0.103 与 192.168.0.104 两个实例共享一份注册中心数据,如下:

```text
```json
{
"name": "demo-provider",
"id": "192.168.0.103:20880",
@@ -77,8 +77,7 @@ dubbo://192.168.0.104:20880/org.apache.dubbo.samples.basic.api.GreetingService?a
}
```



```json
{
"name": "demo-provider",
"id": "192.168.0.104:20880",
@@ -91,6 +90,7 @@ dubbo://192.168.0.104:20880/org.apache.dubbo.samples.basic.api.GreetingService?a
},
"time": 1583461240877
}
```

对比以上两种不同粒度的服务发现模式,从 “接口粒度” 升级到 “应用粒度” 后我们可以总结出最大的区别是:注册中心数据量不再与接口数成正比,不论应用提供有多少接口,注册中心只有一条实例数据。

@@ -105,7 +105,7 @@ dubbo://192.168.0.104:20880/org.apache.dubbo.samples.basic.api.GreetingService?a
### 3.1 对齐主流微服务模型
自动、透明的实例地址发现(负载均衡)是所有微服务框架需要解决的事情,这能让后端的部署结构对上游微服务透明,上游服务只需要从收到的地址列表中选取一个,发起调用就可以了。要实现以上目标,涉及两个关键点的自动同步:

* 实例地址,服务消费方需要知道地址以建立链接
* 实例地址,服务消费方需要知道地址以建立连接
* RPC 方法定义,服务消费方需要知道 RPC 服务的具体定义,不论服务类型是 rest 或 rmi 等。

![img2](/imgs/blog/service-discovery-2.png)
@@ -116,7 +116,7 @@ dubbo://192.168.0.104:20880/org.apache.dubbo.samples.basic.api.GreetingService?a

**1. Spring Cloud**

Spring Cloud 通过注册中心只同步了应用与实例地址,消费方可以基于实例地址与服务提供方建立链接,但是消费方对于如何发起 http 调用(SpringCloud 基于 rest 通信)一无所知,比如对方有哪些 http endpoint,需要传入哪些参数等。
Spring Cloud 通过注册中心只同步了应用与实例地址,消费方可以基于实例地址与服务提供方建立连接,但是消费方对于如何发起 http 调用(SpringCloud 基于 rest 通信)一无所知,比如对方有哪些 http endpoint,需要传入哪些参数等。

RPC 服务这部分信息目前都是通过线下约定或离线的管理系统来协商的。这种架构的优缺点总结如下。
优势:部署结构清晰、地址推送量小;
@@ -202,7 +202,7 @@ Dubbo 要支持 Kubernetes native service,相比之前自建注册中心的服
对比起来 Dubbo 则相对是比较特殊的存在,更多的是从 RPC 服务的粒度去设计的。
> 对应 REST 成熟度模型中的 L4 级别。
如我们上面针对每种模型做了详细的分析,每种模型都有其优势和不足。而我们最初决定 Dubbo 要做出改变,往其他的微服务发现模型上的对齐,是我们最早在确定 Dubbo 的云原生方案时,我们发现要让 Dubbo 去支持 Kubernetes Native Service,模型对齐是一个基础条件;另一点是来自用户侧对 Dubbo 场景化的一些工程实践的需求,得益于 Dubbo 对多注册、多协议能力的支持,使得 Dubbo 联通不同的微服务体系成为可能,而服务发现模型的不一致成为其中的一个障碍,这部分的场景描述请参见以下文章:https://www.atatech.org/articles/157719
如我们上面针对每种模型做了详细的分析,每种模型都有其优势和不足。而我们最初决定 Dubbo 要做出改变,往其他的微服务发现模型上的对齐,是我们最早在确定 Dubbo 的云原生方案时,我们发现要让 Dubbo 去支持 Kubernetes Native Service,模型对齐是一个基础条件;另一点是来自用户侧对 Dubbo 场景化的一些工程实践的需求,得益于 Dubbo 对多注册、多协议能力的支持,使得 Dubbo 联通不同的微服务体系成为可能,而服务发现模型的不一致成为其中的一个障碍,这部分的场景描述请参见以下文章:[Dubbo 如何成为连接异构微服务体系的最佳服务开发框架](https://developer.aliyun.com/article/740260)

### 3.2 更大规模的微服务集群 - 解决性能瓶颈
这部分涉及到和注册中心、配置中心的交互,关于不同模型下注册中心数据的变化,之前原理部分我们简单分析过。为更直观的对比服务模型变更带来的推送效率提升,我们来通过一个示例看一下不同模型注册中心的对比:
@@ -215,17 +215,17 @@ Dubbo 要支持 Kubernetes native service,相比之前自建注册中心的服
* 对于老的 Dubbo 模型,注册中心存储了三条接口粒度的数据,分别对应三个接口 DemoService 1 2 3,并且很多的址数据都是重复的;

可以总结出,基于应用粒度的模型所存储和推送的数据量是和应用、实例数成正比的,只有当我们的应用数增多或应用的实例数增长时,地址推送压力才会上涨。
而对于基于接口粒度的模型,数据量是和接口数量正相关的,鉴于一个应用通常发布多个接口的现状,这个数量级本身比应用粒度是要乘以倍数的;另外一个关键点在于,接口粒度导致的集群规模评估的不透明,相对于实i例、应用增长都通常是在运维侧的规划之中,接口的定义更多的是业务侧的内部行为,往往可以绕过评估给集群带来压力。
而对于基于接口粒度的模型,数据量是和接口数量正相关的,鉴于一个应用通常发布多个接口的现状,这个数量级本身比应用粒度是要乘以倍数的;另外一个关键点在于,接口粒度导致的集群规模评估的不透明,相对于实例、应用增长都通常是在运维侧的规划之中,接口的定义更多的是业务侧的内部行为,往往可以绕过评估给集群带来压力。

以 Consumer 端服务订阅举例,根据我对社区部分 Dubbo 中大规模头部用户的粗略统计,根据受统计公司的实际场景,一个 Consumer 应用要消费(订阅)的 Provier 应用数量往往要超过 10 个,而具体到其要消费(订阅)的的接口数量则通常要达到 30 个,平均情况下 Consumer 订阅的 3 个接口来自同一个 Provider 应用,如此计算下来,如果以应用粒度为地址通知和选址基本单位,则平均地址推送和计算量将下降 60% 还要多,
而在极端情况下,也就是当 Consumer 端消费的接口更多的来自同一个应用时,这个地址推送与内存消耗的占用将会进一步得到降低,甚至可以超过 80% 以上。

一个典型的几段场景即是 Dubbo 体系中的网关型应用,有些网关应用消费(订阅)达 100+ 应用,而消费(订阅)的服务有 1000+ ,平均有 10 个接口来自同一个应用,如果我们把地址推送和计算的粒度改为应用,则地址推送量从原来的 n * 1000 变为 n * 100,地址数量降低可达近 90%。
一个典型的极端场景即是 Dubbo 体系中的网关型应用,有些网关应用消费(订阅)达 100+ 应用,而消费(订阅)的服务有 1000+ ,平均有 10 个接口来自同一个应用,如果我们把地址推送和计算的粒度改为应用,则地址推送量从原来的 n * 1000 变为 n * 100,地址数量降低可达近 90%。

## 4 应用级服务发现工作原理

### 4.1 设计原则
上面一节我们从**服务模型****支撑大规模集群**的角度分别给出了 Dubbo 往应用级服务发现靠拢的好处或原因,但这么做的同时接口粒度的服务治理能力还是要继续保留,这是 Dubbo 框架编程模型易用性、服务治理能力优势的基础。
上面一节我们从**服务模型****支撑大规模集群**的角度分别给出了 Dubbo 往应用级服务发现靠拢的好处和原因,但这么做的同时接口粒度的服务治理能力还是要继续保留,这是 Dubbo 框架编程模型易用性、服务治理能力优势的基础。
以下是我认为我们做服务模型迁移仍要坚持的设计原则

* 新的服务发现模型要实现对原有 Dubbo 消费端开发者的无感知迁移,即 Dubbo 继续面向 RPC 服务编程、面向 RPC 服务治理,做到对用户侧完全无感知。
@@ -289,7 +289,7 @@ Dubbo 要支持 Kubernetes native service,相比之前自建注册中心的服
> * 一部分和实例相关的数据继续保留在注册中心,如 ip、port、机器标识等。
> * 另一部分和 RPC 方法相关的数据从注册中心移除,转而通过 MetadataService 暴露给消费端。
>
> **理想情况下是能达到数据按照实例、RPC 服务严格区分开来,但明显可以看到以上实现版本还存在一些数据冗余,有些也数据还未合理划分。尤其是 MetadataService 部分,其返回的数据还只是简单的 URL 列表组装,这些 URL其实是包含了全量的数据。**
> **理想情况下是能达到数据按照实例、RPC 服务严格区分开来,但明显可以看到以上实现版本还存在一些数据冗余,有些数据也还未合理划分。尤其是 MetadataService 部分,其返回的数据还只是简单的 URL 列表组装,这些 URL其实是包含了全量的数据。**
以下是服务自省的一个完整工作流程图,详细描述了服务注册、服务发现、MetadataService、RPC 调用间的协作流程。

@@ -308,13 +308,13 @@ Dubbo 要支持 Kubernetes native service,相比之前自建注册中心的服

Client 与 Server 间在收到地址推送后的配置同步是服务自省的关键环节,目前针对元数据同步有两种具体的可选方案,分别是:
* 内建 MetadataService。
* 独立的元数据中心,通过中细化的元数据集群协调数据
* 独立的元数据中心,通过中心化的元数据集群协调数据

**1. 内建 MetadataService**
MetadataService 通过标准的 Dubbo 协议暴露,根据查询条件,会将内存中符合条件的“普通服务”配置返回给消费者。这一步发生在消费端选址和调用前。

**元数据中心**
复用 2.7 版本中引入的元数据中心,provider 实例启动后,会尝试将内部的 RPC 服务组织成元数据的格式到元数据中心,而 consumer 则在每次收到注册中心推送更新后,主动查询元数据中心。
**2. 元数据中心**
复用 2.7 版本中引入的元数据中心,provider 实例启动后,会尝试将内部的 RPC 服务组织成元数据的格式同步到元数据中心,而 consumer 则在每次收到注册中心推送更新后,主动查询元数据中心。

> 注意 consumer 端查询元数据中心的时机,是等到注册中心的地址更新通知之后。也就是通过注册中心下发的数据,我们能明确的知道何时某个实例的元数据被更新了,此时才需要去查元数据中心。
@@ -348,7 +348,7 @@ MetadataService 通过标准的 Dubbo 协议暴露,根据查询条件,会将

以上问题的根源在于注册中心不知道任何 RPC 服务相关的信息,因此只能通过应用名来查询。

为了使整个开发流程对老的 Dubbo 用户更透明,同时避免指定 provider 对可扩展性带来的影响(参见下方说明),我们设计了一套 `RPC 服务到应用名`的映射关系,以尝试在 consumer 自动完成 RPC 服务到 provider 应用名的转换。
为了使整个开发流程对老的 Dubbo 用户更透明,同时避免指定 provider 对可扩展性带来的影响(参见下方说明),我们设计了一套 `RPC 服务到应用名`的映射关系,以尝试在 consumer 端自动完成 RPC 服务到 provider 应用名的转换。

![img11](/imgs/blog/service-discovery-11.png)

0 comments on commit 0868889

Please sign in to comment.