一:简介
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
二:安装dubbo管理控制台(dubbo-admin)
下载dubbo-admin(https://github.com/apache/incubator-dubbo-ops/tree/master) 注意是dubbo-admin项目,不是其它项目。
# 打包
mvn clean install
# 启动项目
cd target
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
# 访问
localhost:7001 用户名:root 密码:root
安装监控中心(dubbo-monitor-simple)
# 打包dubbo-monitor-simple
cd dubbo-monitor-simple
mvn clean package
# 解压.tar.gz
cd target
tar -zxvf dubbo-monitor-simple-2.0.0-assembly.tar.gz
mv dubbo-monitor-simple-2.0.0 ../..
# 启动程序
cd ../../dubbo-monitor-simple-2.0.0/assembly.bin
./start.sh
# 访问
http://localhost:8080/
三:XML方式
① dubbo-api
package com.example.api;
public interface DemoService {
String sayHello(String name);
}
② dubbo-service-provider
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.provider</groupId>
<artifactId>dubbo-service-provider</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.example.api</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
DemoServiceImpl
package com.example.provider;
public class DemoServiceImpl implements DemoService {
public String sayHello(String name) {
return "Hello " + name;
}
}
src/main/resources/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-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 服务命名 -->
<dubbo:application name="service-provider"/>
<!-- 指定注册中心 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- 指定服务提供者和服务消费者的通信协议 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!--监控中心(不是必须的)-->
<dubbo:monitor protocol="registry"/>
<!-- 暴露服务接口及接口关联的实现 -->
<dubbo:service interface="com.example.api.DemoService" ref="demoService" timeout="1000" retries="3">
<dubbo:method name="sayHello" timeout="2000"/>
</dubbo:service>
<bean id="demoService" class="com.example.provider.DemoServiceImpl"/>
</beans>
ProviderMain
package com.example.provider;
public class ProviderMain {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
context.start();
// 按任意键退出(阻塞程序停止结束)
System.in.read();
}
}
③ dubbo-client-consumer
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.consumer</groupId>
<artifactId>dubbo-client-consumer</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.example.api</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
src/main/resources/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-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 服务命名 -->
<dubbo:application name="client-consumer" />
<!-- 指定注册中心 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!--监控中心(不是必须的)-->
<dubbo:monitor protocol="registry"/>
<!-- 引用接口
timeout:服务调用超时时间,默认为1秒;
retries: 超时后重试次数(不包含第一次调用);
version: 版本号,可以在服务提供上对同一个类暴露多次,每次都指定一个版本号,服务消费者可以指定来使用哪个版本的服务,*表示随机调用任意一本版本 -->
<dubbo:reference id="demoService" interface="com.example.api.DemoService" timeout="1000" retries="3"/>
</beans>
dubbo可以使用dubbo:reference针对接口做配置,也可以通过dubbo:method对接口的方法做配置,也可以使用dubbo:consumer用于全局配置,越具体的配置优先级越高
<dubbo:consumer timeout=“1000” retries=“3” check=“false”/>
package com.example.consumer;
public class ConsumerMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
context.start();
DemoService demoService = (DemoService)context.getBean("demoService");
String hello = demoService.sayHello("world");
System.out.println(hello);
// 阻塞程序结束
System.in.read();
}
}
先启动zookeeper,然后再运行ProviderMain最后再运行ConsumerMain
刷新控制台
服务治理下有很多菜单,可以查看具体内容
四:API方式
使用ServiceConfig和ReferenceConfig API取代xml配置方式
public class ProviderMain {
public static void main(String[] args) throws IOException {
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<DemoService>();
serviceConfig.setApplication(new ApplicationConfig("dubbo-service-provider"));
serviceConfig.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
serviceConfig.setInterface(DemoService.class);
serviceConfig.setRef(new DemoServiceImpl());
serviceConfig.export();
// 按任意键退出(阻塞程序停止结束)
System.in.read();
}
}
public class ConsumerMain {
public static void main(String[] args) {
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<DemoService>();
referenceConfig.setApplication(new ApplicationConfig("dubbo-client-consumer"));
referenceConfig.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
referenceConfig.setInterface(DemoService.class);
DemoService demoService = referenceConfig.get();
String hello = demoService.sayHello("world");
System.out.println(hello);
// 阻塞程序结束
System.in.read();
}
}
五:Spring Boot
① 导入dubbo-starter, 在application.properties配置属性,使用@EnableDubbo开启dubbo,使用@Service暴露服务,使用@Reference引用服务
注意:此种方式无法做到方法级别的配置
创建一个不依赖任何starter的Spring Boot工程springboot-dubbo-provider
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>com.example.api</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
@EnableDubbo 开启Dubbo
@EnableDubbo
@SpringBootApplication
public class SpringbootDubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDubboProviderApplication.class, args);
}
}
application.properties
dubbo.application.name=springboot-dubbo-provider
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.monitor.protocol=registry
com.alibaba.dubbo.config.annotation.Service : 暴露接口
package com.example.dubbo.provider;
import com.alibaba.dubbo.config.annotation.Service;
@Service
@Component
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
return "Hello " + name;
}
}
创建一个依赖Web starter的Spring Boot工程:springboot-dubbo-consumer
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>com.example.api</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
application.properties
server.port=8081
dubbo.application.name=springboot-dubbo-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry
@EnableDubbo: 开启Dubbo
@EnableDubbo
@SpringBootApplication
public class SpringbootDubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDubboConsumerApplication.class, args);
}
}
@Reference:引用服务方提供的接口
@RestController
public class DemoController {
@Reference
private DemoService demoService;
@GetMapping("/sayHello")
public String sayHello(String name) {
return demoService.sayHello(name);
}
}
dubbo-api 一个普通的maven工程
package com.example.api;
public interface DemoService {
String sayHello(String name);
}
② 使用xml配置
导入dubbo-starter, 配置使用xml配置(provider.xml、consumer.xml),application.properties就不需要任何dubbo配置,使用@ImportResource(location=“classpath:provider.xml”)来代替@EnableDubbo即可。
此种方式支持方法级别的配置。
③ 使用注解API
使用@Configuration来配置,使用@EnableDubbo开启dubbo,使用@Service暴露接口,使用@Reference来引用接口。
每个标签对应一个config类。如dubbo:application 对应ApplicationConfig
@Configuration
public class DubboConfiguration {
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("springboot-dubbo-provider");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("127.0.0.1");
return registryConfig;
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(20882);
return protocolConfig;
}
@Bean
public ServiceConfig<DemoService> demoServiceServiceConfig(DemoService demoService) {
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>();
serviceConfig.setInterface(DemoService.class);
serviceConfig.setRef(demoService);
MethodConfig methodConfig = new MethodConfig();
methodConfig.setName("sayHello");
methodConfig.setTimeout(2000);
serviceConfig.setMethods(Arrays.asList(methodConfig));
return serviceConfig;
}
}
注册中心和监控不是必须的,当注册中心宕机了,仍不影响服务的调用,可以通过@Reference中的url属性直接指定服务提供者对应的ip和端口 @Reference(url = “127.0.0.1:20880”) , 这就是 Dubbo直连 方式。
负载均衡:Dubbo默认使用随机的RandomLoadBanlance,可以在多个地方来配置复杂均衡策略,如在消费放配置 @Reference(loadbalance = “roundrobin”)
Dubbo可以与Hystrix集成,使用@EnableHystrix来开启,使用@HystrixCommand来标注服务提供者方法和使用@HystrixCommand(fallbackMethod=“xxx”)来标注消费方方法
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>