一、多版本的支持
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd" > <!--提供方信息,用于计算依赖关系--> <dubbo:application name= "dubbo-server" owner= "mic" /> <!--注册中心 暴露服务地址--> <dubbo:registry address= "zookeeper://192.168.126.129:2181" /> <!--用dubbo协议在 20880 端口暴露服务--> <dubbo:protocol port= "20880" name= "dubbo" /> <!--声明需要暴露的服务接口,指定协议为dubbo,设置版本号 1.1 . 1 --> <dubbo:service interface = "com.gupaoedu.dubbo.IGpHello" ref= "gpHelloService" protocol= "dubbo" version= "1.1.1" /> <!--声明需要暴露的服务接口,指定协议为dubbo,设置版本号 1.1 . 2 --> <dubbo:service interface = "com.gupaoedu.dubbo.IDemoService" ref= "demoService" protocol= "dubbo" version= "1.1.2" /> <!--和本地服务一样实现服务--> <bean id= "gpHelloService" class = "com.gupaoedu.dubbo.GpHelloImpl" /> <bean id= "demoService" class = "com.gupaoedu.dubbo.DemoService" /> </beans> |
服务端的接口以及实现类
1
|
public interface IGpHello {String sayHello(String msg);} |
1
|
public interface IDemoService {String protocolDemo(String msg);} |
1
2
3
4
|
public class GpHelloImpl implements IGpHello{ @Override public String sayHello(String msg) { return "Hello:" +msg;} } |
1
2
3
4
|
public class GpHelloImpl2 implements IGpHello{ @Override public String sayHello(String msg) { return "Hello,i'm server 2:" +msg;} } |
编写Main方法,用spring容器来启动服务
1
2
3
4
5
|
public class Main { public static void main(String[] args) throws IOException { //默认情况下会使用spring容器来启动服务 com.alibaba.dubbo.container.Main.main( new String[]{ "spring" , "log4j" });} } |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd" > <!--提供方信息--> <dubbo:application name= "dubbo-client" owner= "mic" /> <!--注册中心--> <dubbo:registry id= "zokeeper" address= "zookeeper://192.168.126.129:2181?register=false" file= "d:/dubbo-server" /> <!--声明需要暴露的服务接口,指定版本号--> <dubbo:reference id= "gpHelloService" interface = "com.gupaoedu.dubbo.IGpHello" registry= "zookeeper" version= "1.1.1" /> </beans> |
其实我们可以在zookeeper的客户端可以发现,事实上已经发布了服务方已经发布了两个不同版本的服务,具体如下
1 dubbo%3A%2F%2F192.168.126.1%3A20880%2Fcom.gupaoedu.dubbo.IDemoService%3Fanyhost%3Dtrue%26application%3Ddubbo-server%26dubbo%3D2.5.3%26interface%3Dcom.gupaoedu.dubbo.IDemoService%26methods%3DprotocolDemo%26owner%3Dmic%26pid%3D22548%26revision%3D1.1.2%26side%3Dprovider%26timestamp%3D1530450331827%26version%3D1.1.2 2 dubbo%3A%2F%2F192.168.126.1%3A20880%2Fcom.gupaoedu.dubbo.IGpHello%3Fanyhost%3Dtrue%26application%3Ddubbo-server%26dubbo%3D2.5.3%26interface%3Dcom.gupaoedu.dubbo.IGpHello%26methods%3DsayHello%26owner%3Dmic%26pid%3D22548%26revision%3D1.1.1%26side%3Dprovider%26timestamp%3D1530450325703%26version%3D1.1.1
我们知道,这两个版本正是我们在服务发布方设置的不同版本号,同样的,在消费端,我们可以通过设置指定的版本号获取相应的版本服务,消费的代码如下
public class App{ public static void main( String[] args ) throws IOException, InterruptedException { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("dubbo-client.xml"); context.start(); IGpHello demoService = (IGpHello)context.getBean("gpHelloService");//获取远程服务代理 String hello = demoService.sayHello("world");//执行远程调用方法 System.out.println(hello);//显示调用结果 } }
在控制台,我们可以看到同样的服务发布地址url。
二、主机绑定
String name = protocolConfig.getName(); if (name == null || name.length() == 0) { name = "dubbo"; } String host = protocolConfig.getHost();//从配置文件中获取host if (provider != null && (host == null || host.length() == 0)) { host = provider.getHost(); } boolean anyhost = false; if (NetUtils.isInvalidLocalHost(host)) { anyhost = true; try { host = InetAddress.getLocalHost().getHostAddress();//获取本机的host地址 } catch (UnknownHostException e) { logger.warn(e.getMessage(), e); } if (NetUtils.isInvalidLocalHost(host)) { if (registryURLs != null && registryURLs.size() > 0) {//如果还是没有获取到host地址 for (URL registryURL : registryURLs) { try { Socket socket = new Socket(); try { SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort()); socket.connect(addr, 1000); host = socket.getLocalAddress().getHostAddress();//3、 break; } finally { try { socket.close(); } catch (Throwable e) {} } } catch (Exception e) { logger.warn(e.getMessage(), e); } } } if (NetUtils.isInvalidLocalHost(host)) {//4、 host = NetUtils.getLocalHost(); } } }
三、集群容错
<!--声明需要暴露的服务接口,指定版本号--> <dubbo:reference id="gpHelloService" interface="com.gupaoedu.dubbo.IGpHello" registry="zookeeper" version="1.1.1" cluster="failover"/>
四、服务降级
<!--声明需要暴露的服务接口,指定版本号--> <dubbo:reference id="gpHelloService" interface="com.gupaoedu.dubbo.IGpHello" registry="zookeeper" version="1.1.1" timeout="1" cluster="failover" mock="com.gupaoedu.dubbo.TestMock"/>
然后我们再验证,将超时间加大,设置为100,再运行,此时就不会报错,就会正常输出Hello world,输出结果如下
<!--声明需要暴露的服务接口,指定版本号--> <dubbo:reference id="gpHelloService" interface="com.gupaoedu.dubbo.IGpHello" registry="zookeeper" version="1.1.1" timeout="100" cluster="failover" mock="com.gupaoedu.dubbo.TestMock"/>
五、总结
好了,总结一下,整理了两个晚上,没有整理出我预想的效果,这篇文章主要是以一种开发文档的形式简单介绍了dubbo的多版本机制实现、主机绑定、集群容错处理机制、以及服务降级处理。后续会介绍dubbo的SPI机制,他是dubbo一种核心机制,我也是刚学习dubbo源码不久,到时候有问题忘大家指正。该篇文章也存在许多不足的地方,比如结构可能不是非常清晰,描述也可能不是非常通俗易懂,后续我会努力矫正,今天就到这了,太困了现在,不写了睡觉。
欢迎扫码关注我的微信公众号,我会不定期的更新一些个人技术文章