赣州新闻网

首页 / 科技

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

2020-02-27 · 赣州新闻网 · 科技

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

作者 | 刘军

责编 | 屠敏

从编程开发的角度来说,Apache Dubbo (以下简称 Dubbo)首先是一款 RPC 服务框架,它最大的优势在于提供了面向接口代理的服务编程模型,对开发者屏蔽了底层的远程通信细节。同时 Dubbo 也是一款服务治理框架,它为分} ; ) i N i d ]布式部署的微服务提供了服务发现、流量调度等服务治理解决方案。

在这篇文章中,我们将以以上基础能力为背景,尝试突破 Dubboo 8 7 0 3 # 体系自身,探索如何利用 DubboB X - 4 对多协议、多服务发现模A ? P ,型的支持,来实现异构微服( x h Q ( 2 4务体系间的互联互通。在实际z p T n业务场景中,这可以用来解决异构技术体系共存场景下的通信问题,帮助公司实现在异构技术体系间作平滑迁移,解决大规模跨区域、多集群部署场景# F 6 S Q的地址发现及流量调度等问题。

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

面向接口代理的透明服务开发框架

我们还是从 Dubbo 是一个微服务开发框架 这个大家熟知的概念开始g h u , 7 d。就像 Spring 是开发 Java 应用的基础框架一样,我们经常会选用 Dubbo 作为开发微服务业的基础框架。Dubbo 框架的最大优势我认为就在其面向接口的编程模型,使得开发远程服务调用就像开发本地服务一样(以 Java 语言为例):

1、服务定义

public interface GreetingsService {
String sayHi(String name);
}

2、消费方调用服务

// 和调用本地服务一样,完全透明。
@Reference
private Grc S deetingService grey : 3 u V #etingServicv M -e;

public void doSayHello^ h + x(String name) {
greetingService.sayHi(\"Hello world!\");~ Y Q z T f e . M
}

下图是 Dubbo 的基本工作原理图,服务提供者与服务消费者之间通过注册中心协调地址,h = , ` Q Y通过约定的协议实现数据交换。

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

同构/异构微服务体系面临的问题

关于 Dubb U Y _ Y T { bo 协议本身及其服务治理相关功能细节并不是本文的重点,我们今h P $天将从一个更X H # P e高的层次,来看看公司内部构建微服务体系所3 $ K : 3 ^ 面的挑战,以及 Dubbo 能为架构选型和迁移等提供哪些解决思路。

一个公司内部的微服务可能都是基于某一个相同的服务框架开发的,比如说 Dubbo,对于这样的架构,我们称之为是同构的微服务体系;而有些公司的微服务可能是使用多个不同的服务框架所建设,我们称之为异构的微服务体系,多个不同技术栈微服务体系的共存在大型组织内还是非常普遍的,造成这种局面可能有很多$ L P f 5 8 J原因。比如,可能是遗留系统带来的,也可能是公司正在做技术栈迁移,或者就是不同业务k , r ~部门为了满足各自特殊需求而做的独. Y Z E #立选型(这也意味着异构微服务体系的长期共存)。

1、异构微服务体系共存

我们很容易想到的一个挑战是:不同的体系间通常是使用不同的 RPC 通信协议、部署独立的注册中心B L g ? K c + _集群,面对这种多协议、多注册中心集群的场景,要如何实现相互之间透明的地址发现和透X v 7 N f %明的 RPC 调用?如果我们什么L n 0 Y * C都不做,那么每个微服1 $ H 5务体系就只能感知到自己体系内的服务状态,流量也在各自的体系内封闭。而要做到从体系 A 平滑的迁移到体系 B,或者想长期的保持公司内部多个体系的共存,则解决不同体系间的互联互通,实现流量的透明调度将是非常重要的环节。

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

2、D9 3 nubbo 体系内部

多协议、多注册中心集群的问题在同构的微服务体系中也可能存在,尤其是当一个组织W u | + S H D内部的微服务规模增长到一定量级的时候。

  • 我们可能要在不同的服务之间采用不同的通信协议,t } k p因为不同的服务面临不同的业务场景% 6 + j e z } P p,而这也进一步导致了数据传输特点的不同,我们需要分别采用更适合各类业务特点的协议。比如典型的场景:我们可能对于普通的业务服务采用 Dubbo 协议,对于和 Fron2 . ZtEnd 交互的服务需要 HTTP 协议,而对于需要流式数据传输的业务则采? K ~ X ( Y D用 gz i v kRPC 协议等等。

  • Dubbo 体系内部另一个& : S l U 8 d常出现的问题3 , } 0 2 r % ? #是,在大规模分布式部署的场景下,微服务系统会做跨区域、跨注册中心的部! b s署,这个时候就会出现多集群间地址同步和流量调度的问题。

总结起来,不论是同构体系还是异构体系,都面临对多协议通信、多注册中心集群地址. V 1 I w发现的问题。Dubbo 目前是支持多协议、多注+ r 2 = i $册中心的,可以说就是为解决我们上面分析的 Dubbo 同构体系内的场景而设计的,因此下面我们从同构9 u ? | c t ~ `体系的多协议、多注册中心场景7 | o , Y S T K Z讲起,先了解 Dubbo 多协议、多注册中心的基本支持情况以及它们是如何工作的。而在后面的一章再进一步探索怎么扩展z 7 q W这个能力来支持异构微服务体系的互联互通。

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

Dubbo 体系内的多协议、多注册中心机制

我j F : # n H ) & 1们将通过两个场景示例,来分别具体的讲一下 Dubbo 的多协议、多注册中心机制的使用方式和工作原理。

多协议

Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

以上是使用 Dubbo 开发的一套微服务,服务间通信使用到了不同的协议,根据我们的调研发现,公司内部启用多协议其实是非常普遍需求,具体场景在此我们暂不做解释。

应用 B 作为服务提7 z d @ 1 供者,发布了 5 个服务,其中:

  • DemoServicM o t g m R rvice1 DemoService2,使用 gRPC 协议消费# z D DemoSE g B D V H Mervice0。

    应用 B 作为消费者,使用 gRPC 协议消费 DemoSg V - 4 H l v 2 zervice2 DemoService% X 4,使用 dubbo 协议消费 DemoService0。

    以e . 9 b下是具体的代码配置E _ { e 4 Q 2 m ^:

    1、提供端应用 B

    <dubbo:service interface=\"org.apache.dubbo.samples.basic.api.De & 7 m dmoService1\" pro; @ j  ftocol=\"dubbo\"/>
    <dubbo:servic& 5 | Re interface=\"org.apache.dubbo.samples.basic.api.DemoService2\" protocol=\"dubbo\"/>

    &p % O & K Alt;dubbo:service interface6 R 7=\"org.apache.dubbo.samples.basic.api.DemoService3\" protocol=\"grpc\"/>
    <dubbo:service interface=\"org.apache.dubbo.samples.basic.api.B | 9DemoService4\" protocol=\"grpX 0 3 f kc\"/>

    <a i 1 g N 5 B W;dubbo:service interw m ) Sface=\"org.apache.dubbo.samples.basic.api.DemoService0\"p 6 9 protocol=\"dubbo, grpc\. } X E 4 1"/>

    2、消费端应用 A

    <dubbo:reference protocol=\"d# t k E ; = Y $ Jubbo\" inteD y ?rface=\"org.apache.dubbo.samples.bas& x 2 j :ic.api.DemoService1\"/>3 z ( # N;
    <dubbo:referE ? N j ^ a I dence protococ D 7 W v ( 8l=\"dubbo\" intS Q K u B U 3 _erface=\"org.apache.dubbo.samI _ J X G eples.basic.api.DemoService2\"/>

    <dubbo:reference protocol=\"grpc\" interface=\"org.apache.dubbo.samples.basic.api.DemoService0\"/>

    3、消费端应用C

    <dubbo:referenceq 5 $ y k prb 8 _ Cotocol=\"grpc\" interface=\"org.apache.dubbo.samples.basic.api.DemoService3\"/> <dubbo:reference protocol=\"grpc\" interface=\"org.apache.dubbo.samples.basic.api.DemoService4\"/>

    <dubbo:reference protocol=\"dubbo\" interface=\"org.apacht 1 1 7e.dubbo.samples.bS R T d * n Iasic.api.DemoService0\"/>

    Dubbo 多协议支持现状

    Dubbo 目_ 0 G o c Y前所支持的协议包括 Dubbo、REST、Thrift、gRPC、JsonRPC、Hessian 等,基本涵盖了业界大多数主流的 RPC 通信协议。需要注意的是,这些协议的支持都是以直接集成官方 Release 实现的形式来做的,我认为这是一个很好的选择,既保证了协议解析自身的稳定性,又能使 Dubbo 社区更专注的将更多的精力放在 Dubbo 外围服务治理能力的改善上。试想如果 Dubbo 社区自己为每个协议提供实现,那是要花费多少精力和时间才能使每种协议达到稳定的生产可用。

    除了以上官方提供支持的协议之外,v i 0 , ."beijingRegistry\" address=\"zookeeper://$` j & m : ( ( 0 h{zookeeper.address1}\" default=\"false\"/> &l* x L D Ht;dubbo:registry id=\"shanghaiRegistry\" address=\"zookeeper://$2 v J{zookeeper.address2}\" />

    <dubbo:service interface=\"org.apache.dubbo.sams * O |ples.multi.registry.api.% : THelloService\" ref=\Z x U 8"helloService\" registry=\j ( g H l ? F x a"shanghaiReg| B M & ? O H ] @isi Z : Xtry,beijingRegistry\"/>
    <dubbo:service interface=\"org.apache.dubbo.samples.multi.registry.api.DemoServic2 f ? Xe\" ref=\"demoService\" registry=\"shanghaiRegistry,beijingRe3 q bgistry\"/>

    2、服务消费端,根据消费需求做) 6 A r单/双注册中心订阅

    <dC 8 Y r y R _ - dubbo:registry id=\"bei? F M c  9jingRegistry\" address=\"zoo, z X Kkeeper://${zookeeper.Y Z ,address1}\" default=\"false\" preferredD U =\"true\" weight9 J s a  + S R=\"100\"/> <dubbo:registrO f Y =y id=\"shanghT ! % VaiRegistry\" address=\"zookeeper://${zookeeper.address2}\" default=) 8 {\"true\" weight=\"20\"/>

    <dubbo:reference interface=\"org.apache.dubbo.samples.x 6 M * l NmultiX : a 6 j .registry.api.DemoService\"/>

    <duo X z G v O Zbbo:reference interface= k H\"org.apache.dubbo.samples.multi.registry.api.DemoService\" registY i b . & f 8 , ery=\"beijingRegiv R gstry, shanghaiRegistry\"/>

    <dubbo:reference interface=\"org.apache.dubbm O Do.samples.multi.registry.api.HelloSeP ^ w 5rvicea / !\" registry=\"beijingRegistry\"/>

    <dubbo:reference interface=x / f F\"org.apache.dubbo.samples.multi.registry.api.HelloService\" rr & Q 0 6 P xegist, $ V A R j yry=\"8 ; v 2 & s d ; }shanghaiRegistry,shanghaiRegistry\"/>

    Dubbo 对异l C M C ? f ` 8构注册中心集群的支持

    虽然我们会做多注册中心集群部署,但通常情1 b p R X况下,我们部署的都是相同的注册中心产品,如都是 Zookeeper、Nacos;D C W而对于注册中心迁移的场景,则要求 Dubbo 能提供对更多的注册中心产品的支持,或者最重要的是要有很好的扩展能9 Q = S x v s力。Dubbo 官方目前支持的注册中心实现有:

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

    这里需要9 + u c特别提到的一点是,当前 Dubbo 的服务注册/发现模型是以接口y ; !为粒度的,而从 2.7.5 版本开始,Dubbo 新引入了应用粒度的7 A ? n 4 M c + h服务注册/发现模型。这一方面有助于优化 D^ = fubbo 当前服务发现机制、提升服务容量,另一方面对于联通以 SpringCloj v g ` 9ud 为代表的微服务体系也非常重要(关于这点在下一章中有进一步提及)。更多关于《应用粒度服务发现:服务自省》的介绍,我们将在接下来的文章或文档中予以补充,请持续关注。

    多订阅带来的流量调度问题

    在引入多注册中心集群@ P . y ; 3 u {后,Dubbo 在流量选址时的多了一6 8 - B : | ^ 2 [层注册中心集群间的负载均衡:

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

    在 Cluster Invoker 这一级,我们支持的选址策略有(2.7.5+ 版本,具体使用请参见0 m k H A S ^ 0 1文档):

    1、J Y d O g @ r V指定优* O ) : C M先级

    &l4 2 F xt;!-- 来自 preferred=“true” 注册中心的地址将被优先选择,只有该中心无可用地址时才 Fallback 到其他注册中心 -->
    <dubbo:registry address=\"zookeeper://${zookeeper.ad[ 3 ` , / Q f !dress1}\" preferred=\"true\| [ X k j I v" />

    2、同 zone 优先

    <!-- 选址时会和流量中的 zone key 做匹配,流量会优先派发到相同 zone 的地址 -->
    <dubbo:registry address=\"zookeeper://${zookeeper.address1}\" zone=\"beijing\" />

    3- R } Q V、权重轮选

    <!-- 来c q :自北京和上海集群的地址,将以 10:1 的比例来分配流量 -->
    <dubbo:registry id=\"beijing) m =\" add: 6 {ress=\"zookeeper://${zookeeper.address1}\" weight=”100“ />
    <dubbo:registry id=\"shanghai\" address=\"zookeeper://${zookeeper.( j s V h ! ~address2}\" weight=”10“ />

    4、默认,stick to 任意可用

    多注册中心适用的场景

    • 同m p . V { V & L W区域流量优先调度
      出于容灾或者服务伸o x R B K Z H缩性需求,服务/应用往往需要部署在多个独立的机房/区域,在每个区域有独立注册中x U * X # & u X ,心集群的场景下,实现同区域的流量优先调度就能很好的解决延迟和可用性问题A q L q K。
    • 注册中心迁移
      公司的服务一直以来可能是存储在某一个注册中心,如 Zookeeper,但到了某个时间节 7 h a 8点,A M g _ J i因为各种各样1 9 ~ M /的原因,当我们要迁移到另外的注册中心时,多注册中心模型能0 g m D n h 4 i够保证平滑的迁移。
    • 异构系统互通
      不同微服务体系开发的服务,都封闭在各自的服务发现g D [体系中,而通过统一的多注册中心模型,可以6 { n h U % R Q 3实现不同体系的服务互相发现。

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

    借助 Dubbo 联通异构的微服务体系

    上文我们提到了在组织内存在异构微m { M服务体系的各种合理可能性,现在我们来具体看一h u _ U P ` 8 R r下异构微服务体系的实际场景,以及使用 Dubbo 实 d {图来看一下,联通异构的微服务体系具体是一个什么样的场景。

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

    如上图所示,我们有部分微服务可以是基于 SpringCloud、gRPC、K8S 或者是自建体系构q : G建的,他们各自之间默认是相互隔离无法联通的。当我们再构建一套基于 Dubbo 的微服务Q * P g ~ ~ ? a体系时,则利用 Dubbo 的多协议、多服务发现模型,我们就可以做到和各个微服务体系间的两两之间的互联互通。进一步的,} _ O e o p c如图中橙色箭头所示,依赖 Dubbo 体系作为桥接层,我们还可以实现两个异构微服务 | M P体系间的打通。

    对于以下几个示例场景,由于在地址发现层面目前没有统一的标准,我们暂且假设地址发现层面不同的体系建是没有障碍的,我们将重点关注迁移的基本流程以及通信协Q A ^ * U + x f议环节。(关于地址发现部分,我们将在后续《服务自省:基于应用粒度的服务发现》之后再深入探讨)

    DubG y ? Xbo 体系内的协议R e p @ . N迁移(共存)

    绝大多数开发者对 Dubbo 有这么一个固有认知:使用 Dubbo 开发微服务系统,则就要用 Dubbo 协议来作为服务间的通信协议才是最优方案。实际上F E / t,我们完全没有必要只束缚在 Dubbo RPC 协议上。Dubbo 作为微服务开发框架和 Dub$ & nbo 作为 RPC 协议这是两个概念,其实是完全% + H可以分开来看待的,比如我们用 Dubbo 框架开发的业务系统,选用 rest、gRPCm o ~ ! D g ? 通信是完全没有问题的(参加 Dubbo 支持的协议列表),具体用什么协议根据业务 4 3 #特点和技术规划才是最适合的。

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

    当前在云原生、Mesh 的大背景下, HTTP1/26 k t * x G、gRPC 协议开始受到越来越多的关注,一方面原因自然是因为它们在标准化方面做的更好,得到的更多的网络设备和O I H d v * ~ w基础设施的支持,具备更好的通用性和穿透性。对于很多有云原生迁移意愿的企业来说,往此类协议迁移无疑将对之后的架构升级有更多的帮助。

    下图演示了在 Dubbo 体系内,从 Dubbo 协议向 gRPC 协议迁移的一个中间状态。

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?
    • 最左边的代表尚未迁移的老应用 4 n t 8 ? 9,这类应用在迁移过程中仍+ T M 然要消费和提供 Dubbo 协U | A q议的服务。

    • 中间的代表处于迁移中的应用,他们中间可能有些是服务提O ! i I供者,既要为左边的老系统提供提供 Dubbo 协M / o # y %议服务;又要为右边的新系统提供 gRPC 服务;因此他们都是双协议暴露服务。

    • 最右边则代表是新开发的或者已经迁移完成的应用,这个体系内已能完全用 gRPC 协议通信。

    • 最终度过中间态后,我们期望所有的应用都达到最左边应用的状态,实现完全的 gRPC 协议通信T m E S A : 3。

    Spring Cloud 体系迁移到 Dubbo 体系(共存)

    如前文所述,由于 SpringCloud 和 Dubbo 间服务发现模型的问题,要两个体Y i d 3 x $ / x H系间的地址互通需要 Dubbo 侧作相应的适配,关于这部分内容将在接下来的 2.7.5 版本《服务自省》部分发布,在此我们暂且认为已经打通。

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

    Dubbo 体系内的部分应用} s } $ c V作为透明的联通两个体系的关键节点,部分服务提供者应用要双协议发布、部分消费者应用要做到选定协议消费。由于老的 Spring Cloud 体系不允4 n 8 Y b T {许做任何改动] _ V 6,因此联通两套体系的关键是 REST 协议,对 Dubbo 侧的8 2 )应用t = : , u S z来说:

    • 部分应用可能要以 REST 协议消费 SpringCloud 的服务;

    • 部分应用可能要暴露 REST 协议共 Sprf { S gingCloud 消费;

    • Dubbo 自有体系内则通过自己选定的协议通信,这里就比较灵活了,可以是 Dubbo、REST、gRPC 等其中的任一种。而如果选定 RH Z U jEST 协议则对于与 SpringCloud 体系的联通就变g , Z E : L得更加自然了,因为两端的协议都是统一的。

    对于消费 Spring Clo8 k i 7 . [ wud 服务的应用,要配置服务 :

    <dubbo:reference interface =\P : V % @"xxx.Spr@ O ( XingServiceW D O Q\" protocol=\"rest| K i\"/>

    对于提供服务给 Spring Cloud 侧消费的应用,则指定服务暴露为 rest 协议,或者双协议暴露(因如果这个服务还要被新体系内的应用调用到):: & _ ~

    <dubbo:service interface=\"xxx.NewService\" protocol=\"rest,dubbo\"/>

    作为 Dubbo 的维护者,虽然我们这里有明显的偏向0 d _ } C g # i性w j Z,讲的是从如何从 SpringCloud 体系迁移到 Dubbo 体系。但是反过来考虑,如果你已经或者即将选型 Dubbo 来开发微服务,则未来从 Dubbo 迁移到 SpringCloud 也是同样的思路,Dubbo 的多协议、多注册模型为双向迁移都提供了同样的灵活性。

    自建体系迁移到 Dubbo 体系(共存)

    这个场景和上一节中讲到的的 SpringCloud 迁移有些类似,最大的区别在于 rg d B 2est 协议是 Dubbo 官方默认提供支持A ) p k { 1 s 0的,而对于已有的微服务体系内的私有通信协议,则需要先要自己去扩展 Dubbo Pro5 I 8 0 6 b Ltocol 来提供协议层面的支持,关于 Protocol 如何扩展请参见以下官方文档:

    http://dubbo.apache.org/zhz m R Y ;-cn/docs/dev/impls/protx 2 Jocol.html

    Dubbo 如何成为连接异构微服务体系的最佳服务开发框架?

    总结与展望

    要实现异构微服务体系间的共存或迁移,关键点在打通异构体系间的协议与服务发现,得益于 Dubbo 自身对多协议、多注册模型的支持W u X P D & ),我们可以很容易的使 Dubbo 成为桥接异构微服务体系的中间层。熟悉 Dubbo 多协议实现细节的同学,可能会担心在服务数量较多的场景下,多协议注册会导致地址数量翻倍从而影响地址推送性能。

    另外,在本文“借助 Dubbo 联通异构的微服务体系”一| Q p c 5 l & g节中,关于如何实现异构体系J n e P h q间的透明服务发现部分,我们没有做详T D U ^细的说明。涉及服务发现的这部分,我们将在接下来的文章中做具体阐述,看看 Dubbo 2.7.5 版本引入新的服务发现机制是如何解决这个% O Y问题的,请持续关注后续文章及 Dd Y ` [ ) u u m 7ubbo 官方文档。

    作者:刘军,GitHub账号Chickenlj,Apache Dubbo PMC,项目核心维护者,见证了Dubbo从重启开源到Apache毕业的整个流程。% p ( %现任职阿里云云原生应用平台团队,参与服务框架、微服务相关工作,目前主要在推动Dubbo开源的云原生化。

    本文缩略图:icon by Dora1900

项目企业隔离工作兴国开发体系服务连接