1.   概述

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。主要核心部件

Remoting: 网络通信框架,实现了sync-over-async 和 request-response 消息机制.

RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能

Registry: 服务目录框架用于服务的注册和服务事件发布和订阅。

Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。

dubbo架构图如下所示:

dubbo使用实例 dubbo简单实例_spring

节点角色说明:

Provider: 暴露服务的服务提供方。

Consumer: 调用远程服务的服务消费方。

Registry: 服务注册与发现的注册中心。

Monitor: 统计服务的调用次调和调用时间的监控中心。

Container: 服务运行容器。

调用关系说明:

0 服务容器负责启动,加载,运行服务提供者。

1. 服务提供者在启动时,向注册中心注册自己提供的服务。

2. 服务消费者在启动时,向注册中心订阅自己所需的服务。

3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。




2.   实例

2.1 pom.xml

首先maven项目增加dubbo的jar依赖,因为要用到zookeeper注册中心,也要依赖但是要去掉自带的log4j。

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>test</groupId>  <artifactId>test</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <spring.version>3.1.4.RELEASE</spring.version>    <slf4j.version>1.6.6</slf4j.version>  </properties>  <dependencies>    <!-- dubbo  -->    <dependency>      <groupId>com.alibaba</groupId>      <artifactId>dubbo</artifactId>      <version>2.5.3</version>    </dependency>    <!-- zookeeper  -->    <dependency>      <groupId>org.apache.zookeeper</groupId>      <artifactId>zookeeper</artifactId>      <version>3.4.6</version>      <exclusions>        <exclusion>          <groupId>log4j</groupId>          <artifactId>log4j</artifactId>        </exclusion>      </exclusions>    </dependency>    <!-- Spring -->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-aop</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-asm</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-expression</artifactId>      <version>${spring.version}</version>    </dependency>    <!-- log -->    <dependency>      <groupId>log4j</groupId>      <artifactId>log4j</artifactId>      <version>1.2.16</version>    </dependency>  </dependencies></project>

因为要增加zookeeper的注册管理,所以如果有可用的zookeeper就用可用的zookeeper。本实例使用的zk地址是192.168.4.114:2181

2.2 dubbo-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://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     http://code.alibabatech.com/schema/dubbo/dubbo.xsd">  <!-- 提供方应用信息,用于计算依赖关系 -->  <dubbo:application name = "hello-world-app-provider" />  <!--zookeeper注册中心 -->  <dubbo:registry protocol="zookeeper" address="192.168.4.114:2181" />  <!-- 用dubbo协议在20880端口暴露服务 -->  <dubbo:protocol name="dubbo" port="20880" />  <!-- 声明需要暴露的服务接口 -->  <dubbo:service interface="com.mt.test.DemoService" ref="demoProvideService"/>  <!-- 具体的实现bean -->  <bean id="demoProvideService" class="com.mt.test.DemoServiceImpl" /></beans>

2.3 dubbo-consumer.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://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     http://code.alibabatech.com/schema/dubbo/dubbo.xsd">  <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->  <dubbo:application name="hello-world-app-consumer"/>  <!-- 使用zookeeper注册中心暴露服务地址 -->  <dubbo:registry protocol="zookeeper" address="192.168.4.114:2181"/>  <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->  <dubbo:reference id="demoConsumeService" interface="com.mt.test.DemoService"/></beans>

2.4 DemoService.java

package com.mt.test;import java.util.List;public interface DemoService {
    public String sayHello(String name);    public List getUsers();
}
package com.mt.test;import java.util.List;public interface DemoService {
    public String sayHello(String name);    public List getUsers();
}

2.5 DemoServiceImpl.java

package com.mt.test;import java.util.ArrayList;import java.util.List;public class DemoServiceImpl implements DemoService{
    @Override
    public String sayHello(String name) {  return "Hello " + name;
    }    @Override
    public List getUsers() {  List list = new ArrayList();  User u1 = new User();  u1.setName("jack");  u1.setAge(20);  u1.setSex("男");  User u2 = new User();  u2.setName("tom");  u2.setAge(21);  u2.setSex("女");  User u3 = new User();  u3.setName("rose");  u3.setAge(19);  u3.setSex("女");  list.add(u1);  list.add(u2);  list.add(u3);  return list;
    }
}
package com.mt.test;import java.util.ArrayList;import java.util.List;public class DemoServiceImpl implements DemoService{
    @Override
    public String sayHello(String name) {  return "Hello " + name;
    }    @Override
    public List getUsers() {  List list = new ArrayList();  User u1 = new User();  u1.setName("jack");  u1.setAge(20);  u1.setSex("男");  User u2 = new User();  u2.setName("tom");  u2.setAge(21);  u2.setSex("女");  User u3 = new User();  u3.setName("rose");  u3.setAge(19);  u3.setSex("女");  list.add(u1);  list.add(u2);  list.add(u3);  return list;
    }
}

2.6 LuncherProvider.java

package com.mt.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.ApplicationContext;public class LuncherProvider {  public static void main(String[] args) throws Exception {    LuncherProvider luncher = new LuncherProvider();    luncher.start();    System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟  }  public void start() {    String configLocation = "spring/dubbo-provider.xml";    ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);    String[] names = context.getBeanDefinitionNames();    System.out.print("Beans:");    for (String string : names)      System.out.print(string + ",");    System.out.println();  }
}
package com.mt.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.ApplicationContext;public class LuncherProvider {  public static void main(String[] args) throws Exception {    LuncherProvider luncher = new LuncherProvider();    luncher.start();    System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟  }  public void start() {    String configLocation = "spring/dubbo-provider.xml";    ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);    String[] names = context.getBeanDefinitionNames();    System.out.print("Beans:");    for (String string : names)      System.out.print(string + ",");    System.out.println();  }
}

2.7 LuncherConsumer.java

package com.mt.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class LuncherConsumer {  public static void main(String[] args) throws Exception {    LuncherConsumer luncher = new LuncherConsumer();    luncher.start();  }  void start() {    String configLocation = "spring/dubbo-consumer.xml";    ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);    String[] names = context.getBeanDefinitionNames();    System.out.print("Beans:");    for (String string : names) {      System.out.print(string);      System.out.print(",");    }    System.out.println();    DemoService ds = (DemoService) context.getBean("demoConsumeService");    System.out.println(ds.sayHello("hehe"));    System.out.println(ds.getUsers());  }
}



2.8 User.java
package com.mt.test;import java.io.Serializable;//必须实现Serializable接口public class User implements Serializable {  private static final long serialVersionUID = -2814022769568306965L;  private String name;  private Integer age;  private String sex;  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public Integer getAge() {    return age;  }  public void setAge(Integer age) {    this.age = age;  }  public String getSex() {    return sex;  }  public void setSex(String sex) {    this.sex = sex;  }  @Override  public String toString() {    return "User{" +        "name='" + name + '\'' +        ", age=" + age +        ", sex='" + sex + '\'' +        '}';  }
}<strong>
</strong>
package com.mt.test;import java.io.Serializable;//必须实现Serializable接口public class User implements Serializable {  private static final long serialVersionUID = -2814022769568306965L;  private String name;  private Integer age;  private String sex;  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public Integer getAge() {    return age;  }  public void setAge(Integer age) {    this.age = age;  }  public String getSex() {    return sex;  }  public void setSex(String sex) {    this.sex = sex;  }  @Override  public String toString() {    return "User{" +        "name='" + name + '\'' +        ", age=" + age +        ", sex='" + sex + '\'' +        '}';  }
}<strong>
</strong>

运行结果:

(1)provider:

Beans:hello-world-app-provider,com.alibaba.dubbo.config.RegistryConfig,dubbo,com.mt.test.DemoService,demoProvideService,

(2)consumer:

Beans:hello-world-app-consumer,com.alibaba.dubbo.config.RegistryConfig,demoConsumeService,

Hello hehe

[User{name='jack', age=20, sex='男'}, User{name='tom', age=21, sex='女'}, User{name='rose', age=19, sex='女'}]