前言
dubbo是一个高性能的RPC框架,提供面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现等能力(从官网上抄过来的,反正很强大),可以和spring无缝整合,实现接口透明化调用。
简单说就是,通过dubbo,可以将本地spring容器中的服务暴露出去,也可以将远程服务引用到spring中(体现在代码中,就是简单换了两个注解,就好了!!!)。
这里呢,介绍下dubbo的几种调用方式,主要分为:xml配置、属性文件+注解方式、API调用方式。
dubbo官网地址:http://dubbo.apache.org/
几种配置方式的介绍
xml方式
- 提供者
通过配置application、registry、protocol、service等标签做提供者的应用配置。 - 消费者
通过配置application、registry、reference等标签做消费者的应用配置。 - service和reference
提供者通过service暴露服务,消费者通过reference引用服务
属性文件+注解方式
通过使用spring的自动注入方式,将application、registry、protocol等信息通过属性文件自动注入。
消费者通过注解@Reference代替xml中的reference标签
提供者通过注解@Service代替xml中的service标签
API方式
通过dubbo提供的底层类ServiceConfig、ReferenceConfig完成服务的暴露和引用。
提供者通过将接口信息、接口实例、application、registry等信息封装为ServiceConfig,暴露服务。
消费者通过将接口信息、application、registry等信息封装为ReferenceConfig,查找接口实例,引用服务。
前提
- 本地有个zookeeper注册中心
- 搭建个dubbo的控制台,根据dubbo官方文档进行搭建(可选)
可以在dubbo-admin-server中配置文件(application.properties)修改zk注册中心的地址,以及后台的默认账号密码。
git clone https://github.com/apache/dubbo-admin.git
cd dubbo-admin
mvn clean package
cd dubbo-admin-distribution/target
java -jar dubbo-admin-0.1.jar
准备工作
新建个mvn项目
- pom文件
<properties>
<spring.version>4.3.16.RELEASE</spring.version>
<dubbo.version>2.6.5</dubbo.version>
</properties>
<!-- spring支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-config-spring</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- zookeeper注册中心 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-remoting-netty</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>${dubbo.version}</version>
</dependency>
一些公用的类
- 公用接口UserService
package com.zyu.service;
public interface UserService {
String echoUser(String username);
}
- UserService接口的实现类
package com.zyu.service;
import com.alibaba.dubbo.config.annotation.Service;
@Service//dubbo的Service注解
public class UserServiceImpl implements UserService {
public String echoUser(String username) {
System.out.println("收到远程调用请求,username:" + username);
return String.format("dubbo provider echo:hello,%s", username);
}
}
- UserController调用类
package com.zyu.action;
import com.alibaba.dubbo.config.annotation.Reference;
import com.zyu.service.UserService;
import org.springframework.stereotype.Component;
@Component("userController")
public class UserController {
@Reference//dubbo的Reference注解
private UserService userService;
public String echo(String username){
String s = userService.echoUser(username);
return s;
}
}
代码撸起来
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:context="http://www.springframework.org/schema/context"
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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--全局配置-->
<dubbo:provider timeout="3000" />
<!-- 服务提供方应用名称, 方便用于依赖跟踪 -->
<dubbo:application name="xml-provider" />
<!-- 使用本地zookeeper作为注册中心 -->
<dubbo:registry address="zookeeper://192.168.1.103:2181" />
<!--name指示使用什么协议监听端口:dubbo/rmi/rest-->
<dubbo:protocol id="d1" name="dubbo" port="20880" />
<dubbo:protocol id="d2" name="dubbo" port="20882" />
<!-- 通过xml方式配置为bean, 让spring托管和实例化 -->
<bean id="userService" class="com.zyu.service.UserServiceImpl"/>
<!-- 声明服务暴露的接口,并暴露服务 -->
<dubbo:service interface="com.zyu.service.UserService" ref="userService" protocol="d1" />
</beans>
- 消费者配置
<?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:context="http://www.springframework.org/schema/context"
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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="xml-consumer" />
<dubbo:registry address="zookeeper://192.168.1.103:2181" />
<dubbo:reference id="userService" interface="com.zyu.service.UserService" />
</beans>
- 提供者代码
package com.zyu.dubbo.xml;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* xml文件配置方式暴露dubbo服务
*/
public class XmlProvider {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:/spring/dubbo-server.xml");
app.start();
System.out.println("dubbo 启动成功");
System.in.read();
}
}
- 消费者代码
package com.zyu.dubbo.xml;
import com.zyu.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* xml文件配置方式引用dubbo服务
*/
public class XmlConsumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:/spring/dubbo-client.xml");
app.start();
UserService userService = app.getBean(UserService.class);
String ret = userService.echoUser("zyufocus");
System.out.println(ret);
}
}
配置类方式
Bean配置方式
- 提供者代码
package com.zyu.dubbo.annotation;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import com.zyu.action.UserController;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 注解方式引用dubbo服务
*/
public class AnnoConsumer {
public static void main(String[] args) {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
app.start();
UserController userController = app.getBean(UserController.class);
String ret = userController.echo("zyufocus");
System.out.println(ret);
}
@Configuration
@ComponentScan("com.zyu.action")
@EnableDubbo(scanBasePackages = "com.zyu.action")
static class Config{
@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("anno-consumer");
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("192.168.1.103");
registryConfig.setPort(2181);
return registryConfig;
}
}
}
- 消费者代码
package com.zyu.dubbo.annotation;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import com.zyu.action.UserController;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 注解方式引用dubbo服务
*/
public class AnnoConsumer {
public static void main(String[] args) {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
app.start();
UserController userController = app.getBean(UserController.class);
String ret = userController.echo("zyufocus");
System.out.println(ret);
}
@Configuration
@ComponentScan("com.zyu.action")
@EnableDubbo(scanBasePackages = "com.zyu.action")
static class Config{
@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("anno-consumer");
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("192.168.1.103");
registryConfig.setPort(2181);
return registryConfig;
}
}
}
自动装配方式
自动装配,就是将配置类中手动创建的Bean,使用spring自动装配的方式,从属性文件中自动装配到Bean中。
- 提供者的属性文件
dubbo.application.name=properties-provider
dubbo.registry.address=zookeeper://192.168.1.103:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
- 消费者的属性文件
dubbo.application.name=properties-consumer
dubbo.registry.address=zookeeper://192.168.1.103:2181
dubbo.consumer.timeout=30000
- 提供者代码
package com.zyu.dubbo.config;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import java.io.IOException;
/**
* 属性文件配置方式暴露dubbo服务
*/
public class ConfigProvider {
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
app.start();
System.out.println("dubbo 启动成功");
System.in.read();
}
@Configuration
@EnableDubbo(scanBasePackages = "com.zyu.service")
@PropertySource("classpath:dubbo-provider.properties")
static class Config {
}
}
- 消费者代码
package com.zyu.dubbo.config;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import com.zyu.action.UserController;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* 属性文件配置方式引用dubbo服务
*/
public class ConfigConsumer {
public static void main(String[] args) {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
app.start();
UserController userController = app.getBean(UserController.class);
String s = userController.echo("zyufocus");
System.out.println(s);
}
@Configuration
@EnableDubbo(scanBasePackages = "com.zyu.action")
@ComponentScan("com.zyu.action")
@PropertySource("classpath:dubbo-consumer.properties")
static class Config{
}
}
API方式
- 提供者代码
package com.zyu.dubbo.api;
import com.alibaba.dubbo.config.*;
import com.zyu.service.UserService;
import com.zyu.service.UserServiceImpl;
import java.io.IOException;
/**
* 使用api方式暴露dubbo服务
*/
public class ApiProvider {
public static void main(String[] args) throws IOException {
ServiceConfig<UserService> serviceConfig = new ServiceConfig<UserService>();
serviceConfig.setApplication(new ApplicationConfig("api-provider"));
serviceConfig.setRegistry(new RegistryConfig("zookeeper://192.168.1.103:2181"));
serviceConfig.setInterface(UserService.class);
serviceConfig.setRef(new UserServiceImpl());
serviceConfig.export();
System.out.println("api 方式暴露服务成功");
System.in.read();
}
}
- 消费者代码
package com.zyu.dubbo.api;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.zyu.service.UserService;
/**
* 使用api方式调用dubbo服务
*/
public class ApiConsumer {
public static void main(String[] args) {
ReferenceConfig<UserService> referenceConfig = new ReferenceConfig<UserService>();
referenceConfig.setApplication(new ApplicationConfig("api-consumer"));
referenceConfig.setRegistry(new RegistryConfig("zookeeper://192.168.1.103:2181"));
referenceConfig.setInterface(UserService.class);
UserService userService = referenceConfig.get();
String s = userService.echoUser("zyufocus");
System.out.println(s);
}
}
测试
使用xml方式作测试。
-
启动提供者
-
启动消费者
- 查看dubbo控制台(localhost:8080)
结束语
简单使用下dubbo,蛮有意思,比自己写的rmi要好多了。
学无止境,诸君共勉