Dubbo+Zookeeper架构——springboot整合dubbo
SpringBoot与Dubbo的整合,在网上我百度到最多的会两种方式的依赖引入。
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
</dependency>
不过根据更新的时间去看,我这边选用了alibaba的依赖来使用。并且ch
查看官网给的案例:https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/README_CN.md
项目结构:
以上是一个简单的dubbo 和 springboot 整合的结构。
- springboot_dubbo_luu_learing 父项目
- luu_api 接口
- luu_service 服务提供者
- luu_web 服务消费者
luu_api 接口
该项目主要是用来在消费者和提供者中引用,为两者直接diao调用提供一个接口。主要是实体类对象会保存在这个项目中。也不会有过多的依赖引入。
pom.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot_dubbo_luu_learing</artifactId>
<groupId>com.luu.learing</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luu_api</artifactId>
<packaging>jar</packaging>
<name>luu_api</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
</project>
luu_service 服务消费者
目前我们没有采用自动的dubbo配置,我们是自定义配置类去对dubbo进行配置。
pom.xml配置文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot_dubbo_luu_learing</artifactId>
<groupId>com.luu.learing</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luu_service</artifactId>
<packaging>jar</packaging>
<name>luu_service</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 服务监控模块 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<!-- 引入spring-boot-starter以及dubbo和curator的依赖 -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!--<dependency>-->
<!--<groupId>io.dubbo.springboot</groupId>-->
<!--<artifactId>spring-boot-starter-dubbo</artifactId>-->
<!--<version>1.0.0</version>-->
<!--</dependency>-->
<!-- Spring Boot相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- zk服务中心 -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.2</version>
</dependency>
<!--Mybatis-SpringBoot集成-->
<!--<dependency>-->
<!--<groupId>org.mybatis.spring.boot</groupId>-->
<!--<artifactId>mybatis-spring-boot-starter</artifactId>-->
<!--<version>1.0.0</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>com.alibaba</groupId>-->
<!--<artifactId>druid-spring-boot-starter</artifactId>-->
<!--<version>1.1.0</version>-->
<!--</dependency>-->
<!-- mysql-connector-java -->
<!--<dependency>-->
<!--<groupId>mysql</groupId>-->
<!--<artifactId>mysql-connector-java</artifactId>-->
<!--<version>5.1.38</version>-->
<!--</dependency>-->
<!--luu_api服务接口-->
<dependency>
<groupId>com.luu.learing</groupId>
<artifactId>luu_api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
dubbo.xml配置文件
# zk注册中心地址和端口,注册中心配置,用于配置连接注册中心相关信息。
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.registry.id=luu-service-registry
# 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。
# 当前服务/应用的名字
spring.dubbo.application.name=provider
spring.dubbo.application.id=provider
# 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
spring.dubbo.protocol.port=20991
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.id=dubbo
spring.dubbo.protocol.status=server
# 服务暴露与发现消费所在的package,这个配置只要用来扫描我们向外提供服务的实现类的包 ,开启包扫描,可替代 @EnableDubbo 注解
spring.dubbo.scan.basePackages=com.luu.learing.facadeImpl
# 这是一个我们自定义的服务版本号,可以随便写,推荐规范的书写
spring.dubbo.service.version=1.0.0
# 启动时检查
spring.dubbo.consumer.check=false
我们在 DefaultProperties 类中使用配置注解 @Configuration ,通过注解
@PropertySource(value = {"classpath:/dubbo.properties"}, ignoreResourceNotFound = true)
引入了外部属性的配置文件。并且通过注解 @ConfigurationProperties 将对应的dubbo属性值配置到类 DubboProperties
@Configuration
@PropertySource(value = {"classpath:/dubbo.properties"}, ignoreResourceNotFound = true)
public class DefaultProperties {
@Bean
@ConfigurationProperties(prefix = "spring.dubbo")
public DubboProperties dubboProperties() {
return new DubboProperties();
}
}
package com.luu.learing.config;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
public class DubboProperties {
private String scan;
private ApplicationConfig application;
private ProtocolConfig protocol;
private RegistryConfig registry;
private int timeout=3000;
private int retries=3;
private int delay=-1;
public String getScan() {
return scan;
}
public void setScan(String scan) {
this.scan = scan;
}
public ApplicationConfig getApplication() {
return application;
}
public void setApplication(ApplicationConfig application) {
this.application = application;
}
public ProtocolConfig getProtocol() {
return protocol;
}
public void setProtocol(ProtocolConfig protocol) {
this.protocol = protocol;
}
public RegistryConfig getRegistry() {
return registry;
}
public void setRegistry(RegistryConfig registry) {
this.registry = registry;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getRetries() {
return retries;
}
public void setRetries(int retries) {
this.retries = retries;
}
public int getDelay() {
return delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
}
之后我们自定义配置类去配置dubbo
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.AnnotationBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SuppressWarnings("deprecation")
@Configuration
//某个class位于类路径上,才会实例化一个Bean
@ConditionalOnClass({AnnotationBean.class,ApplicationConfig.class,ProtocolConfig.class,RegistryConfig.class,ProviderConfig.class})
public class DubboAutoConfigration {
@Bean
@ConditionalOnMissingBean(AnnotationBean.class)//容器中如果没有这个类,那么自动配置这个类
public static AnnotationBean annotationBean(@Value("${spring.dubbo.scan.basePackages}")String packageName) {
System.out.println("-------------------------"+packageName+"-----------------------------");
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage(packageName);
return annotationBean;
}
@Bean
@ConditionalOnMissingBean(ApplicationConfig.class)//容器中如果没有这个类,那么自动配置这个类
public ApplicationConfig applicationConfig( DubboProperties prop) {
ApplicationConfig applicationConfig = new ApplicationConfig();
System.out.println("----"+prop.getApplication().getName());
applicationConfig.setName(prop.getApplication().getName());
return applicationConfig;
}
@Bean
@ConditionalOnMissingBean(ProtocolConfig.class)//容器中如果没有这个类,那么自动配置这个类
public ProtocolConfig protocolConfig( DubboProperties prop) {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName(prop.getProtocol().getName());
System.out.println(prop.getProtocol().getName()+"======");
protocolConfig.setPort(prop.getProtocol().getPort());
return protocolConfig;
}
@Bean
@ConditionalOnMissingBean(RegistryConfig.class)//容器中如果没有这个类,那么自动配置这个类
public RegistryConfig registryConfig( DubboProperties prop) {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(prop.getRegistry().getAddress());
return registryConfig;
}
@Bean
public ProviderConfig providerConfig(ApplicationConfig applicationConfig, RegistryConfig registryConfig, ProtocolConfig protocolConfig,DubboProperties prop) {
System.out.println("providerConfig 配置=====");
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTimeout(prop.getTimeout());
providerConfig.setRetries(prop.getRetries());
providerConfig.setDelay(prop.getDelay());
providerConfig.setApplication(applicationConfig);
providerConfig.setRegistry(registryConfig);
providerConfig.setProtocol(protocolConfig);
return providerConfig;
}
}
发布服务tong通过注解@Service,这个@Service是dubbo提供的注解
@Component
@Service(interfaceClass = UserInfoFacade.class)
public class UserInfoFacadeImpl implements UserInfoFacade {
@Autowired
private UserInfoService userInfoService;
@Override
public UserInfo getUserInfo() {
return userInfoService.getUuserInfo();
}
}
服务提供者启动类
@SpringBootApplication
@EnableAutoConfiguration
public class LuuSerApplication
{
public static void main( String[] args )
{
ConfigurableApplicationContext context = SpringApplication.run(LuuSerApplication.class, args);
}
}
luu_web 服务消费者
服务消费者的配置与服务提供者一样,除了在配置文件上有点不同之外,比如协议的端口号和名称不一样。
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.registry.id=luu-controller-registry
spring.dubbo.protocol.port=20990
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.id=dubbo
spring.dubbo.protocol.status=server
spring.dubbo.application.name=comsumer
spring.dubbo.application.id=comsumer
spring.dubbo.scan.basePackages=com.luu.learing.controller
spring.dubbo.service.version=1.0.0
spring.dubbo.consumer.check=false
消费服务,通过注解@Reference 注解
@RestController
public class LuuController {
@Reference
private UserInfoFacade userInfoFacade;
@RequestMapping("getInfo")
public UserInfo get(){
return userInfoFacade.getUserInfo();
}
}
我们分别启用消费者和提供者,然后在管控台可以看到数据。