Dubbo使用指南

来源:互联网 发布:软文软件 编辑:程序博客网 时间:2024/06/05 10:02

Dubbo介绍

简单的来说,Dubbo是一个服务治理的框架,集中管理了RPC调用,并提供多种访问策略和负载来满足应用系统之间的相互调用。

Dubbo架构

  • Provider: 暴露服务的服务提供方。
  • Consumer: 调用远程服务的服务消费方。
  • Registry: 服务注册与发现的注册中心。
  • Monitor: 统计服务的调用次调和调用时间的监控中心。
  • Container: 服务运行容器。

注意:Registry是一个很轻的东西,实际上Dubbo只是在注册中心共享了服务的相关信息,Dubbo的主体是Provider和Consumer,这两者都是属于应用范围内的。Monitor也是很轻的模块,需要有监控服务在Registry进行了注册应用才能正常使用监控,监控宕掉不影响服务。

协议介绍

Dubbo本身提供了多种协议的支持,我们系统内广泛使用的hession协议也是其中之一。

  • dubbo://
    Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
    Dubbo缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
  • rmi://
    RMI协议采用JDK标准的java.rmi.*实现,采用阻塞式短连接和JDK标准序列化方式。
  • hessian://
    Hessian协议用于集成Hessian的服务,Hessian底层采用Http通讯,采用Servlet暴露服务,Dubbo缺省内嵌Jetty作为服务器实现。
  • http://
     基于http的短连接协议,基本不会去使用了。
  • webservice://
     webservice
  • redis://
    Redis是一个高效的KV存储服务器
  • memcached://
    Memcached是一个高效的KV缓存服务器
  • Thrift://
    Thrift是Facebook捐给Apache的一个RPC框架

注册中心介绍

Dubbo也支持多种类型的注册中心,分别有:

  • Multicast
    基于组 播实现的注册中心,互相发现
  • Zookeeper
    Zookeeper是Apacahe Hadoop的子项目,是一个树型的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。
  • Redis
    Redis是一个高效的KV存储服务器
  • Simple
    注册中心本身就是一个普通的Dubbo服务,可以减少第三方依赖,使整体通讯方式一致。

完整介绍

目前我们系统使用的协议是Dubbo协议,注册中心是Zookeeper,这两者可以仔细去了解一下,下面给出Dubbo的官方文档地址:

User+Guide-zh

使用示例

下面我会给出一个完整的基于Dubbo服务的调用代码示例,需要注意的点我在注释上说明。

 

接口定义

  1. 定义Maven接口项目

    pom.xml
    <project xmlns="<a href="http://maven.apache.org/POM/4.0.0" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://maven.apache.org/POM/4.0.0" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 <a href="http://maven.apache.org/xsd/maven-4.0.0.xsd" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.lefu</groupId>
      <artifactId>Iexample</artifactId>
      <version>1.0</version>
    </project>
  2. 定义接口
     

    ISayHello.java
    1
    2
    3
    4
    package com.lefu.iexample;
    public interface ISayHello {
        public String sayHelloWaitAnswer(String s);
    }

服务提供方(Provider)

 

  1. 定义Maven服务端项目,并提供相应依赖(Iexample,dubbo,zookeeper)。

    pom.xml
    <project xmlns="<a href="http://maven.apache.org/POM/4.0.0" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://maven.apache.org/POM/4.0.0" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 <a href="http://maven.apache.org/xsd/maven-4.0.0.xsd" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.lefu</groupId>
      <artifactId>example-server</artifactId>
      <version>1.0</version>
      <dependencies>
        <dependency>
            <groupId>com.lefu</groupId>
            <artifactId>Iexample</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
      </dependencies>
    </project>

    Dubbo对外的依赖是需要什么就增加什么的jar依赖,我们需要到的依赖一个是dubbo自身的依赖,另外一个是注册中心zookeeper的依赖,需要提供zookeeper的连接客户端,再者就是需要实现的接口jar了。

  2. 实现接口的服务类

    SayHelloImpl.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package com.lefu.example.server.rpc;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.atomic.AtomicInteger;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import com.lefu.iexample.ISayHello;
    public class SayHelloImpl implements ISayHello {
        private final Logger log = LoggerFactory.getLogger(getClass());
        private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        private String template = "[%s] - %d.";
        private AtomicInteger count = new AtomicInteger();
     
        public String sayHelloWaitAnswer(String s) {
            log.info("Receive message {} from client", s);
            Date now = new Date();
            String answerTime = dateFormat.format(now);
            return String.format(template, answerTime, count.getAndIncrement());
        }
    }
  3. 准备Spring的配置文件,因为这个示例是基于Spring Context实现的。

    applicationContext.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="<a href="http://www.springframework.org/schema/beans" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://www.springframework.org/schema/beans"
        xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="<a href="http://code.alibabatech.com/schema/dubbo" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        <a href="http://code.alibabatech.com/schema/dubbo/dubbo.xsd" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
     
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="say-hello-server"  />
        <!-- Group属性指定dubbo在zookeeper中以什么路径开始,group之间相对隔离,如果不写,则所有服务都从根/开始 -->
        <dubbo:registry address="zookeeper://10.10.110.58:2181" group="dubbo" client="zkclient"/>
        <!-- 如果注册中心里有监控服务进行注册,则可以开启下面的配置,监控会从注册中心寻找监控服务端,通过protocol="registry"指定 -->
        <dubbo:monitor protocol="registry"/>
        <!-- 服务提供方对外提供的连接数控制,connections代表与每一个消费者建立多少连接,accepts代表本服务提供方总共对外提供多少连接 -->
        <dubbo:provider connections="5" accepts="8"/>
     
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880"/>
     
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="com.lefu.iexample.ISayHello" ref="simpleServer"/>
     
        <!-- 和本地bean一样实现服务 -->
        <bean id="simpleServer" class="com.lefu.example.server.rpc.SayHelloImpl" />
     
    </beans>
  4. 提供主程序入口

    Main.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package com.lefu.example.server;
    import java.io.IOException;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class Main {
        /**
         * @param args
         */
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            context.start();
            try {
                System.in.read();
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

服务消费方(Consumer)

  1. 定义Maven项目,提供消费者的依赖

    pom.xml
    <project xmlns="<a href="http://maven.apache.org/POM/4.0.0" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://maven.apache.org/POM/4.0.0" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 <a href="http://maven.apache.org/xsd/maven-4.0.0.xsd" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.lefu</groupId>
      <artifactId>example-client</artifactId>
      <version>1.0</version>
      <dependencies>
        <dependency>
            <groupId>com.lefu</groupId>
            <artifactId>Iexample</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
      </dependencies>
    </project>

    消费者的依赖也是根据服务而定,基本上与服务提供者相同,只是不需要实现接口,只需要调用即可。

  2. 提供Spring配置文件

    applicationContext.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="<a href="http://www.springframework.org/schema/beans" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://www.springframework.org/schema/beans"
        xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="<a href="http://code.alibabatech.com/schema/dubbo" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        <a href="http://code.alibabatech.com/schema/dubbo/dubbo.xsd" "="" style="color: rgb(50, 108, 166); text-decoration-line: none; border-radius: 0px !important; background: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 20px !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: auto !important;">http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
     
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="say-hello-client"  />
     
        <dubbo:registry address="zookeeper://10.10.110.58:2181" group="dubbo" client="zkclient"/>
        <!-- 与服务端相同,有监控服务注册就可以开启 -->
        <!-- <dubbo:monitor protocol="registry"/> -->
        <!-- 定义引用的服务 -->
        <dubbo:reference id="simpleClient" interface="com.lefu.iexample.ISayHello"/>
     
    </beans>
  3. 提供Main入口调用服务

    Main.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 com.lefu.example.client;
    import java.io.IOException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import com.lefu.iexample.ISayHello;
    public class Main {
        private final Logger log = LoggerFactory.getLogger(getClass());
        private ClassPathXmlApplicationContext context;
     
        public Main() {
            context = new ClassPathXmlApplicationContext("applicationContext.xml");
            context.start();
        }
     
        public void start() {
            ISayHello simpleClient  = (ISayHello) context.getBean("simpleClient");
            for(int i = 0; i < 100; i++){
                String answer = simpleClient.sayHelloWaitAnswer("HOHO " + i);
                log.info("Answer from server {}", answer);
            }
        }
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            new Main().start();
            try {
                System.in.read();
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    这样启动后就能正常访问服务了。

F&Q

  1. Dubbo里很多标签在应用环境内都是唯一的,只有<dubbo:service>和<dubbo:reference>是多份的,但是需要注意,这两个标签的底层实现都是非常重的,所以尽量保证使用单例模式。
  2. 有时候在应用启动时可能使用的服务还没有注册,这个时候默认启动会报错,可以在reference标签添加check="false"来关闭启动的检测,只在真正发起调用时去检查。
  3. Dubbo中存在很多的配置,从上往下有很多继承关系,所以默认需要的配置很少,但是越小范围的配置越高,在小范围内没有时默认采用上一级的配置,application,registry,provider,consumer都是教高层的配置,具体的配置在Dubbo官方文档中有详细的说明,大家可以去自己研究一下。
  4. 出现java.io.IOException: Can not lock the registry cache file /home/deployer/.dubbo/dubbo-registry-xxxxx.cache, ignore and retry later的问题解决方法
    这个问题的出现是因为dubbo在用户目录下使用一个文件来缓存注册中心的服务提供者的信息,那么在使用前会加上文件锁,所以再一次使用这个文件是获取锁就会失败,解决的方式是:
    1:确认应用内只有一个<registry>标签,不同文件的情况下,也只能有一个
    2:在<registry>标签内指定一个文件,使用file属性 <registry address="xxx" file="xxx"/>
    这样就能解决这个问题了 

 

原创粉丝点击