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

一、Dubbo出现的背景

  随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进;

  Dubbo(一) -- 初体验_ide

  1.当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。

  2.当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。

  3.接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?

二、Dubbo架构

  Dubbo(一) -- 初体验_ide_02

  1.节点角色说明:

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

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

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

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

     Container: 服务运行容器。

  2.调用关系说明:

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

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

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

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

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

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

三、Dubbo后台部署管理

1.源码下载

     1. 访问www.github.com 网站

     2. 搜索dubbo服务框架

     3. 搜索到git的地址:​​https://github.com/alibaba/dubbo.git​

     4. 通过git客户端clone代码

   5. Dubbo源码导入到Eclipse遇到的问题 ​​

2.dubbo控制台部署

  方式一:

   启动dubbo源码中的dubbo-admin模块:  

   1. 找到dubbo-admin 模块

   2. 修改dubbo.properties的配置,包括注册中心的配置,以下是zookeeper的示例   

    dubbo.registry.address=zookeeper://101.200.129.112:2181;zookeeper://101.200.129.112:2182;zookeeper://101.200.129.112:2183

    dubbo.admin.root.password=root 

    dubbo.admin.guest.password=guest

   3. 部署到web容器中,启动服务即可,启动服务需要很久一段时间。

    Dubbo(一) -- 初体验_初体验_03

     4.服务启动成功后,登录到控制台

       Dubbo(一) -- 初体验_xml_04

  5.查看zookeeper中的节点: ls /,发现产生了dubbo节点

  Dubbo(一) -- 初体验_maven_05

   方式二:

   直接下载dubbot.war,修改修改dubbo.properties的配置(和方式一修改方式一样),放到tomcat中启动, ​

  方式二更加简单方便,而且支持JDK1.8。

四、实例:Hello World

  架构如下所示:

  Dubbo(一) -- 初体验_初体验_06

  1.建立三个maven工程,分别是 provider,api,consumer。

  直接在Eclipse中建立、或者直接使用Maven索架来生成。

  这里在Eclipse中分别新建三个项目,当然也可以不新建三个项目,分为三个模块也可以:

  1).新建DubboApiDemo项目

     2).新建DubboProviderDemo 项目

  3).新建DubboConsumerDemo项目

  2.Api工程,此工程用于提供接口服务

  1)新建 IHelloWorld 接口:


package com.dubbo.demo.api;
/**
* 提供接口服务
* @author xbq
*/
public interface IHelloWorld {
// 接口
public String sayHello(String name);
}


  2) 使用maven工具打包到Maven私服,即Maven install

  成功后,会成成一个jar包,如下图所示:

  Dubbo(一) -- 初体验_初体验_07

 3.Provider工程,生产者

  1)pom.xml


1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4
5 <groupId>com.dubbo.demo.provider</groupId>
6 <artifactId>DubboPrividerDemo</artifactId>
7 <version>0.0.1-SNAPSHOT</version>
8 <packaging>jar</packaging>
9
10 <name>DubboPrividerDemo</name>
11 <url>http://maven.apache.org</url>
12
13 <properties>
14 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15 </properties>
16
17 <dependencies>
18 <dependency>
19 <groupId>junit</groupId>
20 <artifactId>junit</artifactId>
21 <version>4.10</version>
22 <scope>test</scope>
23 </dependency>
24
25 <dependency>    <!-- 刚刚打包的api jar,在这里引用 -->
26 <groupId>com.dubbo.demo.api</groupId>
27 <artifactId>DubboApiDemo</artifactId>
28 <version>0.0.1-SNAPSHOT</version>
29 </dependency>
30 <dependency>
31 <groupId>com.alibaba</groupId>
32 <artifactId>dubbo</artifactId>
33 <version>2.5.3</version>
34 </dependency>
35 <dependency>
36 <groupId>org.slf4j</groupId>
37 <artifactId>slf4j-api</artifactId>
38 <version>1.7.21</version>
39 </dependency>
40 <dependency>
41 <groupId>org.slf4j</groupId>
42 <artifactId>slf4j-log4j12</artifactId>
43 <version>1.7.16</version>
44 </dependency>
45 <dependency>
46 <groupId>org.apache.zookeeper</groupId>
47 <artifactId>zookeeper</artifactId>
48 <version>3.4.6</version>
49 </dependency>
50 <dependency>
51 <groupId>com.github.sgroschupf</groupId>
52 <artifactId>zkclient</artifactId>
53 <version>0.1</version>
54 </dependency>
55 <dependency>
56 <groupId>org.mortbay.jetty</groupId>
57 <artifactId>jetty</artifactId>
58 <version>7.0.0.pre5</version>
59 </dependency>
60 <dependency>
61 <groupId>javax.servlet</groupId>
62 <artifactId>servlet-api</artifactId>
63 <version>2.5</version>
64 </dependency>
65 </dependencies>
66 </project>


  2)provider.xml(自己定义的)


1 <?xml version="1.0" encoding="UTF-8"?>  
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://code.alibabatech.com/schema/dubbo
8 http://code.alibabatech.com/schema/dubbo/dubbo.xsd
9 ">
10 <!-- 提供方应用信息,用于计算依赖关系 -->
11 <dubbo:application name="hello-world-provider"/>
12
13 <!-- 使用zookeeper注册中心暴露服务地址 -->
14 <dubbo:registry address="zookeeper://192.168.242.130:2181?backup=192.168.242.130:2182,192.168.242.130:2183" id="zk"/>
15
16 <!-- 用dubbo协议在20880端口暴露服务 -->
17 <dubbo:protocol name="dubbo" port="20880"/>
18
19 <!-- 具体的bean实现 -->
20 <bean id="helloWorldService" class="com.dubbo.demo.provider.HelloWorldServiceImpl" />
21
22 <!-- 声明需要暴露的服务接口 -->
23 <dubbo:service interface="com.dubbo.demo.api.IHelloWorld" ref="helloWorldService" protocol="dubbo" registry="zk"/>
24 </beans>


   dubbo:registry 标签一些属性的说明:

    1)register是否向此注册中心注册服务,如果设为false,将只订阅,不注册。

    2)check注册中心不存在时,是否报错。

    3)subscribe是否向此注册中心订阅服务,如果设为false,将只注册,不订阅。

    4)timeout注册中心请求超时时间(毫秒)。

    5)address可以Zookeeper集群配置,地址可以多个以分号隔开等。

      dubbo:service标签的一些属性说明:

    1)interface服务接口的路径

    2)ref引用对应的实现类的Bean的ID

    3)registry向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A

    4)register 默认true ,该协议的服务是否注册到注册中心。

  3)实现接口


1 package com.dubbo.demo.provider;
2
3 import com.dubbo.demo.api.IHelloWorld;
4
5 /**
6 * 实现接口
7 * @author xbq
8 * 可以调用 IHelloWorld ,是因为 引入了的 api项目的依赖
9 */
10 public class HelloWorldServiceImpl implements IHelloWorld{
11
12 @Override
13 public String sayHello(String name) {
14 return "Hello World!" + name;
15 }
16
17 }


  4)启动生产者服务


1 package com.dubbo.demo.provider;
2
3 import java.io.IOException;
4 import org.springframework.context.support.ClassPathXmlApplicationContext;
5 /**
6 * 启动生产者服务
7 * @author xbq
8 */
9 public class Main {
10
11 public static void main(String[] args) {
12 // 引用xml文件
13 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
14 context.start();
15
16 try {
17 // 为保证服务一直开着,利用输入流的阻塞来模拟
18 System.in.read();
19 } catch (IOException e) {
20 e.printStackTrace();
21 }
22 }
23 }


 4.Consumer工程,消费者

  1)pom.xml


1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4
5 <groupId>com.dubbo.demo.consumer</groupId>
6 <artifactId>DubboConsumerDemo</artifactId>
7 <version>0.0.1-SNAPSHOT</version>
8 <packaging>jar</packaging>
9
10 <name>DubboConsumerDemo</name>
11 <url>http://maven.apache.org</url>
12
13 <properties>
14 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15 </properties>
16
17 <dependencies>
18 <dependency>
19 <groupId>junit</groupId>
20 <artifactId>junit</artifactId>
21 <version>4.10</version>
22 <scope>test</scope>
23 </dependency>
24 <dependency>
25 <groupId>com.alibaba</groupId>
26 <artifactId>dubbo</artifactId>
27 <version>2.5.3</version>
28 </dependency>
29 <dependency> <!-- 刚刚打包的api jar,在这里引用 -->
30 <groupId>com.dubbo.demo.api</groupId>
31 <artifactId>DubboApiDemo</artifactId>
32 <version>0.0.1-SNAPSHOT</version>
33 </dependency>
34 <dependency>
35 <groupId>org.apache.zookeeper</groupId>
36 <artifactId>zookeeper</artifactId>
37 <version>3.4.6</version>
38 </dependency>
39 <dependency>
40 <groupId>com.github.sgroschupf</groupId>
41 <artifactId>zkclient</artifactId>
42 <version>0.1</version>
43 </dependency>
44 </dependencies>
45 </project>


  2)consumer.xml(自己定义的)


1 <?xml version="1.0" encoding="UTF-8"?>  
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans.xsd
6 http://code.alibabatech.com/schema/dubbo
7 http://code.alibabatech.com/schema/dubbo/dubbo.xsd
8 ">
9 <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
10 <dubbo:application name="hello-world-consumer"/>
11
12 <!-- 使用zookeeper注册中心暴露服务地址 -->
13 <dubbo:registry address="zookeeper://192.168.242.130:2181?backup=192.168.242.130:2182,192.168.242.130:2183" id="zk"/>
14
15 <!-- 用dubbo协议在20880端口暴露服务 -->
16 <dubbo:protocol name="dubbo" port="20881"/>
17
18 <!-- 生成远程服务代理,可以像使用本地bean一样使用demoService -->
19 <dubbo:reference interface="com.dubbo.demo.api.IHelloWorld" id="helloService" protocol="dubbo" registry="zk" />
20 </beans>


      dubbo:reference 的一些属性的说明:  

    1)interface调用的服务接口

    2)check 启动时检查提供者是否存在,true报错,false忽略

    3)registry 从指定注册中心注册获取服务列表,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔

    4)loadbalance 负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用

  3)启动消费者服务


1 package com.dubbo.demo.consumer;
2
3 import java.io.IOException;
4 import org.springframework.context.support.ClassPathXmlApplicationContext;
5 import com.dubbo.demo.api.IHelloWorld;
6
7 /**
8 * 启动消费者服务
9 * @author xbq
10 */
11 public class Main {
12
13 public static void main(String[] args) {
14 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
15 context.start();
16
17 IHelloWorld helloWorld = (IHelloWorld)context.getBean("helloService");
18 String str = helloWorld.sayHello("Joe");
19 System.out.println(str);
20
21 try {
22 // 为保证服务一直开着,利用输入流的阻塞来模拟
23 System.in.read();
24 } catch (IOException e) {
25 e.printStackTrace();
26 }
27 }
28 }


五、启动生产者和消费者

  1.启动生产者,执行生产者的 main方法

  2.查看dubbo控制台开启的服务,可以看到发布的生产者是正常状态,下图:

  Dubbo(一) -- 初体验_Dubbo_08

  3.查看zookeeper中dubbo节点下的节点: ls /dubbo

  Dubbo(一) -- 初体验_初体验_09

  4.启动消费者,执行消费者的main方法

  5.查看Eclipse控制台打印的消息,则说明接口调用成功:

  Dubbo(一) -- 初体验_maven_10

  6.查看dubbo控制台中的应用,既有生产者,又有消费者,如下图:

  Dubbo(一) -- 初体验_Dubbo_11