分布式框架Dubbo

JAVA学习网 2020-09-01 15:23:02

Dubbo简介

Dubbo是一款高性能的Java RPC框架,其前身是阿里巴巴公司开源的一个高性能、轻量级的开源Java RPC框架,可以和Spring框架无缝集成。

Dubbo官网

特性

  • 面向接口代理的高性能RPC调用
  • 智能负载均衡
  • 服务自动注册与发现
  • 高度可扩展能力
  • 运行期间流量调度
  • 可视化的服务治理与运维

Dubbo的设计架构

节点 角色名称

Provider

服务提供者
Registry 注册中心
Consumer 服务消费者
Container 框架容器
Monitor 监控中心

虚线是异步访问,实线是同步访问。

0、1、2是在启动时完成的功能,3、4、5是在程序运行中执行的功能。

调用流程

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

Dubbo部署

配置注册中心

zokeeper说明文档

zokeeper下载

  1. 下载zokeeper
  2. zokeeper配置文件,路径:zokeeper/conf/zoo_sample.cfg
     1  # Client-Server通信心跳时间
     2  tickTime=2000
     3  # Leader-Follower初始通信时限
     4  initLimit=10
     5  # Leader-Follower同步通信时限
     6  syncLimit=5
     7  # 数据文件目录
     8  dataDir=../data
     9  # 客户端连接端口
    10  clientPort=2181

     

  3. 可执行文件,路径:zokeeper/bin/zkEnv.cmd
    1 REM 与conf下的配置文件名称一致
    2 set ZOOCFG=%ZOOCFGDIR%\zoo_sample.cfg

     

  4. 启动zookeeper服务,路径:zokeeper/bin/zkServer.cmd

项目部署

公共服务接口

  1. 创建一个公共接口工程
  2. 创建一个HelloService接口
     1 package com.tankang.service;
     2 
     3 /**
     4  * @program: dubbo
     5  * @description: 提供者服务层接口
     6  * @author: 谭康
     7  * @create: 2020-08-30 13:45
     8  **/
     9 public interface HelloService {
    10     String sayHello(String name);
    11 }

     

服务提供者

  1. 创建一个服务提供者工程
  2. 导入maven坐标
      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <project xmlns="http://maven.apache.org/POM/4.0.0"
      3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      5     <modelVersion>4.0.0</modelVersion>
      6 
      7     <groupId>com.tankang</groupId>
      8     <artifactId>dubbodemo_provider</artifactId>
      9     <version>1.0-SNAPSHOT</version>
     10     <packaging>war</packaging>
     11 
     12     <properties>
     13         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     14         <maven.compiler.source>1.8</maven.compiler.source>
     15         <maven.compiler.target>1.8</maven.compiler.target>
     16         <spring.version>5.0.5.RELEASE</spring.version>
     17     </properties>
     18     <dependencies>
     19         <dependency>
     20             <groupId>org.springframework</groupId>
     21             <artifactId>spring-context</artifactId>
     22             <version>${spring.version}</version>
     23         </dependency>
     24         <dependency>
     25             <groupId>org.springframework</groupId>
     26             <artifactId>spring-beans</artifactId>
     27             <version>${spring.version}</version>
     28         </dependency>
     29         <dependency>
     30             <groupId>org.springframework</groupId>
     31             <artifactId>spring-webmvc</artifactId>
     32             <version>${spring.version}</version>
     33         </dependency>
     34         <dependency>
     35             <groupId>org.springframework</groupId>
     36             <artifactId>spring-jdbc</artifactId>
     37             <version>${spring.version}</version>
     38         </dependency>
     39         <dependency>
     40             <groupId>org.springframework</groupId>
     41             <artifactId>spring-aspects</artifactId>
     42             <version>${spring.version}</version>
     43         </dependency>
     44         <dependency>
     45             <groupId>org.springframework</groupId>
     46             <artifactId>spring-jms</artifactId>
     47             <version>${spring.version}</version>
     48         </dependency>
     49         <dependency>
     50             <groupId>org.springframework</groupId>
     51             <artifactId>spring-context-support</artifactId>
     52             <version>${spring.version}</version>
     53         </dependency>
     54         <!-- dubbo相关 -->
     55         <dependency>
     56             <groupId>com.alibaba</groupId>
     57             <artifactId>dubbo</artifactId>
     58             <version>2.6.0</version>
     59         </dependency>
     60         <dependency>
     61             <groupId>org.apache.zookeeper</groupId>
     62             <artifactId>zookeeper</artifactId>
     63             <version>3.4.7</version>
     64         </dependency>
     65         <dependency>
     66             <groupId>com.github.sgroschupf</groupId>
     67             <artifactId>zkclient</artifactId>
     68             <version>0.1</version>
     69         </dependency>
     70         <dependency>
     71             <groupId>javassist</groupId>
     72             <artifactId>javassist</artifactId>
     73             <version>3.12.1.GA</version>
     74         </dependency>
     75         <dependency>
     76             <groupId>com.alibaba</groupId>
     77             <artifactId>fastjson</artifactId>
     78             <version>1.2.47</version>
     79         </dependency>
     80         <!-- 导入公共抽取接口坐标 -->
     81         <dependency>
     82             <groupId>com.tankang</groupId>
     83             <artifactId>dubbodemo_interface</artifactId>
     84             <version>1.0-SNAPSHOT</version>
     85         </dependency>
     86     </dependencies>
     87     <build>
     88         <plugins>
     89             <plugin>
     90                 <groupId>org.apache.maven.plugins</groupId>
     91                 <artifactId>maven-compiler-plugin</artifactId>
     92                 <version>2.3.2</version>
     93                 <configuration>
     94                     <source>1.8</source>
     95                     <target>1.8</target>
     96                 </configuration>
     97             </plugin>
     98             <!-- tomcat插件 -->
     99             <plugin>
    100                 <groupId>org.apache.tomcat.maven</groupId>
    101                 <artifactId>tomcat7-maven-plugin</artifactId>
    102                 <configuration>
    103                     <!-- 指定端口 -->
    104                     <port>8082</port>
    105                     <!-- 请求路径 -->
    106                     <path>/</path>
    107                 </configuration>
    108             </plugin>
    109         </plugins>
    110     </build>
    111 </project>

     

  3. 创建提供者实现类
     1 package com.tankang.service.impl;
     2 
     3 import com.alibaba.dubbo.config.annotation.Service;
     4 import com.tankang.service.HelloService;
     5 
     6 /**
     7  * @program: dubbo
     8  * @description: 提供者实现类
     9  * @author: 谭康
    10  * @create: 2020-08-30 13:58
    11  **/
    12 @Service
    13 public class HelloServiceImpl implements HelloService {
    14     @Override
    15     public String sayHello(String name) {
    16         return "Hello," + name + "!";
    17     }
    18 }

     

  4. 配置web.xml
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
     5          version="4.0">
     6     <context-param>
     7         <param-name>contextConfigLocation</param-name>
     8         <param-value>classpath:provida.xml</param-value>
     9     </context-param>
    10     <listener>
    11         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    12     </listener>
    13 </web-app>

     

  5. 用Spring配置声明暴露服务,provida.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"  />
    
        <!-- 使用注册中心暴露服务地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 组件扫描,加入@Service注解的类会被发布为服务 -->
        <dubbo:annotation package="com.tankang.service.impl" />
    
    </beans>

     

服务消费者

  1. 创建一个服务消费者工程
  2. 导入坐标
      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <project xmlns="http://maven.apache.org/POM/4.0.0"
      3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      5     <modelVersion>4.0.0</modelVersion>
      6 
      7     <groupId>com.tankang</groupId>
      8     <artifactId>dubbodemo_consumer</artifactId>
      9     <version>1.0-SNAPSHOT</version>
     10     <packaging>war</packaging>
     11 
     12     <properties>
     13         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     14         <maven.compiler.source>1.8</maven.compiler.source>
     15         <maven.compiler.target>1.8</maven.compiler.target>
     16         <spring.version>5.0.5.RELEASE</spring.version>
     17     </properties>
     18     <dependencies>
     19         <dependency>
     20             <groupId>org.springframework</groupId>
     21             <artifactId>spring-context</artifactId>
     22             <version>${spring.version}</version>
     23         </dependency>
     24         <dependency>
     25             <groupId>org.springframework</groupId>
     26             <artifactId>spring-beans</artifactId>
     27             <version>${spring.version}</version>
     28         </dependency>
     29         <dependency>
     30             <groupId>org.springframework</groupId>
     31             <artifactId>spring-webmvc</artifactId>
     32             <version>${spring.version}</version>
     33         </dependency>
     34         <dependency>
     35             <groupId>org.springframework</groupId>
     36             <artifactId>spring-jdbc</artifactId>
     37             <version>${spring.version}</version>
     38         </dependency>
     39         <dependency>
     40             <groupId>org.springframework</groupId>
     41             <artifactId>spring-aspects</artifactId>
     42             <version>${spring.version}</version>
     43         </dependency>
     44         <dependency>
     45             <groupId>org.springframework</groupId>
     46             <artifactId>spring-jms</artifactId>
     47             <version>${spring.version}</version>
     48         </dependency>
     49         <dependency>
     50             <groupId>org.springframework</groupId>
     51             <artifactId>spring-context-support</artifactId>
     52             <version>${spring.version}</version>
     53         </dependency>
     54         <!-- dubbo相关 -->
     55         <dependency>
     56             <groupId>com.alibaba</groupId>
     57             <artifactId>dubbo</artifactId>
     58             <version>2.6.0</version>
     59         </dependency>
     60         <dependency>
     61             <groupId>org.apache.zookeeper</groupId>
     62             <artifactId>zookeeper</artifactId>
     63             <version>3.4.7</version>
     64         </dependency>
     65         <dependency>
     66             <groupId>com.github.sgroschupf</groupId>
     67             <artifactId>zkclient</artifactId>
     68             <version>0.1</version>
     69         </dependency>
     70         <dependency>
     71             <groupId>javassist</groupId>
     72             <artifactId>javassist</artifactId>
     73             <version>3.12.1.GA</version>
     74         </dependency>
     75         <dependency>
     76             <groupId>com.alibaba</groupId>
     77             <artifactId>fastjson</artifactId>
     78             <version>1.2.47</version>
     79         </dependency>
     80         <!-- 导入公共抽取接口坐标 -->
     81         <dependency>
     82             <groupId>com.tankang</groupId>
     83             <artifactId>dubbodemo_interface</artifactId>
     84             <version>1.0-SNAPSHOT</version>
     85         </dependency>
     86     </dependencies>
     87     <build>
     88         <plugins>
     89             <plugin>
     90                 <groupId>org.apache.maven.plugins</groupId>
     91                 <artifactId>maven-compiler-plugin</artifactId>
     92                 <version>2.3.2</version>
     93                 <configuration>
     94                     <source>1.8</source>
     95                     <target>1.8</target>
     96                 </configuration>
     97             </plugin>
     98             <!-- tomcat插件 -->
     99             <plugin>
    100                 <groupId>org.apache.tomcat.maven</groupId>
    101                 <artifactId>tomcat7-maven-plugin</artifactId>
    102                 <configuration>
    103                     <!-- 指定端口 -->
    104                     <port>8083</port>
    105                     <!-- 请求路径 -->
    106                     <path>/</path>
    107                 </configuration>
    108             </plugin>
    109         </plugins>
    110     </build>
    111 </project>

     

  3. 通过Spring配置引用远程服务,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 http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
     5     <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
     6     <dubbo:application name="consumer-of-helloworld-app"  />
     7 
     8     <!-- 连接服务注册中心zookeeper,ip为zookeeper所在服务器的ip地址-->
     9     <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    10 
    11     <!-- 组件扫描,扫描的方式暴露接口  -->
    12     <dubbo:annotation package="com.tankang.controller" />
    13 
    14     <!--超时全局设置-->
    15     <!--
    16         timeout:时间(10分钟)
    17         check:是否检查服务提供方(true|false),开发阶段建议设置为false
    18             true启动时不检查服务提供方
    19             false启动时检查服务提供方,如果服务提供方没有启动则报错
    20     -->
    21     <dubbo:consumer timeout="600000" check="false"/>
    22 </beans>

     

  4. 编写消费者类
     1 package com.tankang.controller;
     2 
     3 import com.alibaba.dubbo.config.annotation.Reference;
     4 import com.tankang.service.HelloService;
     5 import org.springframework.web.bind.annotation.RequestMapping;
     6 import org.springframework.web.bind.annotation.RestController;
     7 
     8 /**
     9  * @program: dubbo
    10  * @description: 消费者类
    11  * @author: 谭康
    12  * @create: 2020-08-30 14:21
    13  **/
    14 @RestController
    15 @RequestMapping("/hello")
    16 public class HelloController {
    17     @Reference
    18     private HelloService helloService;
    19     
    20     @RequestMapping("/sayHello")
    21     public String sayHello(String name){
    22         String str = helloService.sayHello(name);
    23         return str;
    24     }
    25 }

     

  5. 配置web.xml
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
     5          version="4.0">
     6     <!-- 配置前端控制器 -->
     7     <servlet>
     8         <servlet-name>DispatcherServlet</servlet-name>
     9         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    10         <!-- 指定加载的配置文件,通过参数contextConfigLocation加载 -->
    11         <init-param>
    12             <param-name>contextConfigLocation</param-name>
    13             <param-value>classpath:consumer.xml</param-value>
    14         </init-param>
    15         <load-on-startup>1</load-on-startup>
    16     </servlet>
    17     <servlet-mapping>
    18         <servlet-name>DispatcherServlet</servlet-name>
    19         <url-pattern>/</url-pattern>
    20     </servlet-mapping>
    21 </web-app>

     

测试访问

  1. 启动zokeeper服务,路径:zokeeper/bin/zkServer.cmd
  2. 启动提供者tomcat服务,路径:Maven -> dubbodemo_provider -> Plugins -> tomcat7 -> tomcat7:run
  3. 启动消费者tomcat服务,路径:Maven -> dubbodemo_consumer -> Plugins -> tomcat7 -> tomcat7:run
  4. 测试资源访问,访问地址:http://localhost:8083/hello/sayHello?name=张三

 Dubbo负载均衡

Dubbo提供了四种负载均衡策略

说明
RandomLoadBalance 随机调用(默认)
RoundRobinLoadBlance 轮询调用
LeastActiveLoadBlance 最少活跃数调用
ConsistentHashLoadBalance 一致性Hash算法

使用方法

@Service(loadbalance = "负载均衡策略")

 1 package com.tankang.service.impl;
 2 
 3 import com.alibaba.dubbo.config.annotation.Service;
 4 import com.tankang.service.HelloService;
 5 
 6 /**
 7  * @program: dubbo
 8  * @description: 提供者实现类
 9  * @author: 谭康
10  * @create: 2020-08-30 13:58
11  **/
12 @Service(loadbalance = "random")
13 public class HelloServiceImpl implements HelloService {
14     @Override
15     public String sayHello(String name) {
16         return "Hello," + name + "!";
17     }
18 }

 

 

Dubbo事务解决方案

问题:在使用dubbo 2.5.3之前的版本@Service来发布服务时,当该服务中有@Transactional,是无法正常发布的?

解决方案:

  1. 因为事务TransactionManagement默认是使用了jdk的代理即基于接口的代理,必须改成基于类的代理,@service才会生效,所以必须修改代理方式,如果是javaconfig来配置,加上 @EnableTransactionManagement(proxyTargetClass=true) ,如果是xml配置,加上 <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> 。

  2. 进行了第一步之后,发现仍然不能发布服务,因为dubbo的@Service源码@Inherited,所以没有是不能被代理类继承的,所以还需要修改dubbo @Service的源码,在annotation上加入@Inherited,这样代理类就会继承了这个注解。(注:目前dubbo的master的分支已经修复了这个问题,但是没有发正式的版本。)

  3. 虽然已经发布了,但是会发现发布的服务是spring的代理SpringProxy(可以通过dubbo-admin看到,或者启动日志),不是你想要的,无法正常引用,因为必须在@Service中指定interfaceName,指定发布的服务的名称,例: @Service(version = "1.0.0",interfaceName = "com.zl.dubbotest.api.HelloService") 。
阅读(2370) 评论(0)