分布式服务框架 dubbodubbox 入门示例

    xiaoxiao2025-08-04  16

    http://www.cnblogs.com/yjmyzz/p/dubbox-demo.html

    dubbo是一个分布式的服务架构,可直接用于生产环境作为SOA服务框架。

    官网首页:http://dubbo.io/ ,官方用户指南 http://dubbo.io/User+Guide-zh.htm上面的几张图画得不错,完全可以当做SOA架构的学习资料

    淘宝将这个项目开源出来以后,得到了不少同行的支持,包括:

    当当网的扩展版本dubbox :https://github.com/dangdangdotcom/dubbox

    京东的扩展版本jd-hydra: http://www.oschina.net/p/jd-hydra

    不过,略有遗憾的是,据说在淘宝内部,dubbo由于跟淘宝另一个类似的框架HSF(非开源)有竞争关系,导致dubbo团队已经解散(参见http://www.oschina.net/news/55059/druid-1-0-9 中的评论),反到是当当网的扩展版本仍在持续发展,墙内开花墙外香。

    不管如何,能在阿里、当当、京东这些大型网站正式使用的框架,总不至于差到哪里去。

    本文下面的示例均基于当当的dubbox版本,由于dubbox并没向maven提交编译后的jar包,所以只能从github clone代码到本地编译得到jar包。

     

    编译及测试步骤:(以下步骤全在windows环境中完成)

    1. 本机先安装github on Windows的客户端,将在path路径中,把git.exe加进去

    2. 命令行下 git clone https://github.com/dangdangdotcom/dubbox 把代码拉到本地

    3. mvn install -Dmaven.test.skip=true 跳过测试编译

    4. 在本机安装一个zookeeper,参考zoo.cfg如下:

    tickTime=2000 initLimit=10 syncLimit=5 dataDir=D:/java/zookeeper-3.4.6/data dataLogDir=D:/java/zookeeper-3.4.6/log clientPort=2181 server.1=localhost:2287:3387

    然后输入 bin/zkServer.cmd 启用zookeeper

    5. intellij Idea中导入源码

    6. 运行 \dubbox\dubbo-demo\dubbo-demo-provider\src\test\java\com\alibaba\dubbo\demo\provider\DemoProvider.java 

    把服务提供方跑起来,成功后,可以在ZK里,用 ls / 看下,会发现zk里多出了一个dubbo的节点,所有服务全注册在这里了

    7. 运行\dubbox\dubbo-demo\dubbo-demo-consumer\src\test\java\com\alibaba\dubbo\demo\consumer\DemoConsumer.java

    服务消费方调用测试,可以看console里的输出

    8. 运行\dubbox\dubbo-demo\dubbo-demo-consumer\src\test\java\com\alibaba\dubbo\demo\consumer\RestClient.java

    跑一下rest调用

    9. 浏览器访问 http://localhost:8888/services/users/100.xml 或 http://localhost:8888/services/users/100.json

     

    dubbox官方的示例,虽然已经很简单了,但是对于初次接触的人来讲,仍然略显复杂,下面的代码在其基础上简化了一下:

    一、先定义服务接口及传输对象DTO

    项目结构如下

    代码:

    User.java

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package  yjmyzz.dubbo.demo.api; import  org.codehaus.jackson.annotate.JsonProperty; import  javax.validation.constraints.Min; import  javax.validation.constraints.NotNull; import  javax.validation.constraints.Size; import  javax.xml.bind.annotation.XmlAccessType; import  javax.xml.bind.annotation.XmlAccessorType; import  javax.xml.bind.annotation.XmlElement; import  javax.xml.bind.annotation.XmlRootElement; import  java.io.Serializable;   @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) public  class  User  implements  Serializable {        @NotNull      @Min (1L)      private  Long id;        @JsonProperty ( "username" )      @XmlElement (name =  "username" )      @NotNull      @Size (min =  6 , max =  50 )      private  String name;        public  User() {      }        public  User(Long id, String name) {          this .id = id;          this .name = name;      }        public  Long getId() {          return  id;      }        public  void  setId(Long id) {          this .id = id;      }        public  String getName() {          return  name;      }        public  void  setName(String name) {          this .name = name;      }        @Override      public  String toString() {          return  "User ("  +                  "id="  + id +                  ", name='"  + name + '\ ''  +                  ')' ;      } }

    UserService.java

    1 2 3 4 5 package  yjmyzz.dubbo.demo.api;   public  interface  UserService {      User getUser(Long id); }

    UserRestService.java

    1 2 3 4 5 6 7 package  yjmyzz.dubbo.demo.api;   import  javax.validation.constraints.Min;   public  interface  UserRestService {      User getUser( @Min (value = 1L, message =  "User ID must be greater than 1" ) Long id); }

    pom.xml

    1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 6 <modelVersion>4.0.0</modelVersion> 7 8 <groupId>com.cnblogs.yjmyzz</groupId> 9 <artifactId>dubbo-hello-api</artifactId> 10 <version>0.1</version> 11 12 <dependencies> 13 14 <dependency> 15 <groupId>com.alibaba</groupId> 16 <artifactId>dubbo</artifactId> 17 <version>2.8.4</version> 18 </dependency> 19 20 <dependency> 21 <groupId>javax.validation</groupId> 22 <artifactId>validation-api</artifactId> 23 <version>1.0.0.GA</version> 24 </dependency> 25 26 <dependency> 27 <groupId>javax.annotation</groupId> 28 <artifactId>javax.annotation-api</artifactId> 29 <version>1.2</version> 30 </dependency> 31 32 <dependency> 33 <groupId>org.codehaus.jackson</groupId> 34 <artifactId>jackson-mapper-asl</artifactId> 35 <version>1.9.12</version> 36 </dependency> 37 38 </dependencies> 39 </project>

     

    二、定义服务生产者(即:服务接口的实现方)

    UserServiceImpl.java

    1 2 3 4 5 6 7 8 9 10 11 package  yjmyzz.dubbo.demo.provider;   import  yjmyzz.dubbo.demo.api.User; import  yjmyzz.dubbo.demo.api.UserService;   public  class  UserServiceImpl  implements  UserService {        public  User getUser(Long id) {          return  new  User(id,  "username"  + id);      } }

    UserRestServiceImpl.java

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package  yjmyzz.dubbo.demo.provider;   import  com.alibaba.dubbo.rpc.RpcContext; import  com.alibaba.dubbo.rpc.protocol.rest.support.ContentType; import  yjmyzz.dubbo.demo.api.User; import  yjmyzz.dubbo.demo.api.UserRestService; import  yjmyzz.dubbo.demo.api.UserService; import  javax.servlet.http.HttpServletRequest; import  javax.servlet.http.HttpServletResponse; import  javax.ws.rs.*; import  javax.ws.rs.core.MediaType;   @Path ( "users" ) @Consumes ({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) @Produces ({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8}) public  class  UserRestServiceImpl  implements  UserRestService {        private  UserService userService;        public  void  setUserService(UserService userService) {          this .userService = userService;      }        @GET      @Path ( "{id : \\d+}" )      public  User getUser( @PathParam ( "id" ) Long id) {          if  (RpcContext.getContext().getRequest(HttpServletRequest. class ) !=  null ) {              System.out.println( "Client IP address from RpcContext: "  + RpcContext.getContext().getRequest(HttpServletRequest. class ).getRemoteAddr());          }          if  (RpcContext.getContext().getResponse(HttpServletResponse. class ) !=  null ) {              System.out.println( "Response object from RpcContext: "  + RpcContext.getContext().getResponse(HttpServletResponse. class ));          }          return  userService.getUser(id);      } }

    DemoProvider.java

    1 2 3 4 5 6 7 8 9 10 11 12 package  yjmyzz.dubbo.demo.provider; import  org.springframework.context.support.ClassPathXmlApplicationContext; import  java.io.IOException;   public  class  DemoProvider {      public  static  void  main(String[] args)  throws  IOException {          ClassPathXmlApplicationContext context =  new  ClassPathXmlApplicationContext( "classpath*:META-INF/spring/*.xml" );          context.start();          System.out.println( "服务已经启动..." );          System.in.read();      } }

    配置文件:resources\META-INF\spring\dubbo-demo-provider.xml

    1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <beans xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 7 http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> 8 9 <dubbo:application name="demo-provider" owner="programmer" organization="dubbox"/> 10 11 <dubbo:registry address="zookeeper://127.0.0.1:2181"/> 12 13 <dubbo:protocol name="dubbo" serialization="kryo" optimizer="yjmyzz.dubbo.demo.api.SerializationOptimizerImpl"/> 14 15 <!-- use tomcat server --> 16 <dubbo:protocol name="rest" port="8888" threads="500" contextpath="services" server="tomcat" accepts="500" 17 extension="com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter"/> 18 19 20 <dubbo:service interface="yjmyzz.dubbo.demo.api.UserService" ref="userService" protocol="dubbo" /> 21 22 <dubbo:service interface="yjmyzz.dubbo.demo.api.UserRestService" ref="userRestService" protocol="rest" validation="true"/> 23 24 <bean id="userService" class="yjmyzz.dubbo.demo.provider.UserServiceImpl"/> 25 26 <bean id="userRestService" class="yjmyzz.dubbo.demo.provider.UserRestServiceImpl"> 27 <property name="userService" ref="userService"/> 28 </bean> 29 30 31 </beans>

    pom.xml

      View Code

    测试时,运行DemoProvider中的main方法即可启动服务,所有服务注册在ZooKeeper,层次结构类似下面这样:

    /dubbo /dubbo/yjmyzz.dubbo.demo.api.UserRestService /dubbo/yjmyzz.dubbo.demo.api.UserRestService/providers /dubbo/yjmyzz.dubbo.demo.api.UserRestService/configurators /dubbo/yjmyzz.dubbo.demo.api.UserService /dubbo/yjmyzz.dubbo.demo.api.UserService/providers /dubbo/yjmyzz.dubbo.demo.api.UserService/configurators

     

    三、服务消费方

     

    DemoConsumer.java

    + View Code

    配置文件:resources\META-INF\spring\dubbo-hello-consumer.xml

      View Code

    pom.xml

      View Code

    其它注意事项:

    dubbo构架中,zk充着“服务注册中心”的角色,所以生产者与消费者的xml配置文件中,都要配置zk地址,如果zk采用集群部署时,配置写法参考下面这样:

    <dubbo:registry address="zookeeper://172.28.*.102:2181?backup=172.28.*.102:2182,172.28.*.102:2183"/>

     

    dubbo还有一个管理界面,用于服务治理,包括启用/禁用服务,设置服务的路由规则(即:A地址的Consumer直接调用B机器的Provider,而不是由负载均衡算法分配)等等。

    使用方法:将dubbo-admin这个项目编译成war包后,部署到jetty或其它兼容web server即可(当然要修改\WEB-INF\dubbo.properties里zk的地址)

    部署完成后,访问管理界面时,默认用户名,密码均是root。 

    另外dubbo-monitor项目用于性能监控,结合监控产生的数据,再套上一些图表展示的框架,可以用图表方式直观展示各种指标。

    注:官网给出的dubbo-admin采用的webx架构有点老,而且除了淘宝之外,几乎没人在用,dubbo-monitor-simple界面也比较古朴,所以社区也人对其做了扩展,详情参考另一篇博客dubbox 的各种管理和监管

    2016-02-25:dubbox依赖的spring虽然升级成3.x了,但版本还是有点低,spring都已经4.x了,为了方便我fork了一份,升级成spring 4.x 同时增加了log4j2的日志组件支持,详情见:dubbox升级spring到4.x及添加log4j2支持

     

    参考文章:

    http://shiyanjun.cn/archives/341.html

    http://blog.csdn.net/wilsonke/article/details/39896595

    http://www.dataguru.cn/thread-464197-1-1.html

    http://www.iteye.com/magazines/103

    http://dangdangdotcom.github.io/dubbox/rest.html

    http://dangdangdotcom.github.io/dubbox/demo.html

    http://blog.csdn.net/hzzhoushaoyu/article/details/43273099

    转载请注明原文地址: https://ju.6miu.com/read-1301401.html
    最新回复(0)