【Dubbo分布式服务框架】2.基于配置的服务提供者和消费者

来源:互联网 发布:java 实现http长轮询 编辑:程序博客网 时间:2024/06/06 00:54
一个使用Dubbo的系统架构图如下:


可分为以下几个角色:
(1)Provider:暴露服务的服务提供方。
(2)Consumer:调用远程服务的服务消费方。
(3)Registry:服务注册与发现的注册中心。
(4)Monitor:统计服务的调用次调和调用时间的监控中心。
(5)Container:服务运行容器。
其中上面的调用关系为:
0.服务容器负责启动,加载,运行服务提供者。
1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

其实上面的整个流程我们可以转换成日常生活的一个场景:Provider是冷饮提供商,Consumer是购买冷饮的零售商,Registry是冷饮市场的中介,Monitor是工商管理局,而Container是存放冷饮的冷冻库。所以上面的调用关系可以转换为:
0.冷冻库Container用于存放冷饮提供商Provider的产品---冷饮。
1.冷饮提供商Provider在拥有冷冻库的商品后,需要在中介备案,打开销售渠道。
2.冷饮的零售商Consumer需要向中介联系,告知需要的冷饮种类,以帮助寻找合适的厂家订购货源。
3.冷饮市场的中介Registry会将各大冷饮厂商提供的商品列表给冷饮的零售商Consumer看,如果有变动,中介会实时联系厂商。
4.冷饮的零售商Consumer会通过中介Registry提供的厂商列表,选取拿货地最近,路程最短,竞争者最少的厂商购买商品,如果订购失败,就选择其它合适厂商继续订购。
5.冷饮提供商Provider和冷饮的零售商Consumer的每次商业运作,都要告知工商管理局Monitor,有利于政府的监管。

这样解释,大家对于整个Dubbo的架构流程大致有一个思路了吧?我们下面动手去实现Dubbo的基于配置的服务提供者和消费者。

一、服务提供者
首先我们在MyEclipse中创建一个服务提供者的WebProject,名为Dubbo-Web-Provider:



然后我们的Dubbo可以只依赖JDK,不依赖于任何三方库运行,只需配置使用JDK相关实现策略。
我们需要添加的jar包有:
com.alibaba.dubbo.jar(dubbo官方jar包)
log4j.jar(日志输出依赖jar包)
org.javassist.jar(字节码生成jar包)
org.springframework.spring.jar(Spring依赖jar包)
commons-logging.jar(日志输出依赖jar包)
org.jboss.netty.jar(网络传输jar包)

我们将这些jar包放置在Web工程的lib文件夹下,然后“Add To Build Path”添加到编译环境中。


然后我们创建一个原文件夹config,用于存放Spring的配置文件,然后在该文件夹下创建provider.xml配置文件:


在appliactionContext.xml配置文件中添加Spring以及Dubbo的Schema扩展:
<?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:aop="http://www.springframework.org/schema/aop"       xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"       xsi:schemaLocation="http://code.alibabatech.com/schema/dubbo           http://code.alibabatech.com/schema/dubbo/dubbo.xsd           http://www.springframework.org/schema/beans            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-2.5.xsd           http://www.springframework.org/schema/aop           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd           http://www.springframework.org/schema/tx            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  </beans>

然后我们分别定义一个Service服务的接口和实现:

服务接口:
package cn.com.dubbo.service;public interface SortService {//升序排序int[] ascendingSort(int[] arrays);}

服务实现:
package cn.com.dubbo.service.impl;import cn.com.dubbo.service.SortService;public class SortServiceImpl implements SortService{@Overridepublic int[] ascendingSort(int[] arrays) {int temp=0;//冒泡升序排序for (int i = 0; i < arrays.length-1; i++) {for (int j = i+1; j < arrays.length; j++) {if(arrays[i]>arrays[j]){temp=arrays[i];arrays[i]=arrays[j];arrays[j]=temp;}}}return arrays;}}

该服务提供了一个对int数组升序排序的功能。

我们前面提到过有一个Registry,即服务注册与发现的注册中心,这个注册中心就相当于冷饮厂商和冷饮零售商之间的中介,服务提供者在其上面注册服务,服务消费者在其上面获取服务。
我们这里使用的注册中心为Zookeeper,我们先去使用它,关于它的详细介绍,我会在后面的章节中详细为大家讲解。
下载Zookeeper:
http://www.apache.org/dyn/closer.cgi/zookeeper/  
获得压缩文件之后,解压在合适的硬盘中:

修改conf修改zoo_sample.cfg内容,然后修改文件名为zoo.cfg
内容如下:
# The number of milliseconds of each tick  心跳间隔 毫秒每次tickTime=2000# The number of ticks that the initial# synchronization phase can takeinitLimit=10# The number of ticks that can pass between# sending a request and getting anacknowledgementsyncLimit=5# the directory where the snapshot isstored.  //镜像数据位置dataDir=D:\\data\\zookeeper#日志位置dataLogDir=D:\\logs\\zookeeper# the port at which the clients willconnect  客户端连接的端口clientPort=2181
注意:dataDir  和  dataLogDir 目录不会自动创建,得手动创建才能启动。

然后双击bin文件夹下的zkServer.cmd启动注册中心服务:


启动客户端zkCli.cmd运行查看一下:

这个时候zookeeper已经安装并启动成功了。

这里Zookeeper是在我们本地搭建了一个注册中心,默认端口为2181,即提供的注册中心的具体路劲为:
zookeeper://127.0.0.1:2181

别忘记在工程中添加Zookeeper的jar包:


接下来是Dubbo的配置:
由于Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。所以我们对于Dubbo的配置在spring的bean配置文件中即可以实现。

下面我们就在provider.xml中添加Dubbo的配置:
<?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:aop="http://www.springframework.org/schema/aop"       xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"       xsi:schemaLocation="http://code.alibabatech.com/schema/dubbo           http://code.alibabatech.com/schema/dubbo/dubbo.xsd           http://www.springframework.org/schema/beans            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-2.5.xsd           http://www.springframework.org/schema/aop           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd           http://www.springframework.org/schema/tx            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">               <!-- 提供方应用信息,用于计算依赖关系 -->    <dubbo:application name="arrays-sort-app"  />     <!-- 使用zookeeper注册中心暴露服务地址 -->      <dubbo:registry address="zookeeper://127.0.0.1:2181" />        <!-- 用dubbo协议在20880端口暴露服务 -->    <dubbo:protocol name="dubbo" port="20880" />     <!-- 声明需要暴露的服务接口 -->    <dubbo:service interface="cn.com.dubbo.service.SortService" ref="sortService" />     <!-- 和本地bean一样实现服务 -->    <bean id="sortService" class="cn.com.dubbo.service.impl.SortServiceImpl" /></beans>

如果关于dubbo的配置打叉,出现下面类似的错误:
– cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ‘dubbo:application’.
则需要添加dubbo.xsd文件声明,具体做法如下:
(1)下载一个dubbo.xsd文件,选择windows->preferrence->xml->xmlcatalog 
(2)add->catalog entry  ->file system 选择刚刚下载的文件路径
(3)修改key值和配置文件的http://code.alibabatech.com/schema/dubbo/dubbo.xsd相同
(4)保存,在xml文件右键validate,就可以解决了。
注:dubbo.jar解压后也可以找到dubbo.xsd

然后我们编写一个启动类来启动Spring配置:
package cn.com.dubbo.run;import java.io.IOException;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Provider {public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context =  new ClassPathXmlApplicationContext(new String[] {"provider.xml"});  //远程provider调用 /*ClassPathXmlApplicationContext context =  new ClassPathXmlApplicationContext(new String[] {"http://192.168.1.102/wiki/display/dubbo/provider.xml"});*/     context.start();     System.in.read(); // 按任意键退出}}

至此,我们的服务提供者编写完毕。

二、服务消费者
在MyEclipse中创建一个服务提供者的WebProject,名为Dubbo-Web-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:context="http://www.springframework.org/schema/context"       xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"       xsi:schemaLocation="http://code.alibabatech.com/schema/dubbo           http://code.alibabatech.com/schema/dubbo/dubbo.xsd           http://www.springframework.org/schema/beans            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-2.5.xsd           http://www.springframework.org/schema/aop           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd           http://www.springframework.org/schema/tx            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">              <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->    <dubbo:application name="consumer-of-arraysSort-app"  />     <!-- 使用zookeeper注册中心暴露发现服务地址 -->      <dubbo:registry address="zookeeper://127.0.0.1:2181" />        <!-- 生成远程服务代理,可以和本地bean一样使用sortService -->    <dubbo:reference id="sortService" interface="cn.com.dubbo.service.SortService" /></beans>

然后在消费者的启动类Consumer.java中获取配置,然后调用远程服务:

package cn.com.dubbo.run;import java.io.IOException;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.com.dubbo.service.SortService;public class Consumer {public static void main(String[] args) throws IOException {ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});//远程consumer调用/*ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext(new String[] {"http://192.168.1.102/wiki/display/dubbo/consumer.xml"});*/        context.start();         SortService sortService = (SortService)context.getBean("sortService"); // 获取远程服务代理        int [] arrays = {234,1,45,22,123};        System.out.println("排序前:");        for (int i = 0; i < arrays.length; i++) {System.out.println("arrays["+i+"]="+arrays[i]);}        arrays = sortService.ascendingSort(arrays); // 执行远程方法         //显示调用结果        System.out.println("排序后:");        for (int i = 0; i < arrays.length; i++) {System.out.println("arrays["+i+"]="+arrays[i]);}}}

注意:这里为了简化工程,我们没有使用Maven去关联服务提供方和消费者,所以我们在消费者的src中创建了sortService的接口:

实际上当我们使用了Maven时,通过Maven依赖就可以获取接口信息了。后面我们会给大家介绍使用Maven实现的工程。

至此我们的消费者也编写完毕。

三、测试
首先运行服务提供者的启动类Provider,此时服务提供者已经将服务注册到注册中心Zookeeper中了:


然后启动服务的消费者,此时消费者会在注册中心寻找需要的名为“sortService”服务实现,然后引入,执行相关的服务逻辑,最终的执行结果为:


我们上面实现了一个最简单的服务提供者和服务消费者,应该为大家以后深入学习Dubbo提供了一个思路。
转载请注明出处:http://blog.csdn.net/acmman/article/details/73036356
阅读全文
0 0