当前位置: 首页 > 图灵资讯 > 技术篇> Spring Boot集成Dubbo 3.X

Spring Boot集成Dubbo 3.X

来源:图灵教育
时间:2023-07-04 10:08:13

今天,我们将学习如何使用Dubo,并将Dubo集成到Spring中 在Boot项目中。让我们来看看今天要使用的软件和版本:

软件版本说明Java11Spring Boot2.7.13  Spring Boot 从3.0版本开始,最低支持到Java 17Dubbo 3.2.2 Zookeeper 3.8.1 注册中心是Dubbo选择注册中心没有强制性要求,本文以Zookeeper为例进行演示。

TIps:我们今天只处理Spring Boot,Dubo和Zookeeper的集成不涉及其他框架的集成。

Zookeeper部署

让我们先部署一个Zookeper。在这里,我提供Windows和Linux的部署教程。如果部署成功,可以跳过这部分。

首先是下载Zookeeper,在这里我们选择Zookeeper-3.8.1版本。

Spring Boot集成Dubbo 3.X_JAVA

Linux可以使用wget命令下载:

wget https://archive.apache.org/dist/zookeeper/zookeeper-3.8.1/apache-zookeeper-3.8.1-bin.tar.gz

Tips:请注意,我们在这里下载apache-zookeeper-3.8.1-bin.tar.gz这个文件。

Linux部署Zookeperer

解压Zookeper:

tar -zxvf apache-zookeeper-3.8.1-bin.tar.gz

Zookeeper配置文件,配置文件位于../Zookeeper/conf目录下,复制zoo_sample.cfg文件命名为zoooo.cfg:

cp zoo_sample.cfg zoo.cfg

在Dubo的学习中,我们可以使用Zookeper的默认配置,所以我们不需要在这里修改zooo.cfg。

修改profile文件:

vim /etc/profile

将Zookeper的配置添加到profile文件中:

export ZOOKEEPER_HOME=/opt/opt/apache-zookeeper-3.8.1-binexport PATH=$ZOOKEEPER_HOME/bin:$PATHexport PATH

刷新profile文件:

source profile

启动Zookeperper启动:

zkServer.sh start

一般情况下会输出日志:

ZooKeeper JMX enabled by defaultUsing config: /opt/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfgStarting zookeeper ... STARTED

使用命令查看Zookeeper的状态:

 

zkServer.sh status

单机状态输出如下日志:

ZooKeeper JMX enabled by defaultUsing config: /opt/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfgClient port found: 2181. Client address: localhost. Client SSL: false.Mode: standalone

在这里,我们成功地在Linux服务器上部署了一个简单可用的单机版Zookeeper。

Windows部署Zookeperer

参照Linux上部署Zookeper的步骤来修改配置文件。在Windows上,我们需要修改datadir的路径,并添加datalogdir的路径:

 

tickTime=2000initlimit=10synclimit=5datadirt==D:\\Apache\\Apache Zookeeper 3.8.1\\datadataLogDir=D:\\Apache\\Apache Zookeeper 3.8.1\\logsclientPort=2181

 

如果系统中没有环境变量JAVA_HOME,我们需要修改zkenvv.位于cmd中的JAVA_HOME配置../Apache Zookeeper/bin目录下:

 

@echo offREM Licensed to the Apache Software Foundation (ASF) under one or moreREM contributor license agreements.  See the NOTICE file distributed withREM this work for additional information regarding copyright ownership.REM The ASF licenses this file to You under the Apache License, Version 2.0REM (the "License"); you may not use this file except in compliance withREM the License.  You may obtain a copy of the License atREMREM     http://www.apache.org/licenses/LICENSE-2.0REMREM Unless required by applicable law or agreed to in writing, softwareREM distributed under the License is distributed on an "AS IS" BASIS,REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.REM See the License for the specific language governing permissions andREM limitations under the License.set ZOOCFGDIR=%~dp0%..\confset ZOO_LOG_DIR=%~dp0%..\logsREM for sanity sake assume Java 1.6REM see: http://java.sun.com/javase/6/docs/technotes/tools/windows/java.htmlREM add the zoocfg dir to classpathset CLASSPATH=%ZOOCFGDIR%REM make it work in the releaseSET CLASSPATH=%~dp0..\*;%~dp0..\lib\*;%CLASSPATH%REM make it work for developersSET CLASSPATH=%~dp0..\build\classes;%~dp0..\build\lib\*;%CLASSPATH%set ZOOCFG=%ZOOCFGDIR%\zoo.cfg@REM setup java environment variablesif not defined JAVA_HOME (  echo Error: JAVA_HOME is not set.  goto :eof)set JAVA_HOME=%JAVA_HOME%if not exist "%JAVA_HOME%"\bin\java.exe (  echo Error: JAVA_HOME is incorrectly set: %JAVA_HOME%  echo Expected to find java.exe here: %JAVA_HOME%\bin\java.exe  goto :eof)REM strip off trailing \ from JAVA_HOME or java does not startif "%JAVA_HOME:~-1%" EQU "\" set "JAVA_HOME=%JAVA_HOME:~0,-1%" set JAVA="%JAVA_HOME%"\bin\java

我们将第41行set JAVA_HOME=%JAVA_HOME%在提前到第36行之前,在判断环境变量中是否存在JAVA_HOME之前设置,并使用完整的路径,如:set JAVA_HOME=D:\Java\jdk11.0.18

修改上述内容后,直接双击执行zkserverer.cmd可以启动Zokeper。请注意,在Windows下启动可能会出现各种错误,最常见的是启动闪回,然后在Powershell中启动zkserver.cmd,查看解决问题的日志:

cd D:PS D:\> cd '.\Apache\Apache Zookeeper 3.8.1\bin\'PS D:\Apache\Apache Zookeeper 3.8.1\bin> .\zkServer.cmd

好了,在这里你应该已经完成了Zookeeper的部署,接下来我们在Spring Dubbo集成在Boot应用中。

XML形式集成Dubo的XML

首先,我们准备了DuboproviderXML和DuboproDubboConsumerXML,我们直接跳过了模仿服务提供商和服务用户创建项目的部分。我相信每个人在这一步都没有问题。

此外,Dubbo正式提供Dubo Initializer项目脚手架,方便大家快速构建Dubo项目:

Spring Boot集成Dubbo 3.X_JAVA_02

类似于Spring的使用方法 Initializr:

Spring Boot集成Dubbo 3.X_SpringBoot_03

Tips:

  • 当然,您也可以在同一项目中模拟供应商和用户;
  • Spring 严格来说,Initializr是一个错别字,但大家都接受了这种方式,V2EX上有关于名字的讨论。
DuboproviderXML工程

在DubboproviderXML项目下创建了两个子项目:

  • provider-api,声明RPC接口
  • provider-service,实现核心业务逻辑

工程结构如下:

Spring Boot集成Dubbo 3.X_Dubbo_04

现修改DubboProviderXML工程POM文件:

<modelVersion>4.0.0</modelVersion><groupId>com.wyz</groupId><artifactId>DubboProviderXML</artifactId><version>0.0.1-SNAPSHOT</version><packaging>pom</packaging><name>DubboProviderXML</name><description>DubboProviderXML</description><properties>    <maven.compiler.source>11</maven.compiler.source>    <maven.compiler.target>11</maven.compiler.target>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><modules>    <module>provider-api</module>    <module>provider-service</module></modules>

一般情况下,我会在DubboProviderXML项目中添加所有子项目都会使用的依赖,例如:lombok,commons-lang3等,在这里我们忽略了这一部分。

provider-api

然后在provider-api中处理POM文件:

<modelVersion>4.0.0</modelVersion><parent>    <groupId>com.wyz</groupId>    <artifactId>DubboProviderXML</artifactId>    <version>0.0.1-SNAPSHOT</version></parent><artifactId>provider-api</artifactId><version>0.0.1-SNAPSHOT</version><name>provider-api</name><packaging>jar</packaging><description>provider-api</description>

然后在providerapi中声明RPC接口:

package com.wyz.api;/** * @author wyz * @version 1.0 * @date 2023/6/28 */public interface DubboDemoXMLService {    String say(String message);}

这样,provider-api就完成了配置,dubboproviderXML就有了为外界提供RPC服务的入口。

Tips:将provider-api打包成jar,以便DubboconsumerXML使用。

provider配置-service

下面我们配置子工程provider-servicePOM文件:

<modelVersion>4.0.0</modelVersion><parent>    <groupId>com.wyz</groupId>    <artifactId>DubboProviderXML</artifactId>    <version>0.0.1-SNAPSHOT</version></parent><artifactId>provider-service</artifactId><version>0.0.1-SNAPSHOT</version><name>provider-service</name><description>provider-service</description><properties>    <spring.boot.version>2.7.13</spring.boot.version>    <dubbo.version>3.2.2</dubbo.version>    <zookeeper.version>3.8.1</zookeeper.version></properties><dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter</artifactId>        <version>${spring.boot.version}</version>    </dependency>      <!-- dubbo-spring-boot-starter引入dubobo -->    <dependency>        <groupId>org.apache.dubbo</groupId>        <artifactId>dubbo-spring-boot-starter</artifactId>        <version>${dubbo.version}</version>    </dependency>      <!-- DUbo与Zookeeper的连接器 -->    <!-- curator5本身引入了Zookeeper的依赖,所以不需要额外介绍 -->    <dependency>        <groupId>org.apache.dubbo</groupId>        <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>        <version>${dubbo.version}</version>        <type>pom</type>    </dependency>        <dependency>        <groupId>com.wyz</groupId>        <artifactId>provider-api</artifactId>        <version>0.0.1-SNAPSHOT</version>    </dependency></dependencies>

接下来,我们将在provider-service中实现这个接口:

package com.wyz.service.impl;import com.wyz.DubboDemoXMLService;/** * @author wyz * @version 1.0 * @date 2023/7/3 */public class DubboDemoXMLServiceImpl implements DubboDemoXMLService {    @Override    public String say(String message) {        return "XML Provider say : " + message;    }}

现在,我们有了界面,也有了界面的实现,只需要配置Dubbo服务,新的Dubbo-provider.xml文件:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">    <!-- 基本配置Dubbo-->    <dubbo:application name="DubboProviderXML" qos-port="2222"/>    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>    <dubbo:protocol name="dubbo"/>    <!-- dubodemoxmlserviceimpl配置提供服务 -->    <bean id="dubboDemoXMLServiceImpl" class="com.wyz.service.impl.DubboDemoXMLServiceImpl"/>    <dubbo:service interface="com.wyz.api.DubboDemoXMLService" ref="dubboDemoXMLServiceImpl"/></beans>

所有配置完成后,我们导入dubo-provider.xml文件:

package com.wyz.service;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;/** * @author wyz * @version 1.0 * @date 2023/7/3 */@SpringBootApplication@ImportResource(locations = "classpath:dubbo-provider.xml")public class ProviderServiceApplication {    public static void main(String[] args) {        SpringApplication.run(ProviderServiceApplication.class, args);    }}

此时,我们的DubboProviderXML工程已经配置完毕,工程结构如下:

Spring Boot集成Dubbo 3.X_SpringBoot_05

DuboconsumerXML工程

我们继续配置服务用户DuboconsumerXML项目。整个过程与DuboproviderXML的配置基本相同。我们直接进入consumer-service的配置部分。

consumer配置-service

consumer-service的POM文件与dubboproviderXML工程的子工程provider-service完全一致,我们也直接跳过了这部分。

接下来实现对DubboDemoXMLService#say的调用:

package com.wyz.service.impl;import com.wyz.DubboDemoXMLService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;/** * @author wyz * @version 1.0 * @date 2023/7/3 */@Componentpublic class DubboConsumerXMLService implements CommandLineRunner {    @Autowired    DubboDemoXMLService dubboDemoXMLServiceImpl;    @Override    public void run(String... args) {        String message = dubboDemoXMLServiceImpl.say("wyz");        System.out.println(message);    }}

然后我们增加了dubbo-consumer.xml文件,配置用户要调用的服务:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">    <!-- 基本配置Dubbo-->    <dubbo:application name="DubboConsumerXML" qos-port="2223"/>    <dubbo:registry address="zookeeper://106.75.33.232:2181"/>    <dubbo:protocol name="dubbo"/>      <!-- 配置需要调用的服务 -->    <dubbo:reference id="DubboDemoXMLService" interface="com.wyz.api.DubboDemoXMLService"/></beans>

同样,我们导入dubo-consumer.xml文件:

package com.wyz.service;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;/** * @author wyz * @version 1.0 * @date 2023/7/3 */@SpringBootApplication@ImportResource(locations = "classpath:dubbo-consumer.xml")public class ConsumerServiceApplication {    public static void main(String[] args) {        SpringApplication.run(ConsumerServiceApplication.class, args);    }}

 

最后,我们启动程序,控制台应输出以下日志:

Spring Boot集成Dubbo 3.X_Dubbo_06

DubboConsumerXML的工程结构如下:

Spring Boot集成Dubbo 3.X_SpringBoot_07

集成了Dubbo的注释形式

除了使用XML,我们还可以使用注释配置Dubo(毕竟很多人不喜欢XML)。同样,我们需要创建两个项目:DuboproviderAnotation和DuboconsumerAnotation。

DuboproviderAnotion工程

duboprovideranotation工程与duboproproviderXML的配置步骤基本相同。我们快速进入接口的实现部分,这次我们需要使用它@DubboService注解声明这是一个Dubo服务:

package com.wyz.service.impl;import com.wyz.api.DubboProviderAnnotationService;import org.apache.dubbo.config.annotation.DubboService;/** * @author wyz * @version 1.0 * @date 2023/7/3 */@DubboServicepublic class DubboProviderAnnotationServiceImpl implements DubboProviderAnnotationService {    @Override    public String say(String message) {        return "DubboProviderAnnotationService say : " + message;    }}

有了界面和实现,我们将配置Dubbo的相关内容。这一次,我们使用YAML配置:

dubbo:  application:    name: DubboProviderAnnotation    qos-port: 2222  protocol:    name: dubbo  registry:    address: zookeeper://${zookeeper.address:127.0.0.1}:2181

然后,我们添加了启动类别@EnableDubbo打开Dubbo自动注入注释:

package com.wyz.service;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * @author wyz * @version 1.0 * @date 2023/7/3 */@SpringBootApplication@EnableDubbopublic class ProviderServiceApplication {    public static void main(String[] args) {        SpringApplication.run(ProviderServiceApplication.class, args);    }}

DubboProviderAnnotation的结构如下:

Spring Boot集成Dubbo 3.X_SpringBoot_08

最后,我们可以正常启动DubboProviderAnotation项目。

DuboconsumerAnotion工程

有了前面的基础,相信你一定会想到DubboconsumerAnotation应该如何配置,我们先写调用DubboDemoAnnotationService#say此时通过调用逻辑,通过@DubboReference注入接口:

package com.wyz.service.impl;import com.wyz.api.DubboProviderAnnotationService;import org.apache.dubbo.config.annotation.DubboReference;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;/** * @author wyz * @version 1.0 * @date 2023/7/3 */@Componentpublic class DubboConsumerAnnotationService implements CommandLineRunner {    @DubboReference    DubboProviderAnnotationService dubboProviderAnnotationService;    @Override    public void run(String... args) {        String message = dubboProviderAnnotationService.say("wyz");        System.out.println(message);    }}

然后配置YAML文件:

dubbo:  application:    name: DubboConsumerAnnotation    qos-port: 2223  protocol:    name: dubbo  registry:    address: zookeeper://${zookeeper.address:127.0.0.1}:2181

同样,我们需要向服务用户添加它@EnableDubbo打开Dubbo自动注入注释:
package com.wyz.service;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * @author wyz * @version 1.0 * @date 2023/7/3 */@SpringBootApplication@EnableDubbopublic class ConsumerServiceApplication { public static void main(String[] args) { SpringApplication.run(ConsumerServiceApplication.class, args); }}

此时DuboconsumerAnotation的结构如下:

Spring Boot集成Dubbo 3.X_SpringBoot_09

最后,我们可以正常启动DubboconsumerAnotation项目。

结语

在这里,我们将完成Spring的两种形式 Dubboboot集成在Boot中 3.X。一般来说,我会选择以XML的形式配置Dubo提供的服务,但我会选择在YAML文件中配置Dubo的基本信息,如协议类型和注册中心地址,以统一管理外部服务和使用服务,一目了然地看到项目提供的能力和依赖的外部接口。