#dubbo
1.dubbo的hello world
## 客户端启动之后,服务端打印的请求日志
## 注册信息
[DUBBO] Receive multicast message: register consumer://192.168.1.180/zexin.dubbo.server.UserManager?application=dubbo-client&category=consumers&check=false&dubbo=2.6.2&interface=zexin.dubbo.server.UserManager&methods=getUser&pid=1851&side=consumer×tamp=1543910585453 from /192.168.1.180:1234, dubbo version: 2.6.2, current host: 192.168.1.180
## 订阅信息
[DUBBO] Receive multicast message: subscribe consumer://192.168.1.180/zexin.dubbo.server.UserManager?application=dubbo-client&category=providers,configurators,routers&dubbo=2.6.2&interface=zexin.dubbo.server.UserManager&methods=getUser&pid=1851&side=consumer×tamp=1543910585453 from /192.168.1.180:1234, dubbo version: 2.6.2, current host: 192.168.1.180
十二月 04, 2018 4:03:05 下午 com.alibaba.dubbo.registry.multicast.MulticastRegistry info
1.1 代码上的问题
!!#ff0000 1.1.1 multicast连接不上的问题!!
需要在启动参数上加入
-Djava.net.preferIPv4Stack=true
这个配置
!!#ff0000 1.1.2 ReferenConfig的get到的对象!!
// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
ReferenceConfig<UserManager> referenceConfig = new ReferenceConfig<UserManager>();
referenceConfig.setApplication(applicationConfig);
referenceConfig.setRegistry(registryConfig);
referenceConfig.setInterface(UserManager.class);
//UserManager userManager = referenceConfig.get();
## 该userManager的对象不是UserManager实例化的,而是一个代理对象,使用的jdk动态代理,所以必须使用一个接口去接受
!!#ff0000 1.3 bean必须要实现序列化接口,否则无法在网络上传输!! ‘
1.2 代码结构(zexin-dubbo-01 API实现)
1.2.1 新建一个maven项目
1.2.2 该maven项目要新建两个module,一个是dubbo-server模块,一个是dubbo-client模块,其中,在dubbo-server模块中引入dubbo依赖,dubbo-client依赖dubbo-server
1.2.3 dubbo-server服务端代码
package zexin.dubbo.server;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import zexin.dubbo.server.impl.UserService;
import java.io.IOException;
/**
* 简单的dubbo api服务
*
* @author: xin
* @create: 2018-12-04 下午2:42
*/
public class SimpleServer {
public void openServer(Integer port) {
//1. 应用配置 ApplicationConfig
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-server");
//2. 连接注册中心配置 RegistryConfig multicast://224.5.6.7:1234
//RegistryConfig registryConfig = new RegistryConfig("multicast://224.5.6.7:1234");
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("multicast");
registryConfig.setAddress("224.5.6.7:1234");
//3. 服务者提供协议配置 ProtocolConfig
ProtocolConfig protocolConfig = new ProtocolConfig();
//协议名字
protocolConfig.setName("dubbo");
//如果为-1代表不限制端口,从20880开始
protocolConfig.setPort(port);
//protocolConfig.setThreadpool("fixed");
protocolConfig.setThreads(200);
//4. 服务提供者暴露服务配置
//此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏
ServiceConfig<UserService> serviceConfig = new ServiceConfig<UserService>();
serviceConfig.setApplication(applicationConfig);
serviceConfig.setRegistry(registryConfig); // 多个注册中心可以用setRegistries()
serviceConfig.setProtocol(protocolConfig);
serviceConfig.setInterface(UserManager.class);
UserService ref = new UserService();
serviceConfig.setRef(ref);
//serviceConfig.setVersion("1.0.0"); //不推荐使用版本号
//5. 开始提供服务
/***
* 服务已开启!地址:dubbo://192.168.1.180:20880/zexin.dubbo.server.UserManager?anyhost=true&application=dubbo-server&bind.ip=192.168.1.180&bind.port=20880&dubbo=2.6.2&generic=false&interface=zexin.dubbo.server.UserManager&methods=getUser&pid=2020&side=provider&threads=200×tamp=1543915425061
服务已开启!端口:20880
*/
serviceConfig.export();
System.out.println("服务已开启!地址:"+serviceConfig.getExportedUrls().get(0));
System.out.println("服务已开启!端口:"+serviceConfig.getExportedUrls().get(0).getPort());
ref.setPort(serviceConfig.getExportedUrls().get(0).getPort());
}
public static void main(String[] args) throws IOException {
new SimpleServer().openServer(-1);
System.in.read();
}
}
1.2.4 dubbo-client客户端代码
public class SimpleClient {
//使用的是jdk动态代理
private UserManager userService;
public UserManager buildService() {
//1. 当前应用配置
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-client");
//2. 连接注册中心配置
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("multicast");
registryConfig.setAddress("224.5.6.7:1234");
// 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
//3. 引用远程对象
// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
ReferenceConfig<UserManager> referenceConfig = new ReferenceConfig<UserManager>();
referenceConfig.setApplication(applicationConfig);
referenceConfig.setRegistry(registryConfig);
referenceConfig.setInterface(UserManager.class);
//默认加权随机轮询
referenceConfig.setLoadbalance("roundrobin"); //轮询
UserManager service = referenceConfig.get();
URL url = referenceConfig.toUrls().get(0);
/***
* 客户端请求的服务地址:registry://224.5.6.7:1234/com.alibaba.dubbo.registry.RegistryService
* ?application=dubbo-client&dubbo=2.6.2&pid=2026&refer=application%3Ddubbo-client%26dubbo%3D2.6.2%26interface%3Dzexin.dubbo.server.UserManager%26methods%3DgetUser%26pid%3D2026%26register.ip%3D192.168.1.180%26side%3Dconsumer%26timestamp%3D1543915509407®istry=multicast×tamp=1543915509518---224.5.6.7:1234
*/
System.out.println("客户端请求的服务地址:" + url + "---" + url.getAddress());
this.userService = service;
return userService;
}
public static void main(String[] args) throws IOException {
SimpleClient client = new SimpleClient();
client.buildService();
String cmd;
while (!(cmd = read()).equals("exit")) {
UserVo u = client.userService.getUserWithPort(Integer.parseInt(cmd));
System.out.println(u);
}
}
private static String read() throws IOException {
byte[] b = new byte[1024];
int size = System.in.read(b);
return new String(b, 0, size).trim();
}
}
1.3 代码结构(zexin-dubbo-01 Spring实现)
1.3.1 spring-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" xmlns:dubboi="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!--提供方用于信息,用于计算依赖关系-->
<dubbo:application name="dubbo-server"/>
<!--注册中心配置-->
<dubboi:registry address="multicast://224.5.6.7:1234"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="-1"/>
<!-- 声明需要暴露的服务接口 register="" 如果有多个注册的话需要指定该服务注册到哪个注册中心-->
<dubbo:service id="userManager" interface="zexin.dubbo.server.UserManager" ref="userService" timeout="2000" retries="2"/>
<bean id="userService" class="zexin.dubbo.server.impl.UserService"/>
<!--当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选-->
<dubbo:provider/>
</beans>
1.3.2 SpringClienApplication配置
public class SpringServerApplication {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("/spring-provide.xml");
((ClassPathXmlApplicationContext) context).start();
System.in.read();
}
}
1.3.3 spring-consumer配置
<?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" xmlns:dubboi="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-client"/>
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<!--<dubbo:protocol name="dubbo" port="-1"/>-->
<!--Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'zexin.dubbo.server.UserManager' available-->
<!--此处id必须要填,否则会报上面的异常-->
<dubbo:reference id="userManager2" interface="zexin.dubbo.server.UserManager" loadbalance="roundrobin"></dubbo:reference>
</beans>
1.3.4 SpringClientApplication配置
public class SpringClienApplication {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("/spring-consumer.xml");
UserManager userManager = context.getBean(UserManager.class);
while (!read().equals("exit")) {
UserVo u = userManager.getUserWithPort(1111);
System.out.println(u);
}
}
private static String read() throws IOException {
byte[] b = new byte[1024];
int size = System.in.read(b);
return new String(b, 0, size).trim();
}
}
2. dubbo的深入理解
dubbo在新的server启动后会立马生效,不需要等待心跳时间
2.1 dubbo配置关系图
2.2 dubbo配置
2.3 配置覆盖关系
2.3 配置分类
- 服务发现
表示该配置用于服务的注册与发现,目的是让消费方找到提供(如注册中心配置)
- 服务治理
表示该配置用于治理服务间的关系,或为开发测试提供便利条件(如注册,订阅等)
- 性能调优
表示该配置用于调优性能,不同的选项会对性能产生影响
2.4 dubbo的一些套路
<dubbo:service interface="tuling.dubbo.server.UserService" timeout="2000">
在服务端配置的超时时间,其实是表示客户端请求服务端多久超时,不是服务端处理了多久超时。
类似这种配在服务端用在客户端的配置还有很多,如retries/riː’traɪ/(重试次数)、async/əˈsɪŋk/(是否异步)、loadbalance(负载均衡)。。。等。
2.4.1 服务端错误日志
服务端错误日志是提示channel关闭,无法send response
2.4.2 客户端错误日志
客户端错误地址提示超时异常
2.4.3 关于group
group 可以在provider的service和consumer的reference配置,同个group的consumer才可以调用provider,如果设置了provider的group,没有设置consumer的group或者与provider的group不一致,会报没有提供者的异常
dubbo:provider 和dubbo:consumer也可以配置group,不过他们配置的是针对全部的service和reference的
!18 !!!#ff0000 总结_!!!
dubbo的很多配置都服务端配置,客户端来使用,看上面的参数优先级就知道了,相同配置下,客户端的配置会优先于服务端,超时的设置建议是在服务端配置,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。
3. 推荐配置
3.1 provider
<dubbo:application name="demo-provider"/>
<dubbo:registry protocol="redis" address="192.168.0.147:6379" check="true"/>
<dubbo:protocol name="dubbo" port="20880"/>
<dubbo:provider group="tuling.dubbo.demo"
threadpool="fixed"
threads="500"
timeout="5000"
retries="2"
/>
<dubbo:service interface="com.tuling.teach.service.DemoService"
timeout="5000"
retries="1"
version="3.0.0"
ref="demoService"/>
<bean id="demoService" class="com.tuling.teach.service.DemoServiceImpl"/>
3.2 consumer
<dubbo:application name="demo-consumer"/>
<dubbo:registry protocol="redis" address="192.168.0.147:6379" check="true"/>
## retries为2次,加上本来的一次,就是重试3次
<dubbo:consumer timeout="5000" retries="2"
group="tuling.dubbo.demo"
version="1.0.0"/>
<dubbo:reference
timeout="3000" retries="1"
id="demoService"
version="*"
interface="com.tuling.teach.service.DemoService"/>