Dubbo to Mesh 云原生架构改造方案解析

Posted CSDN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dubbo to Mesh 云原生架构改造方案解析相关的知识,希望对你有一定的参考价值。

Dubbo to Mesh 云原生架构改造方案解析

作者 | 腾讯云泛互云原生团队
责编 | 屠敏
图 | CSDN 下载自东方 IC
出品 | CSDN(ID:CSDNnews)

Dubbo 是一款高性能的 Java RPC 框架,它除了拥有卓越的 RPC 能力,也同时具有微服务的一些治理能力,如:注册发现,负载均衡等,目前 Dubbo 是国内使用较多的微服务框架之一。

在云原生到来的今天,Service Mesh 的服务治理模式彻底解耦了业务逻辑和控制逻辑,通过 Sidecar 将服务发现,流量控制逻辑下沉到 iPaaS 层面,这种方式逐渐得到大家的关注和青睐。而 Dubbo 在流量治理方面存在一些短板,如灰度发布等目前没有完美的方式实现。

在这种环境下,国内有很多使用 Dubbo 的公司诞生了将 Dubbo 应用迁移到 Service Mesh 中的想法。本文便是对 Dubbo 迁移到 Service Mesh/Istio 的探讨。


Dubbo to Mesh 云原生架构改造方案解析

Dubbo to Mesh 改造难点


在 Dubbo 应用向 Service Mesh 应用改造的过程中,可能会遇到以下这些难点:

  • 服务名调用问题Istio 通过对 K8S 服务名调用的拦截,实现了无侵入式的流量治理功能,因此 Isito 要求不同服务间的调用必须以服务名的方式进行。现有项目是否为服务名调用,成了不同类型的项目向 Istio 改造的最大障碍之一,例如 Dubbo 项目就不是服务名调用,而是 Interface 调用,这是第一个痛点问题。

  • 注册中心问题由于 Istio 目前只支持 K8S etcd、Consul 两种服务注册中心,其他注册中心(例如:Zookeeper)的对接以及跟 Istio 配置文件的集成及 xDS 协议数据的下发,成为了第二个痛点问题。

  • 私有协议问题由于当前 Istio 目前只支持 http、gRPC、tcp 三种协议,私有协议适配难度较高,即使在新版 Envoy 已经支持了 Dubbo 协议的情况下,还是需要通过 EnvoyFilter 下发专属 xDS 协议数据来支持 Dubbo 的服务调用及流量治理,这是第三个痛点问题。

 

Dubbo to Mesh 云原生架构改造方案解析

Dubbo to Mesh 云原生架构改造方案


相比于自研 sidecar 或修改 Dubbo SDK 等重度方式,本文从不同的角度尝试两种改造方案:

  • 方案1:Dubbo to Mesh 轻量化改造方案该方案基于 Dubbo 本身提供的直连功能,通过修改 dubbo provider / consumer 配置文件,禁止 dubbo 的注册发现功能,通过配置 provider url 实现基于服务名发送请求。由于 Istio 1.5+ 版已提供了 dubbo 协议的支持,因而数据面 envoy 可对 dubbo 流量进行治理。

  • 方案2:使用 SpringBoot 重构 Dubbo 的改造方案该方案抛弃 Dubbo 框架,直接使用 SpringBoot 进行重构。脱离了框架的限制,项目代码更轻量,同时更自然的拥抱云原生。 

方案 1:Dubbo to Mesh 轻量化改造方案

1.1 改造思路

利用 Dubbo 本身的能力,修改配置文件以禁用 Dubbo 本身的注册发现,并通过指定服务名调用 Dubbo 服务。使用这种方法可以将Dubbo 应用快速部署到 Istio 集群中,不改变通信协议,并实现基于服务名的流量控制。本方案在 Istio 1.5+ 中实验通过。

Dubbo to Mesh 云原生架构改造方案解析

1.2 改造步骤:

  • Step 1. 改造 provider

禁用 registry,不订阅,不注册,也不进行检查。如下修改程序配置:

<beans> <dubbo:application name="hello-dubbo-provider"/> <dubbo:protocol name="dubbo" port="20880" /> <dubbo:registry register="false" subscribe="false" check="false" address="none" /> <bean id="demoService" class="tencent.demo.provider.DemoServiceImpl"/> <dubbo:service interface="tencent.demo.DemoService" ref="demoService" /></beans>

现在无需部署 zk (或其他注册服务),这个应用可以直接启动。

  • Step 2. 改造 consumer
<beans> <dubbo:application name="demo-consumer"/> <dubbo:registry address="none" register="false" subscribe="false" check="false" /> <dubbo:reference id="demoService" check="false" interface="tencent.demo.DemoService" url="dubbo://hello-dubbo-provider:20880" /></beans>
java -Dtencent.demo.DemoService=dubbo://hello-dubbo-provider:20880 ...
java -Ddubbo.resolve.file=services.properties ...

在 services.properties 中可指定多个服务:

tencent.demo.DemoService=dubbo://hello-dubbo-provider:20880tencent.demo.DemoService2=dubbo://hello-dubbo-provider:20880tencent.demo.DemoService3=dubbo://hello-dubbo-provider3:20880

本地调试一下,在 hosts 中映射一下。 

127.0.0.1 hello-dubbo-provider

现在启动 consumer,不出意外,完美运行。

现在我们可以通过 yaml 的部署,轻松将应用部署到 Istio 集群中。本方案在 Isito 1.5.6 和 1.6.1 中实验通过。 详细的实验过程可以参考 腾讯云“云+社区”的文章《Dubbo to Istio / Dubbo Mesh 极简改造指南》。

1.3 方案总结

通过简单的两处的修改,我们便实现禁用 Dubbo本身的注册发现,并交由 Istio 来管理。 通过 Dubbo 本身的能力,修改配置文件和依赖包,我们还可以将 Dubbo 应用的通信方式修改为 http。

实验证明:不改造 dubbo 框架和业务逻辑的情况下(只改配置文件和依赖包),可以实现 如下目标:1 基于 TCP 的流量操控,可以根据 Service 来控制流量。2 基于 HTTP 的流量操控,可以控制到 Service 和 interfaceName(Dubbo 中 interfaceName 是写在 url 里面的,可以通过 uri 匹配规则进行流量操控)。

在调用链追踪方面, Dubbo 本身并没有 OpenTracing,在不修改 Dubbo SDK 的情况下,仍需要使用 Dubbo 原来的方式来实现。

方案 2:使用 SpringBoot 重构 Dubbo 的改造方案

2.1 改造思路:

此方案充分利用 Dubbo 项目原有的代码结构,删除Dubbo原有的注册发现、Dubbo协议、Dubbo服务配置等功能,将一个 Dubbo 项目改造成一个 SpringBoot + K8S + Istio 的项目,代码修改范围可控,改造方式最彻底。

Dubbo to Mesh 云原生架构改造方案解析

  • 由于改造 Dubbo SDK、Isito控制面、Envoy 数据面,让 Dubbo 去适配 Service Mesh 的技术难度较大,而且即使改造成功也需要通过 EnvoyFilter 下发专属 xDS 协议数据的形式来支持 Dubbo 服务间调用的流量治理,使得这种方式与原生 Istio 的使用方式差距较大。

  • 所以我们选择了一条将 Dubbo 项目改造成 SpringBoot + K8S + Istio 项目的更简单的路,充分利用现有 Dubbo 项目的代码结构,将代码修改量降到一个可控的范围内。

  • 由于 Dubbo 项目 facade 模块的作用与 Spring Cloud Feign 模块的作用十分相似(模块内都是一些 interface,需要服务端 xxxServiceImpl 去实现各个 interface,消费端通过 @Resource 注解的方式引入 interface 并直接调用),使得 Dubbo 最复杂的服务间调用方式有了解决的方案。

  • 此次改造只是利用了 Dubbo 项目的代码结构,Dubbo 原有的注册中心、Dubbo 协议等功能全部都会被去掉,也就是改造后的项目跟 Dubbo 已经没有任何关系了,所以注册中心、Dubbo私有协议这两个痛点问题也就不存在了。

  • K8S 会接管服务注册发现、服务编排等工作,Istio 会接管服务治理、调用链监控、服务安全等工作,改造后的项目是一个标准的 Service Mesh 项目。

2.2 改造步骤:

Step 1. 依赖修改
  • 在根 pom.xml 中引入 SpringBoot parent,增加 spring-cloud-dependencies import 引用。

  • 删除所有 dubbo 相关引用。

  • 虽然 pom 文件改动很大,但属于一次性改动,改造工作量较小。

Step 2. dubbo-facade 项目改造
  • pom.xml 增加 spring-cloud-starter-openfeign 引用。
  • 删除所有 Dubbo 相关引用、Dubbo 相关配置文件。

  • Dubbo 原有 facade 接口是标准的 JAVA 接口定义,与 Feign Restful 接口定义十分类似。这里可以在原有的 facade 接口基础上增加 @FeignClient、@RequestMapping 等注解,将一个普通的 facade 接口改造成一个 Feign Restful 接口,后续会使用 Feign 这个 Restful 框架来处理服务间调用等问题。

  • 此部分整体改造工作量取决于原有的 Dubbo 项目包含多少个 facade 接口,以及每个 facade 包含多少个抽象方法。

Step 3. dubbo-provider 项目改造
  • pom.xml 增加 spring-boot-starter-web、spring-cloud-starter-openfeign 等引用,同时增加 SpringBoot mainClass 标准启动项配置。

  • 删除所有 Dubbo 相关引用、Dubbo 相关配置文件。

  • 增加 SpringBoot 启动类,增加 @SpringBootApplication、@EnableFeignClients 两个注解,配置 dubbo-provider 服务端口号。

  • xxxServiceImpl 服务实现类上增加 @RestController 注解,提供 consumer Restful 访问的能力。这个需要每个服务实现类都加上 @RestController 注解,不要遗漏。

  • 此部分大都属于一次性改动,改造工作量相对可控。

Step 4. dubbo-consumer 项目改造
  • pom.xml 增加 spring-boot-starter-web、spring-cloud-starter-openfeign 等引用,同时增加 SpringBoot mainClass 标准启动项配置。

  • 删除所有 Dubbo 相关引用、Dubbo 相关配置文件。

  • 增加 SpringBoot 启动类,增加 @SpringBootApplication、@EnableFeignClients(需要配置 basePackages 扫描包路径) 两个注解,并配置 dubbo-consumer 服务端口号。

  • 此部分大都属于一次性改动,改造工作量相对可控。

Step 5. 将改造后的项目部署到 K8S + Istio
  • 创建 dubbo-provider K8S Deployment、K8S Service(ClusterIP),提供集群内访问服务。

  • 创建 dubbo-consumer K8S Deployment、K8S Service(ClusterIP),提供集群内访问服务。

  • 创建 istio ingressgateway、VirtualService,提供公网访问入口,并进行流量治理测试。

经过上面几步操作,我们成功的将一个 Dubbo 项目改造成了一个 Service Mesh 项目,并在 K8S + Istio 集群中部署成功、测试通过。

详细的实验过程可以参考 腾讯云“云+社区”的文章《如何将一个 Dubbo 项目改造成一个 Service Mesh 项目?》:https://cloud.tencent.com/developer/article/1635721。

2.3 Dubbo to Mesh 改造过程中的迁移态方案

  • 在 service mesh 和未做 mesh 化改造的 dubbo 服务之间,添加 MeshGate 业务网关。

  • 业务网关会在 dubbo 注册中心进行注册和订阅,向 mesh 外提供 dubbo-rpc 调用服务,向 mesh 内提供 http/rest 接口服务。

Dubbo to Mesh 云原生架构改造方案解析

2.4 方案总结

当然,真实业务系统中的架构复杂度是远高于这个 Demo 的,实际改造的工作量要比改造这个 Demo 大得多。但笔者以为:Dubbo 的服务治理功能和 Istio 是重复的,并且随着云原生的 Java 框架兴起,以及 Spring 对云原生/Native 的支持,最终的 Dubbo 迁移到 Mesh 的改造都会走到这个路径。

 

Dubbo to Mesh 云原生架构改造方案解析

两种改造方案的适用场景及优缺点


最后总结一下本文中两种方案各自的适用场景及优缺点:

Dubbo to Mesh 云原生架构改造方案解析

作者简介:腾讯云泛互云原生团队基于腾讯云的技术和产品能力,致力于帮助企业客户推广及落地微服务、容器、服务网格、大数据、DevOps、AI等技术产品,有效提升客户的研发及运维效率。目前服务的客户主要有:快手、知乎、KEEP、小红书、微盟等。

Dubbo to Mesh 云原生架构改造方案解析
Dubbo to Mesh 云原生架构改造方案解析
   
     
     
   
更多精彩推荐
    
      
      
    
TensorFlow 2.0 发布以来,又有哪些最新进展?| AI ProCon 2020
Dubbo to Mesh 云原生架构改造方案解析
点分享
点点赞
点在看

以上是关于Dubbo to Mesh 云原生架构改造方案解析的主要内容,如果未能解决你的问题,请参考以下文章

云原生微服务架构SpringCloud和Dubbo的区别?

企业应用架构演化探讨:从微服务到Service Mesh

云原生改造之后,作业帮又把发力点放到了无边界云计算

Dubbo架构设计与源码解析 架构设计

云原生网络性能优化:service mesh篇

第八章 跨语言服务治理方案 Service Mesh