迈出云原生重要一步 — Dubbo 3 应用级服务发现
喜欢就关注我们吧!
Dubbo 与开源中国共同策划【Dubbo 云原生之路】系列文章,和大家一起回顾 Apache Dubbo 社区的发展。这是系列第二篇。系列文章主要涵盖 Dubbo 技术解读、社区运营、应用案例解析三大部分。
在这里,我们也向所有的 Dubbo 用户和开发者发出投稿邀请,如果你正在使用 Dubbo,或是正在为 Dubbo 贡献力量,欢迎和我们分享你的开发使用经验,优质文章也会收录进【Dubbo 云原生之路】系列。
投稿地址:[email protected]
本文作者:刘军花名陆龟,Github 账号 Chickenlj,Apache Dubbo PMC,项目核心开发,见证了 Dubbo 重启开源,到从 Apache 基金会毕业的整个过程。现任职阿里云云原生应用平台团队,参与服务框架、微服务相关工作,目前主要在推动 Dubbo 3.0 - Dubbo 云原生。
一、服务发现(Service Discovery)概述
从 Internet 刚开始兴起,如何动态感知后端服务的地址变化就是一个必须要面对的问题,为此人们定义了 DNS 协议
基于此协议,调用方只需要记住由固定字符串组成的域名,就能轻松完成对后端服务的访问,而不用担心流量最终会访问到哪些机器 IP,因为有代理组件会基于 DNS 地址解析后的地址列表,将流量透明的、均匀的分发到不同的后端机器上。
在使用微服务构建复杂的分布式系统时,如何感知 backend 服务实例的动态上下线,也是微服务框架最需要关心并解决的问题之一。
业界将这个问题称之为 - 微服务的地址发现(Service Discovery),业界比较有代表性的微服务框架如 SpringCloud、Microservices、Dubbo 等都抽象了强大的动态地址发现能力,并且为了满足微服务业务场景的需求,绝大多数框架的地址发现都是基于自己设计的一套机制来实现
因此在能力、灵活性上都要比传统 DNS 丰富得多。如 SpringCloud 中常用的 Eureka, Dubbo 中常用的 Zookeeper、Nacos 等,这些注册中心实现不止能够传递地址(IP + Port),还包括一些微服务的 Metadata 信息,如实例序列化类型、实例方法列表、各个方法级的定制化配置等。
下图是微服务中 Service Discovery 的基本工作原理图,微服务体系中的实例大概可分为三种角色:服务提供者(Provider)、服务消费者(Consumer)和注册中心(Registry)。
而不同框架实现间最主要的区别就体现在注册中心数据的组织:地址如何组织、以什么粒度组织、除地址外还同步哪些数据?
我们今天这篇文章就是围绕这三个角色展开,重点看下 Dubbo 中对于服务发现方案的设计,包括之前老的服务发现方案的优势和缺点,以及 Dubbo 3.0 中正在设计、开发中的全新的面向应用粒度的地址发现方案,我们期待这个新的方案能做到:
支持几十万/上百万级集群实例的地址发现 与不同的微服务体系(如 Spring Cloud)实现在地址发现层面的互通
二、Dubbo 地址发现机制解析
<dubbo:service
interface=
"org.apache.dubbo.samples.basic.api.DemoService"ref=
"demoService"/>
<dubbo:service
interface=
"org.apache.dubbo.samples.basic.api.GreetingService"ref=
"greetingService"/>
2.1 “接口粒度” 服务发现
192.168.0.103 实例注册的数据:
dubbo:
//192.168.0.103:
20880/org.apache.dubbo.samples.basic.api.DemoService?anyhost=
true&application=demo-provider&
default=
true&deprecated=
false&dubbo=
2.0.2&dynamic=
true&generic=
false&interface=org.apache.dubbo.samples.basic.api.DemoService&methods=testVoid,sayHello&pid=
995&release=
2.7.7&side=provider×tamp=
1596988171266dubbo:
//192.168.0.103:
20880/org.apache.dubbo.samples.basic.api.GreetingService?anyhost=
true&application=demo-provider&
default=
true&deprecated=
false&dubbo=
2.0.2&dynamic=
true&generic=
false&interface=org.apache.dubbo.samples.basic.api.GreetingService&methods=greeting&pid=
995&release=
2.7.7&side=provider×tamp=
1596988170816192.168.0.104 实例注册的数据:
dubbo:
//192.168.0.104:
20880/org.apache.dubbo.samples.basic.api.DemoService?anyhost=
true&application=demo-provider&
default=
true&deprecated=
false&dubbo=
2.0.2&dynamic=
true&generic=
false&interface=org.apache.dubbo.samples.basic.api.DemoService&methods=testVoid,sayHello&pid=
995&release=
2.7.7&side=provider×tamp=
1596988171266dubbo:
//192.168.0.104:
20880/org.apache.dubbo.samples.basic.api.GreetingService?anyhost=
true&application=demo-provider&
default=
true&deprecated=
false&dubbo=
2.0.2&dynamic=
true&generic=
false&interface=org.apache.dubbo.samples.basic.api.GreetingService&methods=greeting&pid=
995&release=
2.7.7&side=provider×tamp=
15969881708162.2 “应用粒度” 服务发现
192.168.0.103 实例数据:
{
"name"
:
"demo-provider",
"id"
:
"192.168.0.103:20880",
"address"
:
"192.168.0.103",
"port"
:
20880,
"metadata"
: {
"dubbo.endpoints"
:
"[{\"port\":20880,\"protocol\":\"dubbo\"}]",
"dubbo.metadata.storage-type"
:
"local",
"dubbo.revision"
:
"6785535733750099598" },
"time"
:
1583461240877}
192.168.0.104 实例数据:
{
"name"
:
"demo-provider",
"id"
:
"192.168.0.104:20880",
"address"
:
"192.168.0.104",
"port"
:
20880,
"metadata"
: {
"dubbo.endpoints"
:
"[{"port
":20880,"protocol
":"dubbo
"}]",
"dubbo.metadata.storage-type"
:
"local",
"dubbo.revision"
:
"7829635812370099387"},
"time"
:
1583461240947}
对比以上两种不同粒度的服务发现模式,从 “接口粒度” 升级到 “应用粒度” 后我们可以总结出最大的区别是:注册中心数据量不再与接口数成正比,不论应用提供有多少接口,注册中心只有一条实例数据。
那么接下来我们详细看下这个变化给 Dubbo 带来了哪些好处。
三、Dubbo 应用级服务发现的意义
我们先说结论,应用级服务发现给 Dubbo 带来以下优势:
与业界主流微服务模型对齐,比如 SpringCloud、Kubernetes Native Service 等 提升性能与可伸缩性。注册中心数据的重新组织(减少),能最大幅度的减轻注册中心的存储、推送压力,进而减少 Dubbo Consumer 侧的地址计算压力;集群规模也开始变得可预测、可评估(与 RPC 接口数量无关,只与实例部署规模相关)
3.1 对齐主流微服务模型
实例地址,服务消费方需要知道地址以建立链接 RPC 方法定义,服务消费方需要知道 RPC 服务的具体定义,不论服务类型是 rest 或 rmi 等
服务注册由平台接管,provider 不再需要关心服务注册 consumer 端服务发现将是 Dubbo 关注的重点,通过对接平台层的 API-Server、DNS 等,Dubbo client 可以通过一个 Service Name(通常对应到 Application Name)查询到一组 Endpoints(一组运行 provider 的 pod),通过将 Endpoints 映射到 Dubbo 内部地址列表,以驱动 Dubbo 内置的负载均衡机制工作
Service Name - > Application Name,Dubbo 应用和 Kubernetes 服务一一对应,对于微服务运维和建设环节透明,与开发阶段解耦
: v1
kind
: Service
metadata:
name:provider-app-namespec:
selector:
app:provider-app-name
ports:
-protocol:TCP
port:
targetPort:9376
Service Name - > Dubbo RPC Service,Kubernetes 要维护调度的服务与应用内建 RPC 服务绑定,维护的服务数量变多
apiVersion:v1
kind:Service
metadata:
name:rpc-service-1
spec:
selector:
app:provider-app-name
ports:##
...
---
apiVersion:v1
kind:Service
metadata:
name:rpc-service-2
spec:
selector:
app:provider-app-name
ports:##
...
---
apiVersion:v1
kind:Service
metadata:
name:rpc-service-N
spec:
selector:
app:provider-app-name
ports:##
...
3.2 更大规模的微服务集群 - 解决性能瓶颈
对于 Spring Cloud 和 Kubernetes 模型,注册中心只会存储一条 DEMO - 10.210.134.30+metadata 的数据 对于老的 Dubbo 模型,注册中心存储了三条接口粒度的数据,分别对应三个接口 DemoService 1 2 3,并且很多的址数据都是重复的
四、应用级服务发现工作原理
4.1 设计原则
新的服务发现模型要实现对原有 Dubbo 消费端开发者的无感知迁移,即 Dubbo 继续面向 RPC 服务编程、面向 RPC 服务治理,做到对用户侧完全无感知 建立 Consumer 与 Provider 间的自动化 RPC 服务元数据协调机制,解决传统微服务模型无法同步 RPC 级接口配置的缺点
4.2 基本原理详解
{
"name"
:
"provider-app-name",
"id"
:
"192.168.0.102:20880",
"address"
:
"192.168.0.102",
"port"
:
20880,
"sslPort"
:
null,
"payload"
: {
"id"
:
null,
"name"
:
"provider-app-name",
"metadata"
: {
"metadataService"
:
"{\"dubbo\":{\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"2.7.5\",\"port\":\"20881\"}}",
"endpoints"
:
"[{\"port\":20880,\"protocol\":\"dubbo\"}]",
"storage-type"
:
"local",
"revision"
:
"6785535733750099598",
}
},
"registrationTimeUTC"
:
1583461240877,
"serviceType"
:
"DYNAMIC",
"uriSpec"
:
null}
[
"dubbo://192.168.0.102:20880/org.apache.dubbo.demo.DemoService?anyhost=true&application=demo-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=9585&
release=
2.7.5&side=provider×tamp=
1583469714314",
"
dubbo://
192.168.0.102:
20880/org.apache.dubbo.demo.HelloService?anyhost=
true&application=demo-provider&deprecated=
false&dubbo=
2.0.2&dynamic=
true&generic=
false&
interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=
9585&
release=
2.7.5&side=provider×tamp=
1583469714314",
"
dubbo://
192.168.0.102:
20880/org.apache.dubbo.demo.WorldService?anyhost=
true&application=demo-provider&deprecated=
false&dubbo=
2.0.2&dynamic=
true&generic=
false&
interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=
9585&
release=
2.7.5&side=provider×tamp=
1583469714314"
]
一部分和实例相关的数据继续保留在注册中心,如 ip、port、机器标识等 另一部分和 RPC 方法相关的数据从注册中心移除,转而通过 MetadataService 暴露给消费端
服务提供者启动,首先解析应用定义的“普通服务”并依次注册为 RPC 服务,紧接着注册内建的 MetadataService 服务,最后打开 TCP 监听端口 启动完成后,将实例信息注册到注册中心(仅限 ip、port 等实例相关数据),提供者启动完成 服务消费者启动,首先依据其要“消费的 provider 应用名”到注册中心查询地址列表,并完成订阅(以实现后续地址变更自动通知) 消费端拿到地址列表后,紧接着对 MetadataService 发起调用,返回结果中包含了所有应用定义的“普通服务”及其相关配置信息 至此,消费者可以接收外部流量,并对提供者发起 Dubbo RPC 调用
4.3 服务自省中的关键机制
内建 MetadataService 独立的元数据中心,通过中细化的元数据集群协调数据
<dubbo:registryaddress="zookeeper://127.0.0.1:2181"/>
<dubbo:referenceinterface="RPC Service 1" />
<dubbo:referenceinterface="RPC Service 2" />
<dubbo:referenceinterface="RPC Service N" />
<dubbo:registryaddress="zookeeper://127.0.0.1:2181?registry-type=service"/>
<dubbo:referenceinterface="RPC Service 1"provided-by="provider-app-x"/>
<dubbo:referenceinterface="RPC Service 2"provided-by="provider-app-x" />
<dubbo:referenceinterface="RPC Service N"provided-by="provider-app-y" />
五、总结与展望
▼
觉得不错,请点个在看呀
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。