[dubbo]springboot2.x整合dubbo之整合dubbo2.6.5
在上篇文章中,我们讲解了如何整合dubbo-spring-boot-starter实现服务化框架的搭建。
文章末尾,我给出了建议,dubbo-spring-boot-starter使用的注解方式的配置不如传统的xml文件灵活,因此我们在线上的开发框架是基于springboot2.x整合了dubbo2.6.5。
通过配置文件的方式更加直观的管理dubbo服务,并对其进行相关的优化操作等。
我们选择的springboot框架的版本为2.1.2.RELEASE,选择了dubbo2.6.5作为基础的整合版本,该版本相比更早的2.5.x修复了较多的遗留bug,且对nacos、sentinel等框架的适配度更好。
话不多说,进入正题。
服务提供方开发
首先整合服务提供方的配置。
引入dubbo依赖
建立一个maven工程dubbo-provider,并在其pom.xml中添加依赖如下:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<curator-framework.version>4.1.0</curator-framework.version>
<zookeeper.version>3.4.13</zookeeper.version>
</properties>
.....
<!-- dubbo依赖开始 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator-framework.version}</version>
</dependency>
<!-- dubbo依赖结束 -->
这里要注意的是,从2.6.5开始,dubbo默认使用的zookeeper客户端更换为apache-curator,不再是zkclient了,因此我们要将apache.curator的依赖引入。你可以直接复用我的配置。
编写dubbo配置文件
在resources文件夹下建立META-INF/dubbo目录,并在其中放置applicationContext-dubbo.xml配置文件,内容如下
applicationContext-dubbo.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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="${spring.application.name}" />
<!-- 使用Zookeeper集群注册中心暴露服务地址 -->
<dubbo:registry protocol="zookeeper" address="${dubbo.zookeeper.address}" />
<dubbo:protocol name="${dubbo.protocol}" port="${dubbo.port}" threadpool="fixed" threads="1000" />
<import resource="classpath:META-INF/dubbo/applicationContext-dubbo-service.xml" />
</beans>
在它引用的applicationContext-dubbo-service.xml中添加我们的dubbo服务实现类及接口配置,这里同样只是为了说明配置方式,简化了服务的代码逻辑。
applicationContext-dubbo-service.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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--具体的服务实现bean-->
<bean id="helloService" class="com.snowalker.dubbo.service.HelloServiceImpl" />
<!--服务接口-->
<dubbo:service interface="com.snowalker.dubbo.service.HelloService"
ref="helloService" />
</beans>
在applicationContext-dubbo-service.xml中编写服务接口及其实现的类的配置,具体的接口及实现类代码如下:
服务接口HelloService
public interface HelloService {
/**
* @param message
* @return
*/
String sayHello(String message);
}
服务接口实现类HelloServiceImpl
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String message) {
return "HELLO:" + message;
}
}
由于我在applicationContext-dubbo.xml中的部分配置是读取的配置文件,因此需要引入配置文件的读取bean定义,定义写在applicationContext-bean.xml中,内容如下:
applicationContext-bean.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:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 读取配置文件 -->
<bean id="commonConfigPropertiesReader"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:application.properties</value>
</list>
</property>
</bean>
<import resource="classpath:META-INF/dubbo/applicationContext-dubbo.xml" />
</beans>
这里我们配置读取classpath下的application.properties中的dubbo相关配置
application.properties中关于dubbo的配置
......
########################################################################
#
# dubbo配置
#
#########################################################################
#zookerper配置
dubbo.zookeeper.address=zookeeper://127.0.0.1:2181?backup=127.0.0.1:2182,127.0.0.1:2183
dubbo.port=20880
dubbo.group=hello-provider
dubbo.timeout=10000
dubbo.version=1.0
dubbo.protocol=dubbo
dubbo.owner=snowalker
dubbo.service.wallet.version=1.0
dubbo.hello-provider.group=hello-provider
我们在applicationContext-bean.xml将applicationContext-dubbo.xml包含,这样在引用的时候只需要引用applicationContext-bean.xml即可将定义的所有的bean都注入到spring容器中。
默认的服务暴露端口为20880
我们依旧使用zookeeper集群模式作为服务配置中心。
启动服务,注入配置文件
在springboot的启动类上将我们定义好的xml文件注入,即可将其中的dubbo服务加载到注册中心,暴露给消费方进行服务调用。代码如下
@SpringBootApplication
@ImportResource({"classpath*:META-INF/dubbo/applicationContext-bean.xml"})
public class WalletApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(WalletApplication.class, args);
}
}
运行该入口main方法即可启动服务提供方,注意一定要保证到注册中心的连接是通的。
服务消费方开发
服务消费方的整合与提供方很类似。
引入dubbo依赖
同样建立一个消费方maven工程,工程名为dubbo-consumer。在pom.xml中添加依赖如下:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<curator-framework.version>4.1.0</curator-framework.version>
<zookeeper.version>3.4.13</zookeeper.version>
</properties>
.....
<!-- dubbo依赖开始 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator-framework.version}</version>
</dependency>
<!-- dubbo依赖结束 -->
编写dubbo配置文件
同样在resources文件夹下建立META-INF/dubbo目录,并在其中放置applicationContext-dubbo.xml配置文件,内容如下
applicationContext-dubbo.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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="${spring.application.name}" />
<!-- 使用Zookeeper集群注册中心暴露服务地址 -->
<dubbo:registry address="${dubbo.zookeeper.address}" />
<!--包含服务定义-->
<import resource="classpath:META-INF/dubbo/applicationContext-reference.xml" />
</beans>
在它引用的applicationContext-reference.xml中添加我们的dubbo消费者配置,同样只是为了说明配置方式,简化了服务的代码逻辑。
applicationContext-reference.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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--消费者服务定义-->
<dubbo:reference id="helloService"
interface="com.snowalker.dubbo.service.HelloService"
version="1.0"
group="${dubbo.hello-provider.group}"
timeout="10000"
retries="0"
check="false"/>
</beans>
设置属性 check=”false” 表示在启动时候不进行启动前服务检查,这样就不需要先启动提供方而能够将服务消费者启动起来。
具体的接口及实现类代码如下:
服务接口HelloService
public interface HelloService {
/**
* @param message
* @return
*/
String sayHello(String message);
}
该接口必须与与服务提供方的完全一致。
编写服务消费方业务代码
@Component
public class Hello implements HelloService {
@Autowired
private IHelloService iHelloService;
@Override
public String sayHello(String message) {
return iHelloService.sayHello(message);
}
}
在applicationContext-bean.xml添加读取配置文件的配置,并将applicationContext-dubbo.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:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 读取配置文件 -->
<bean id="commonConfigPropertiesReader"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:application.properties</value>
</list>
</property>
</bean>
<import resource="classpath:META-INF/dubbo/applicationContext-dubbo.xml" />
</beans>
配置读取classpath下的application.properties中的dubbo相关配置
application.properties中关于dubbo的配置
......
########################################################################
#
# dubbo配置
#
#########################################################################
#zookerper配置
dubbo.zookeeper.address=zookeeper://172.30.66.106:2181?backup=172.30.66.106:2182,172.30.66.106:2183
dubbo.hello-provider.group=hello-provider
同提供方一样,只需要引用applicationContext-bean.xml即可将定义的所有的bean都注入到spring容器中。
dubbo会帮我们在20880端口上查找到helloService并发起远程调用。
同样需要将服务消费者注册到与提供方相同的注册中心。
启动服务,注入配置文件
在消费者的启动类上标注applicationContext-bean.xml配置,即可将其中的dubbo服务加载到注册中心,并发起远程调用。代码如下
@SpringBootApplication
@ImportResource({"classpath*:META-INF/dubbo/applicationContext-bean.xml"})
public class OrderApplication {
public static void main(String[] args) throws Exception {
ApplicationContext context = SpringApplication.run(HelloService.class, args);
Hello hello =
context.getBean("hello", HelloService.class);
String sayHello = hello.sayHello("SnoWalker");
System.out.println(sayHello);
}
}
运行该入口main方法即可启动服务消费方,测试时需要将服务提供方启动完毕,在消费方服务的控制台可以看到输出如下字样,表明调用成功
HELLO:SnoWalker
到这里我们便通过xml传统的配置方式实现了springboot2.x框架对dubbo2.6.5的整合,并给予该开发框架实现了dubbo的开发及调用。
小结
本文是通过xml的方式整合了dubbo2.6.5版本,相比较dubbo-spring-boot-starter方式,这种方式对服务的定义更加清晰,对开发者更容易上手且容易理解,当然在合适的地方也可以使用注解方式,我们的目的就是在合适的地方使用合适的方式,最大限度的发挥不同整合方式的优势。
笔者推荐使用本文的方式去进行基础框架的搭建和整合,实践证明更容易使配置清晰,将配置集中管理,不会因为大量的使用注解而造成配置爆炸的情况。对后续的业务迭代和维护更加友好。