如何将应用从HSF迁移到Dubbo3

本文介绍在EDAS上如何将应用从HSF迁移到Dubbo3。参考本文档,您可以在EDAS中将使用HSF构建的微服务系统逐步迁移至Dubbo3架构。迁移期间,您的服务无需整体停机。

背景信息

Dubbo3是流行的开源Java微服务框架,具备更丰富的服务治理能力和更好的社区支持。EDAS同时支持HSF和Dubbo3应用,并建议HSF用户迁移至Dubbo3。

名词解释

  • HSF2应用:使用HSF注解或XML方式声明服务提供者或服务消费者,并使用EDAS容器3.x部署的应用。

  • HSF3应用:使用HSF注解或XML方式声明服务提供者或消费者,并使用EDAS容器5.x及以上版本部署的应用(EDAS容器4.x也是HSF3,但不支持双注册、双发现)。

  • Dubbo3应用:使用Dubbo方式声明服务提供者或消费者,只依赖于开源的Dubbo3。

  • Config Server:EDAS中HSF应用使用的注册中心。

使用说明

HSF3(EDAS容器5.x)同时使用Config Server、Nacos作为服务注册中心,支持服务同时被注册到Config Server和Nacos。此外,HSF3提供HSF协议和Dubbo协议的服务端口。HSF2应用无需改造,直接使用HSF3容器部署后,应用便可实现同时与HSF2、Dubbo3应用的互相通讯,实现平滑迁移。

原理

迁移流程图

如图所示,整体迁移过程历经三个阶段。

  1. 原始状态:全部为HSF2应用,服务注册中心使用Config Server。

  2. 迁移状态:应用处于混合部署阶段,分为如下子过程:

    1. HSF2应用+HSF3应用:使用HSF3部署部分应用,此时,HSF2、HSF3应用同时使用Config Server作为注册中心,可互相发现,互相调用服务。具体操作,请参见步骤一:升级应用运行环境

    2. 全量HSF3应用:使用HSF3重新部署所有应用后,此时,系统中已无HSF2应用。

    3. HSF3应用+Dubbo3应用:为HSF3应用开启服务双注册、服务双发现,同时使用Dubbo3方式声明服务并部署应用实例。具体操作,请参见步骤二:创建应用。此时,HSF3、Dubbo3应用可互相发现、互相调用服务。

  3. 最终状态:所有HSF应用迁移至Dubbo3。

迁移步骤

步骤一:升级应用运行环境

说明

该步骤无需修改应用程序代码。

  • 对于在EDAS部署的ECS应用,通过运行时环境升降级功能,将Pandora版本升级到5.X。运行环境升降级

  • 对于在EDAS使用WAR、JAR包部署的K8s应用,可通过部署,将应用运行环境升级到EDAS-Container 5.X的版本。K8s环境升级

  • 对于在EDAS使用镜像部署的K8s应用,可重新构建镜像,将镜像版本升级到5.0.0。在HSF应用的Dockerfile文件中增加如下配置,将HSF应用的运行环境EDAS-Container(Pandora)的版本升级为5.0.0。HSF应用的Dockerfile文件,请参见HSF应用的Dockerfile示例

    # 在WORKDIR/home/admin后增加升级脚本如下
    # 设置EDAS-Container/Pandora应用容器版本
    ENV UPGRADED_CONTAINER_VERSION 5.0.0
    RUN /home/admin/bin/upgradecontainer.sh

修改应用启动参数或修改应用配置,完成部署。具体操作,请参见HSF3应用配置服务双注册、双发布

步骤二:创建应用

说明

该步骤需要修改应用程序代码,请参见Dubbo3应用配置样例,完成配置,并构建出部署包。

使用新的部署包,在EDAS中相同微服务空间下创建Java应用。

  • ECS应用:创建ECS应用

  • K8s应用:创建K8s应用

配置参考

HSF3应用配置服务双注册、双发布

配置要求和方法

  1. 使用EDAS容器5.x部署。

  2. 启动双发布、双发现。

    • 方法一:通过JVM参数-Ddubbo.config.hsf.exportNativeDubbo=true启用双发布,-Ddubbo.config.hsf.referNativeDubbo=true启用双发现。

    • 方法二:在dubbo.properties文件中,指定dubbo.config.hsf.exportNativeDubbo=true启用双发布,指定dubbo.config.hsf.referNativeDubbo=true启用双发现。

HSF3应用会默认发布、发现HSF服务。启用上述配置后,应用将服务注册到Nacos,并发布Dubbo服务,同时通过Nacos发现服务,调用Dubbo服务。启用双发布、双发现后,HSF3应用可以使用Nacos作为注册中心,使用Triple协议作为通讯协议,提供Dubbo服务。

双发现的路由策略

  • 按照Provider数量均衡调用。例如,当有1个HSF服务节点,3个Dubbo节点(一个HSF3节点启用双发布后,同时作为HSF服务节点和Dubbo服务节点)时,HSF服务节点被调用的概率为1/4,Dubbo服务节点的调用概率为3/4。

  • 若任一种类型的节点不可用,则调用可用类型的节点。

  • 若两种类型的节点都不可用,则默认调用HSF类型节点。

Dubbo3应用配置样例

应用必须声明对dubbo-registry-nacos、dubbo-rpc-triple的依赖,建议使用3.0.5~3.0.12之间版本。

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-registry-nacos</artifactId>
    <version>${dubbo.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-rpc-triple</artifactId>
    <version>${dubbo.version}</version>
</dependency>

对于nacos-client版本依赖要求,仅能使用2.0.3或2.1.2及以上版本。2.0.4~2.1.1的版本存在不支持EDAS共享注册中心或MSE注册中心的问题。

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>2.1.2</version>
</dependency>

Dubbo声明配置要求

HSF3仅支持服务级服务发布、发现。所以需要Dubbo侧设置强制使用服务发现模式,设置方法如下:

  • 方法一:声明JVM参数:-Ddubbo.application.service-discovery.migration=FORCE_INTERFACE

  • 方法二:在dubbo.properties中配置dubbo.application.service-discovery.migration=FORCE_INTERFACE

    spring boot yaml配置格式示例如下:

    重要

    特别注意,需要声明使用Triple协议。

    dubbo:
      application:
          name: ....
        protocol:
          # 必须声明该配置,因为HSF3使用Triple协议发布服务
        name: tri
        port: -1
      # 声明使用Nacos注册、配置中心(EDAS上部署后,将被自动替换)
      registry:
        id: nacos-registry
        address: nacos://127.0.0.1:8848
      config-center:
        address: nacos://127.0.0.1:8848
      metadata-report:
        address: nacos://127.0.0.1:8848

    xml配置格式示例如下:

    <dubbo:metadata-report address="nacos://127.0.0.1:8848"/>
    <dubbo:registry address="nacos://127.0.0.1:8848"/>
    <dubbo:config-center address="nacos://127.0.0.1:8848"/>
    <dubbo:protocol id="tri" name="tri" />

参考DEMO

下载Demo

说明

该Demo包含如下工程模块:

流程图

如上图所示,提供了4组Demo工程,其中第一组Demo采用HSF2容器、HSF3容器部署。

服务提供者

服务消费者

itemcenter-hsf

HSF方式声明服务的服务提供者。

detail-hsf

  • HSF方式声明服务的服务消费者。

  • 使用HSF2容器部署。

  • 仅能调用到HSF服务。

itemcenter-hsf

  • HSF方式声明服务的服务提供者(WAR包)。

  • 使用HSF3容器部署。

  • 能同时提供HSF、Dubbo服务。

detail-hsf

  • HSF方式声明服务的服务消费者(WAR包)。

  • 使用HSF3容器部署。

  • 能同时调用到HSF、Dubbo服务。

itemcenter-hsf-pandora-boot

  • HSF方式声明服务的服务提供者(JAR包)。

  • 使用HSF3容器部署。

  • 同时提供HSF、Dubbo服务。

detail-hsf-pandora-boot

  • HSF方式发布消费服务(JAR包)。

  • 使用HSF3容器部署。

  • 能同时调用到HSF、Dubbo服务。

itemcenter-dubbo

  • 原生Dubbo方式(WAR包)声明服务的服务提供者。

  • 无需依赖EDAS容器,使用apache-tomcat部署即可。

  • 提供Dubbo服务。

detail-dubbo

  • 原生Dubbo方式(WAR包)声明服务的服务消费者。

  • 无需依赖EDAS容器,使用apache-tomcat部署即可。

  • 调用Dubbo服务。

itemcenter-dubbo-spring-boot

  • 原生Dubbo方式(JAR包)声明服务的服务提供者。

  • 无需依赖EDAS容器。

  • 提供Dubbo服务。

detail-dubbo-spring-boot

  • 原生Dubbo方式(JAR包)声明服务的服务消费者。

  • 无需依赖EDAS容器。

  • 调用Dubbo服务。

可以根据自己的需要,选择相应的Demo分组部署实验。部署后,可进入任一Consumer执行如下命令。

curl 'http://127.0.0.1:8080/index.htm?name=abc'

返回信息如下:

# 第x次调用
Item Id: 1, Name: Protocol=HSF,LocalIP=172.17.48.116,Name=default,Date=2022-11-22 19:45:19:372,TraceId=ac11303616691175193702012d003f
# 第x+1次调用
Item Id: 1, Name: Protocol=TRI,LocalIP=172.17.48.116,Name=default,Date=2022-11-22 19:45:15:741,TraceId=ac11303616691175157392011d003f

返回说明:

  • Protocol:服务提供者使用的处理协议。其中,HSF表示HSF协议,TRI表示Triple协议。

  • LocalIP:服务提供者的IP地址。

FAQ

HSF3应用如何使用MSE Nacos实例作为Dubbo服务注册中心

如果您继续使用EDAS共享注册中心,则无需执行以下操作。

  1. MSE管理控制台创建实例,并添加命名空间。具体操作,请参见创建MSE实例创建命名空间

  2. 在应用Maven源码的resources目录下,添加dubbo.properties文件,在dubbo.properties文件中,添加以下内容,并构建应用包。

    dubbo.config.hsf.nativeDubbo.registry=nacos://mse-xxxx-nacos-ans.mse.aliyuncs.com:8848?namespace=msenamespace01
    • mse-xxxx-nacos-ans.mse.aliyuncs.com:实例的地址。

    • msenamespace01:创建的命名空间ID。

  3. 使用程序配置注册中心。

    • 方法一:添加JVM启动参数-Dnacos.use.endpoint.parsing.rule=false -Dnacos.use.cloud.namespace.parsing=false

    • 方法二:如下图,部署应用时,在应用高级设置页面,展开微服务治理,勾选使用程序配置的注册中心(即不使用EDAS提供Nacos的注册中心)微服务治理

  4. 部署应用后进入MSE引擎实例,查看服务列表是否包含您的服务。

如何查看应用是否正常启动?

  • 对于Spring-boot+K8s应用,一般查看K8s标准输出。

  • 对于Tomcat或EDAS容器部署的应用,一般查看tomcat目录/logs/localhost.log.xxx 文件。

如何查看服务是否注册到Nacos?

执行grep REGISTER-SERVICE ~/logs/nacos/naming.log | grep 服务名 命令。若存在,如图所示:

服务注册到Nacos

查看服务是否通过Nacos正常发现?

执行命令find ~/nacos/naming -name "*服务名*" ,文件内容部分格式化后如下所示。

{
  "name": "providers:com.alibaba.edas.carshop.itemcenter.ItemService:1.0.0:HSF",
  "groupName": "DEFAULT_GROUP",
  "clusters": "",
  "cacheMillis": 10000,
  "hosts": [
    {
      "instanceId": "172.17.XX.XX#50051#null#DEFAULT_GROUP@@providers:com.alibaba.edas.carshop.itemcenter.ItemService:1.0.0:HSF",
      "ip": "172.17.XX.XX",
      "port": 50051,
      "weight": 1.0,
      "healthy": true,
      "enabled": true,
      "ephemeral": true,
      "clusterName": "DEFAULT",
      "serviceName": "DEFAULT_GROUP@@providers:com.alibaba.edas.carshop.itemcenter.ItemService:1.0.0:HSF",
      "metadata": {
        "release": "3.0.12",
        "methods": "getItemByName,getItemById,getItemByIdAndName",
        "deprecated": "false",
        "dubbo": "2.0.2",
        "pid": "1",
  • com.alibaba.edas.carshop.itemcenter.ItemService:服务名。

  • 1.0.0:版本号。

  • HSF:分组名。

  • hosts:服务提供者。

  • 172.17.XX.XX:服务提供者IP及服务端口。

服务名称、版本号和分组名尤为关键,是服务的唯一标识。若其中一项与Provider注册不一致,则Consumer无法找到服务。若不存在,执行cat ~/logs/nacos/naming.log | grep ItemService命令,查看日志是否触发订阅。