[TOC]
Spring XML 方式
直连方式
provider
添加一个 provider service:
public interface ProviderService {
String sayHello(String word);
}
实现该接口:
public class ProviderServiceImpl implements ProviderService {
@Override
public String sayHello(String name) {
return "Hello, " + name;
}
}
提供 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://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="provider" owner="bolitao"/>
<dubbo:monitor protocol="registry"/>
<!--暂不使用注册中心-->
<dubbo:registry address="N/A"/>
<dubbo:protocol name="dubbo" port="20880"/>
<dubbo:service interface="xyz.bolitao.service.ProviderService" ref="providerService"/>
<bean id="providerService" class="xyz.bolitao.service.ProviderServiceImpl"/>
</beans>
编写 main()
:
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
context.start();
System.in.read();
}
启动 provider,可以看到 dubbo 已开启服务:
文件树如下:
consumer
添加 provider 依赖,consumer 的其余依赖和 provider 一致:
<dependencies>
<dependency>
<groupId>xyz.bolitao</groupId>
<artifactId>provider</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--其他依赖项-->
...
</dependencies>
添加 dubbo 配置 consumer.xml
,注意调用地址 dubbo://172.16.44.186:20880/xyz.bolitao.service.ProviderService
:
<?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="consumer" owner="bolitao"/>
<dubbo:registry address="N/A"/>
<dubbo:reference id="providerService" interface="xyz.bolitao.service.ProviderService" url="dubbo://172.16.44.186:20880/xyz.bolitao.service.ProviderService"/>
</beans>
添加 comsumer 的 main()
方法,通过 dubbo 调用 sayHello()
方法:
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
context.start();
ProviderService providerService = (ProviderService) context.getBean("providerService");
String str = providerService.sayHello("dubbo");
System.out.println(str);
System.in.read();
}
运行 consumer 后,可以看到以下信息:
代码文件树如下:
Zookeeper 注册中心方式
provider 修改
修改 provider.xml
:
<!--原始值:-->
<dubbo:registry address="N/A"/>
<!--修改为以下值:-->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" check="false"/>
consumer 修改
与 provider 类似,将 dubbo:registry
的 address
值修改为 zk 地址:
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" check="false"/>
将 reference 的 URL 删去,consumer 将从 zk 获取服务地址:
<!--原来的 reference 配置:-->
<dubbo:reference id="providerService" interface="xyz.bolitao.service.ProviderService"
url="dubbo://172.16.44.186:20880/xyz.bolitao.service.ProviderService"/>
<!--新的 renfence 配置:-->
<dubb:reference interface="xyz.bolitao.service.ProviderService" id="providerService"/>
运行结果
运行 provider:
运行 consumer:
zk 中注册的服务:
Spring 注解配置方式(com.alibaba.dubbo)
provider
ProviderServiceAnnotation
类:
public interface ProviderServiceAnnotation {
String sayHelloAnnotation(String name);
}
ProviderServiceImplAnnonation
类,使用 dubbo 提供的 @Service
注解进行声明:
@Service(timeout = 5000)
public class ProviderServiceImplAnnonation implements ProviderServiceAnnotation {
@Override
public String sayHelloAnnotation(String name) {
return "Hello, " + name;
}
}
DubboConfiguration
配置类:
@Configuration
@EnableDubbo(scanBasePackages = "xyz.bolitao.service.annotation")
public class DubboConfiguration {
@Bean
public ProviderConfig providerConfig() {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTimeout(1000);
return providerConfig;
}
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-annotation-provider");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("localhost");
registryConfig.setPort(2181);
return registryConfig;
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(20880);
return protocolConfig;
}
}
运行如下:
代码文件树如下:
consumer
添加 ConsumerAnnotationService
,用以替代 XML 形式配置中的 dubb:reference interface
:
@Component("annotatedConsumer")
public class ConsumerAnnotationService {
@Reference
private ProviderServiceAnnotation providerServiceAnnotation;
public String doSayHello(String content) {
return providerServiceAnnotation.sayHelloAnnotation(content);
}
}
添加一个配置类 DubboConsumerConfiguration
:
@Configuration
@EnableDubbo(scanBasePackages = "xyz.bolitao.consumer.annotation")
@ComponentScan(value = "xyz.bolitao.consumer.annotation")
public class DubboConsumerConfiguration {
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-annotation-consumer");
Map<String, String> stringStringMap = new HashMap<>(5);
stringStringMap.put("qos.enable", "true");
stringStringMap.put("qos.accept.foreign.ip", "true");
stringStringMap.put("qos.port", "22221");
applicationConfig.setParameters(stringStringMap);
return applicationConfig;
}
@Bean
public ConsumerConfig consumerConfig() {
ConsumerConfig consumerConfig = new ConsumerConfig();
consumerConfig.setTimeout(3000);
return consumerConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("localhost");
registryConfig.setPort(2181);
return registryConfig;
}
}
编写 consumer main
方法:
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(DubboConsumerConfiguration.class);
context.start();
ConsumerAnnotationService consumerAnnotationService = context.getBean(ConsumerAnnotationService.class);
System.out.println(consumerAnnotationService.doSayHello("dubbo"));
}
运行结果如下:
目录树如下:
总结:使用 Spring 时,该方法还不如 xml 方式简洁。
Spring Boot 方式(dubbo-spring-boot-starter)
alibaba 的 spring boot starter 已经不维护,apache 继续维护的 starter GitHub 页为:apache/dubbo-spring-boot-project: Spring Boot Project for Apache Dubbo。这里使用 Apache 维护的 starter。
API
建立一个 API model,只写一个接口:
public interface TestService {
public String doSth(String content);
}
代码目录树如下:
provider
新建一个 starter_provider
模块,添加依赖如下:
<dependency>
<groupId>xyz.bolitao</groupId>
<artifactId>api</artifactId><!--该包为上节添加的 api 模块-->
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
修改 springboot 启动配置如下:
server.port=10010
dubbo.application.id=provider
dubbo.application.name=provider
dubbo.registry.address=zookeeper://192.168.200.1:2181
dubbo.provider.threads=10
dubbo.provider.threadpool=fixed
dubbo.provider.loadbalance=roundrobin
dubbo.server=true
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
之后实现 TestService 接口,注意 @Service
注解不由 spring 提供,而使用 org.apache.dubbo.config.annotation
包:
@Service(version = "1.0.0")
public class TestServiceImpl implements TestService {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
@Override
public String doSth(String content) {
logger.info("provider 服务被调用");
return "Hello, " + content;
}
}
在 main
方法外,添加 @DubboComponentScan
注解,指定 dubbo 扫描的包位置:
@SpringBootApplication
@DubboComponentScan(basePackages = "xyz.bolitao.starter_provider.service.impl")
public class StarterProviderApplication {
public static void main(String[] args) {
...
代码目录树如下:
consumer
新建 starter-consumer
module,创建 module 时勾选 web starter 依赖,并添加刚才自己创建的 api 和 starter_provider 模块:
<dependency>
<groupId>xyz.bolitao</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>xyz.bolitao</groupId>
<artifactId>starter_provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
...
<!--还需添加和 provider 一样的 dubbo、zk 相关依赖-->
修改 Spring Boot 应用配置:
server.port=10011
dubbo.application.id=consumer
dubbo.application.name=consumer
dubbo.registry.address=zookeeper://192.168.200.1:2181
dubbo.consumer.check=true
添加一个 REST controller,用于远程调用 provider 的方法:
@RestController
@RequestMapping("test")
public class TestController {
@Reference(version = "1.0.0")
private TestService testService;
@GetMapping("{content}")
public String test(@PathVariable String content) {
return testService.doSth(content);
}
}
代码文件树如下:
运行效果
依次运行 provider 和 consumer,访问 consumer 提供的 127.0.0.1:10011/test/{content}
页面:
provider 控制台有以下内容输出: