dubbo入门--原理、应用、实例

2,909 阅读10分钟
原文链接: mp.weixin.qq.com

要说dubbo就先了解一下RPC:

概念:

RPC(Remote Procedure Call):远程过程调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。它使得在本地调用远端的程序就好像是在调用本地的程序一样。

RPC协议假定某些传输协议是存在的,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型(七层模型)中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

RPC调用过程:

  1. 客户端以本地服务方式调用服务

  2. client stub作为代理,然后处理调用与调用的参数

  3. client stub发送调用到远端的系统,通过TCP或UDP

  4. server stub处理client stub发过来的调用与参数

  5. server stub调用真正提供的服务

  6. server stub处理回复,然后发送给客户端

Dubbo

1、什么是dubbo :

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

   soa:“面向服务架构”,它提供的是一种架构风格和理念,而并非是一种技术或者产品。SOA提倡将不同应用程序的业务功能封装成“服务”并宿主起来,通常以接口和契约的形式暴露并提供给外界应用访问(通过交换消息),达到不同系统可重用的目的。

2、Dubbo的技术架构图如下:

我们解释一下这个架构图:

  • a、Consumer服务消费者(花钱的),Provider服务提供者(给钱的),Container服务容器(领钱的地方)。

  • b、服务提供者先启动,然后注册服务(registry)。

  • c、Monitor这是一个监控,图中虚线表明Consumer 和Provider通过异步的方式发送消息至Monitor,Consumer和Provider会将信息存放在本地磁盘,平均1min会发送一次信息。Monitor在整个架构中是可选的。

  • d、Monitor功能需要单独配置,不配置或者配置以后,Monitor挂掉并不会影响服务的调用。

3、Dubbo服务消费者调用过程

上图是服务消费的主过程:

首先通过 ReferenceConfig 类的 private void init() 方法会先检查初始化所有的配置信息后,调用 private T createProxy(Map map) 创建代理,消费者最终得到的是服务的代理, 在 createProxy 接着调用 Protocol 接口实现的 Invoker refer(Class type, URL url) 方法生成 Invoker 实例(如上图中的红色部分),这是服务消费的关键。接下来把 Invoker 通过 ProxyFactory 代理工厂转换为客户端需要的接口(如: HelloWorld ),创建服务代理并返回。

消费端的初始化过程

  • 1、把服务引用的信息封装成URL并注册到zk注册中心;

  • 2、监听注册中心的服务的上下线;

  • 3、连接服务提供端,创建NettyClient对象;

  • 4、将这些信息包装成DubboInvoker消费端的调用链,创建消费端Invoker实例的服务代理并返回;

消费端的服务引用过程

  • 1、经过负载均衡策略,调用提供者;

  • 2、选择其中一个服务的URL与提供者netty建立连接,使用ProxyFactory 创建远程通信,或者本地通信的,Invoker发到netty服务端;

  • 3、服务器端接收到该Invoker信息后,找到对应的本地Invoker,处理Invocation请求;

  • 4、获取异步,或同步处理结果;

    • 异步 不需要返回值:直接调用ExchangeClient.send()方法;

    • 同步 需要返回值:使用ExchangeClient.request()方法,返回一个ResponseFuture,一直阻塞到服务端返回响应结果;

最简单的dubbo实例

服务提供方和消费方都需要的包(这里我新建的maven工程为pom工程,将共同的项目依赖写到pom.xml中)

总的项目结构为

pom.xml文件内容为

  1. <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">

  2.  <modelVersion>4.0.0</modelVersion>

  3.  <groupId>com.test</groupId>

  4.  <artifactId>dubbo-demo</artifactId>

  5.  <version>0.0.1-SNAPSHOT</version>

  6.  <packaging>pom</packaging>

  7.   <properties>

  8.        <motan.version>0.3.0</motan.version>

  9.        <!-- 在阿里巴巴内部广泛使用的GA版本为:2.4.9,强烈推荐此版本 -->

  10.        <dubbo.version>2.5.3</dubbo.version>

  11.        <dubbox.version>2.8.4</dubbox.version>

  12.        <spring.version>4.3.6.RELEASE</spring.version>

  13.        <java.version>1.7</java.version>

  14.        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

  15.    </properties>

  16.    <dependencies>

  17.      <dependency>

  18.            <groupId>com.alibaba</groupId>

  19.            <artifactId>dubbo</artifactId>

  20.            <version>2.5.3</version>

  21.            <exclusions>

  22.                <exclusion>

  23.                    <groupId>org.springframework</groupId>

  24.                    <artifactId>spring</artifactId>

  25.                </exclusion>

  26.            </exclusions>

  27.        </dependency>

  28.        <dependency>

  29.            <groupId>com.github.sgroschupf</groupId>

  30.            <artifactId>zkclient</artifactId>

  31.            <version>0.1</version>

  32.        </dependency>

  33.        <!-- spring相关 -->

  34.        <dependency>

  35.            <groupId>org.springframework</groupId>

  36.            <artifactId>spring-core</artifactId>

  37.            <version>${spring.version}</version>

  38.        </dependency>

  39.        <dependency>

  40.            <groupId>org.springframework</groupId>

  41.            <artifactId>spring-beans</artifactId>

  42.            <version>${spring.version}</version>

  43.        </dependency>

  44.        <dependency>

  45.            <groupId>org.springframework</groupId>

  46.            <artifactId>spring-context</artifactId>

  47.            <version>${spring.version}</version>

  48.        </dependency>

  49.        <dependency>

  50.            <groupId>org.springframework</groupId>

  51.            <artifactId>spring-jdbc</artifactId>

  52.            <version>${spring.version}</version>

  53.        </dependency>

  54.        <dependency>

  55.            <groupId>org.springframework</groupId>

  56.            <artifactId>spring-web</artifactId>

  57.            <version>${spring.version}</version>

  58.        </dependency>

  59.        <dependency>

  60.            <groupId>org.springframework</groupId>

  61.            <artifactId>spring-webmvc</artifactId>

  62.            <version>${spring.version}</version>

  63.        </dependency>

  64.        <dependency>

  65.            <groupId>org.springframework</groupId>

  66.            <artifactId>spring-aop</artifactId>

  67.            <version>${spring.version}</version>

  68.        </dependency>

  69.        <dependency>

  70.            <groupId>org.springframework</groupId>

  71.            <artifactId>spring-tx</artifactId>

  72.            <version>${spring.version}</version>

  73.        </dependency>

  74.        <dependency>

  75.            <groupId>org.springframework</groupId>

  76.            <artifactId>spring-orm</artifactId>

  77.            <version>${spring.version}</version>

  78.        </dependency>

  79.        <dependency>

  80.            <groupId>org.springframework</groupId>

  81.            <artifactId>spring-context-support</artifactId>

  82.            <version>${spring.version}</version>

  83.        </dependency>

  84.        <dependency>

  85.            <groupId>org.springframework</groupId>

  86.            <artifactId>spring-test</artifactId>

  87.            <version>${spring.version}</version>

  88.        </dependency>

  89.        <dependency>

  90.            <groupId>org.springframework</groupId>

  91.            <artifactId>spring-jms</artifactId>

  92.            <version>${spring.version}</version>

  93.        </dependency>

  94.        <dependency>

  95.            <groupId>org.aspectj</groupId>

  96.            <artifactId>aspectjrt</artifactId>

  97.            <version>1.6.11</version>

  98.        </dependency>

  99.        <dependency>

  100.            <groupId>org.aspectj</groupId>

  101.            <artifactId>aspectjweaver</artifactId>

  102.            <version>1.6.11</version>

  103.        </dependency>

  104.    </dependencies>

  105.   <modules>

  106.    <module>demo-api</module>

  107.    <module>dubbo-consumer</module>

  108.    <module>dubbo-provider</module>

  109.   </modules>

  110. </project>

在demo-api中定义服务接口(注意服务提供方和消费方都需要依赖这个项目)

  1. package com.test;

  2. public interface DemoService{  

  3.     String sayHello(String name);  

  4. }

服务提供方实现

项目结构

实现接口

  1. package com.test;

  2. import org.springframework.stereotype.Service;

  3. import com.test.DemoService;

  4. @Service("demoService")

  5. public class DemoServiceImpl implements DemoService{

  6.    @Override

  7.    public String sayHello(String name) {

  8.        // TODO Auto-generated method stub

  9.        return name;

  10.    }  

  11. }

声明暴露服务:

  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.    <dubbo:application name="dubbo_provider"  />  

  11.    <!-- 使用zookeeper注册中心暴露服务地址 -->  

  12.    <dubbo:registry address="zookeeper://127.0.0.1:2181" />  

  13.    <!-- 用dubbo协议在20880端口暴露服务 -->  

  14.    <dubbo:protocol name="dubbo" port="20880" />  

  15.    <!-- 声明需要暴露的服务接口 -->  

  16.    <dubbo:service interface="com.test.DemoService" ref="demoService" />  

  17. </beans>

在springmvc.xml中扫描service注解并将dubbo-provider.xml中的相关的dubbo配置引入进来

  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"

  3.    xmlns:context="http://www.springframework.org/schema/context"

  4.    xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  5.    xsi:schemaLocation="http://www.springframework.org/schema/aop  

  6.        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  

  7.        http://www.springframework.org/schema/beans  

  8.        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  

  9.        http://www.springframework.org/schema/context

  10.        http://www.springframework.org/schema/context/spring-context-4.0.xsd  

  11.        http://www.springframework.org/schema/util

  12.        http://www.springframework.org/schema/util/spring-util-4.0.xsd"

  13.    default-autowire="byName">

  14.    <aop:aspectj-autoproxy />

  15.    <context:component-scan base-package="com.test" />

  16.    <import resource="classpath:dubbo-provider.xml" />

  17. </beans>

加载Spring配置,启动服务:

  1. package com.test;

  2. import java.io.IOException;

  3. import org.springframework.context.support.ClassPathXmlApplicationContext;

  4. public class Test {

  5.    public static void main(String[] args) throws Exception {

  6.        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:springmvc.xml");

  7.        context.start();

  8.        System.out.println("Dubbo provider start...");

  9.        try {

  10.            System.in.read();   // 按任意键退出

  11.        } catch (IOException e) {

  12.            e.printStackTrace();

  13.        }

  14.    }

  15. }

服务消费者实现

项目结构

在dubbo-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.    <dubbo:application name="dubbo_consumer" />      

  10.      <!-- 使用multicast广播注册中心暴露发现服务地址 -->    

  11.    <dubbo:registry  protocol="zookeeper" address="zookeeper://127.0.0.1:2181" />        

  12.      <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->    

  13.    <dubbo:reference id="demoService" interface="com.test.DemoService" />    

  14. </beans>  

在springmvc.xml中扫描service注解并将dubbo-consumer.xml中的相关的dubbo配置引入进来

  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"

  3.    xmlns:context="http://www.springframework.org/schema/context"

  4.    xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  5.    xsi:schemaLocation="http://www.springframework.org/schema/aop  

  6.        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  

  7.        http://www.springframework.org/schema/beans  

  8.        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  

  9.        http://www.springframework.org/schema/context

  10.        http://www.springframework.org/schema/context/spring-context-4.0.xsd  

  11.        http://www.springframework.org/schema/util

  12.        http://www.springframework.org/schema/util/spring-util-4.0.xsd"

  13.    default-autowire="byName">

  14.    <aop:aspectj-autoproxy />

  15.    <context:component-scan base-package="com.test" />

  16.    <import resource="classpath:/dubbo-consumer.xml" />

  17. </beans>

加载Spring配置,调用服务:

  1. package com.test;

  2. import java.io.IOException;

  3. import org.springframework.context.support.ClassPathXmlApplicationContext;

  4. public class Test {

  5.    public static void main(String[] args) {

  6.        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "classpath:springmvc.xml" });

  7.        context.start();

  8.        DemoService demoService = (DemoService) context.getBean("demoService");

  9.        System.out.println(demoService.sayHello("哈哈哈"));

  10.        try {

  11.            System.in.read();

  12.        } catch (IOException e) {

  13.            e.printStackTrace();

  14.        }

  15.    }

  16. }

如果出现以下结果则调用成功

通过dubbo-admin管理后台可以看到服务的提供方与消费方

提供方:

消费者:

推荐阅读

微信:Yuanping1510

本公众号会不定期给大家发福利,包括学习资源等,敬请期待吧!

推送内容如果现在工作用不上,可以先转发朋友圈或收藏,用的时候方便找。

另外欢迎关注公众号 添加微信 好友,互相学习交流。