2.1 Dubbo 概述

Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源 Java RPC 框架,它提 供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

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

官网:http://dubbo.apache.org/zh-cn/

2. Dubbo框架 - 图1

2. Dubbo框架 - 图2

面向接口代理:调用接口的方法,在 A 服务器调用 B 服务器的方法,由 dubbo 实现对 B 的调用,无需关心实现的细节,就像 MyBatis 访问 Dao 的接口,可以操作数据库一样。不用关心 Dao 接口方法的实现。这样开发是方便,舒服的。

2.2 基本架构

2. Dubbo框架 - 图3

1)、服务提供者(Provider): 暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。

2)、 服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

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

4)、监控中心(Monitor): 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

调用关系说明:
**

  • 服务容器负责启动,加载,运行服务提供者。
  • 服务提供者在启动时,向注册中心注册自己提供的服务。
  • 服务消费者在启动时,向注册中心订阅自己所需的服务。
  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

2.3 dubbo 支持的协议

支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。 dubbo 官方推荐使用 dubbo 协议。dubbo 协议默认端口 20880

使用 dubbo 协议,spring 配置文件加入:

2.4 电商平台需求

某电商平台系统需求,用户浏览商品;选择商品下订单,订单系统需要获取用户信息中的送货地址;向支付系统请求完成付款。

2. Dubbo框架 - 图4

2.5 Dubbo的使用(直连的方式)

点对点的直连项目:消费者直接访问服务提供者,没有注册中心。消费者必须指定服务提供者的访问地址。

消费者直接通过 url 地址访问固定的服务提供者。这个 url 地址是不变的。

2. Dubbo框架 - 图5

2.5.1 实现步骤

**

1)服务的提供者

  • 创建一个maven web工程:服务的提供者

  • 创建一个实体bean查询的结果

  • 提供一个服务接口:xxxx

  • 实现这个服务接口:xxxxImpl

  • 配置dubbo服务提供者的核心配置文件

    • 声明dubbo服务提供者的名称:保证唯一

    • 声明dubbo使用的协议和端口号

    • 暴露服务,使用直连方式

  • 添加监听器

配置dubbo服务提供者的pom文件所需要的依赖如下:

  1. <dependencies>
  2. <!--Spring依赖-->
  3. <dependency>
  4. <groupId>org.springframework</groupId>
  5. <artifactId>spring-context</artifactId>
  6. <version>4.3.16.RELEASE</version>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.springframework</groupId>
  10. <artifactId>spring-webmvc</artifactId>
  11. <version>4.3.16.RELEASE</version>
  12. </dependency>
  13. <!--dubbo依赖-->
  14. <dependency>
  15. <groupId>com.alibaba</groupId>
  16. <artifactId>dubbo</artifactId>
  17. <version>2.6.2</version>
  18. </dependency>
  19. </dependencies>

配置JDK1.8编译插件如下:

<build>
        <plugins>
            <!--JDK1.8编译插件-->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
 </build>

配置dubbo服务提供者的核心配置文件如下:

<?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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--服务提供者声明名称:必须保证服务名称的唯一性,它的名称是dubbo内部使用的唯一标识-->
    <dubbo:application name="001-link-userservice-provider"/>

    <!--访问服务协议的名称及端口号,dubbo官方推荐使用的是dubbo协议,端口号默认为20880-->
    <!--
        name:指定协议的名称
        port:指定协议的端口号(默认为20880)
    -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--
        暴露服务接口->dubbo:service
        interface:暴露服务接口的全限定类名
        ref:接口引用的实现类在spring容器中的标识
        registry:如果不使用注册中心,则值为:N/A
    -->
    <dubbo:service interface="com.wkcto.dubbo.service.UserService" ref="userService" registry="N/A"/>

    <!--将接口的实现类加载到spring容器中-->
    <bean id="userService" class="com.wkcto.dubbo.service.impl.UserServiceImpl"/>

</beans>

配置监听器如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-userservice-provider.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

2)服务的消费者

  • 创建一个maven web工程:服务的消费者

  • 配置pom文件:添加需要的依赖(spring,dubbo)

  • 设置dubbo的核心配置文件()

  • 编写controller

  • 配置中央调度器(就是一个servlet:DispatcherServlet)

  • 安装本地服务提供者 jar 到 maven 仓库

配置dubbo服务消费者的pom文件所需要的依赖如下:

<dependencies>
  <!--Spring依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.16.RELEASE</version>
  </dependency>

  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.16.RELEASE</version>
  </dependency>

  <!--dubbo依赖-->
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.2</version>
  </dependency>

  <!--依赖服务提供者-->
  <dependency>
    <groupId>com.wkcto.dubbo</groupId>
    <artifactId>001-link-userservice-provider</artifactId>
    <version>1.0.0</version>
  </dependency>
</dependencies>

配置dubbo服务消费者的核心配置文件如下:

<?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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--声明服务消费者的名称:保证唯一性-->
    <dubbo:application name="002-link-consumer"/>

    <!--
        引用远程服务接口:
        id:远程服务接口对象名称
        interface:调用远程接口的全限定类名
        url:访问服务接口的地址
        registry:不使用注册中心,值为:N/A
    -->
    <dubbo:reference id="userService"
                     interface="com.wkcto.dubbo.service.UserService"
                     url="dubbo://localhost:20880"
                     registry="N/A"/>

</beans>

配置SpringMVC核心配置文件如下:

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--扫描组件-->
    <context:component-scan base-package="com.wkcto.dubbo.web"/>

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

配置web.xml中央调度器(DispatcherServlet)如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd">

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application.xml,classpath:dubbo-consumer.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

安装本地服务提供者 jar 到 maven 仓
**

服务接口中的方法要给消费者使用,消费者项目需要知道接口名称和接口中的方法名称、参数等。这些信息服务提供者才知道。需要把接口的 class 文件打包为 jar 。

服务接口项目的类文件打包为 jar, 安装到 maven 仓库,仓库中的提供者 jar 可以被消费者使用

使用 idea 的 maven 窗口执行 install

编写controller如下:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/user")
    public String userDetail(Model model,Integer id) {

        User user = this.userService.queryUserById(id);
        model.addAttribute("user",user);
        return "userDetail";
    }

}

2.6 Dubbo 服务化最佳实践

2.6.1 分包

建议将服务接口、服务模型、服务异常等均放在公共包中。

2.6.2 粒度

服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。

服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。

不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义, 会给后期维护带来不便。

2.6.3 版本

每个接口都应定义版本号,为后续不兼容升级提供可能,如:

建议使用两位版本号,要变更服务版本。先升级一半提供者为新版本,再将消费者全部升为新版本,然后将剩下的一半提供者升为新版本。

2.7 改造 Dubbo 项目(服务化最佳实践)

抽象分散在多个项目中的公共接口,实体类,异常,工具类到一个项目中,在其他项目如服务提供者,消费者共用公共的资源。

1)、dubbo官方推荐使用的一个模式,将实体bean和业务接口存放到接口工程中
**

  1. 创建一个maven 普通Java工程
  2. 创建一个实体bean查询的结果
  3. 提供一个服务接口:xxxx

2)、服务的提供者
**

  • 创建一个maven web工程:服务的提供者

  • 创建一个实体bean查询的结果

  • 实现这个服务接口:xxxxImpl

  • 配置dubbo服务提供者的核心配置文件

    • 声明dubbo服务提供者的名称:保证唯一

    • 声明dubbo使用的协议和端口号

    • 暴露服务,使用直连方式

  • 添加监听器

  • 导入接口工程的jar到工程中

配置dubbo服务提供者的pom文件所需要的依赖如下:

<dependencies>

  <!--Spring依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.16.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.16.RELEASE</version>
  </dependency>

  <!--dubbo依赖-->
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.2</version>
  </dependency>

  <!--接口工程-->
  <dependency>
    <groupId>com.wkcto.dubbo</groupId>
    <artifactId>003-link-interface</artifactId>
    <version>1.0.0</version>
  </dependency>

</dependencies>

配置JDK1.8编译插件如下:

<build>
        <plugins>
            <!--JDK1.8编译插件-->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
 </build>

配置dubbo服务提供者的核心配置文件如下:

<?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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--声明dubbo服务提供者的名称:保证唯一性-->
    <dubbo:application name="004-link-userservice-provider"/>

    <!--设置dubbo使用的协议和端口号-->
    <!--
        name:dubbo使用协议的名称
        port:dubbo服务的端口号
    -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--
        暴露服务接口
    -->
    <dubbo:service interface="com.wkcto.dubbo.service.UserService" ref="userService" registry="N/A"/>

    <!--加载业务接口的实现类到spring容器中-->
    <bean id="userService" class="com.wkcto.dubbo.service.impl.UserServiceImpl"/>

</beans>

配置监听器如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-userservice-provider.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

2)、服务消费者
**

  1. 创建一个maven web工程:服务的消费者
  2. 配置pom文件:添加需要的依赖(spring,dubbo)
  3. 设置dubbo的核心配置文件()
  4. 编写controller
  5. 配置中央调度器(就是一个servlet:DispatcherServlet)
  6. 导入接口工程的jar到工程中

配置dubbo服务消费者的pom文件所需要的依赖如下:

<dependencies>
  <!--Spring依赖-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.16.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.16.RELEASE</version>
  </dependency>

  <!--dubbo依赖-->
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.2</version>
  </dependency>

  <!--接口工程-->
  <dependency>
    <groupId>com.wkcto.dubbo</groupId>
    <artifactId>003-link-interface</artifactId>
    <version>1.0.0</version>
  </dependency>
</dependencies>

配置dubbo服务消费者的核心配置文件如下:

<?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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--声明服务消费者名称:保证唯一性-->
    <dubbo:application name="005-link-consumer"/>

    <!--引用远程接口服务-->
    <dubbo:reference id="userService"
                     interface="com.wkcto.dubbo.service.UserService"
                     url="dubbo://localhost:20880"
                     registry="N/A"/>
</beans>

配置SpringMVC核心配置文件如下:

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--扫描组件-->
    <context:component-scan base-package="com.wkcto.dubbo.web"/>

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

配置web.xml中央调度器(DispatcherServlet)如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd">

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

编写controller如下:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/userDetail")
    public String userDetail(Model model,Integer id) {

        //根据用户标识获取用户详情
        User user = userService.queryUserById(id);

        //获取用户总人数
        Integer allUserCount = userService.queryAllUserCount();

        model.addAttribute("user",user);
        model.addAttribute("allUserCount",allUserCount);

        return "userDetail";
    }
}

2.8 Dubbo 常用标签

Dubbo 中常用标签。分为三个类别:公用标签,服务提供者标签,服务消费者标签

2.8.1 公用标签

A、配置应用信息
**

B、配置注册中心
**

2.8.2 服务提供者标签

配置暴露的服务

2.8.3 服务消费者标签

配置服务消费者引用远程服务