SpringBoot上手整合Dubbo

  • 一. Dubbo架构图
  • 二. 搭建一个Common模块存放接口+实体类
  • ①. UserAddress 实体类
  • ②. 用户和订单接口
  • 三. 搭建一个生产者Provider模块
  • ①. pom.xml依赖导入
  • ②. 用户实现类UserServiceImpl
  • ③. 启动类上注解添加
  • ④. 配置文件修改application.yml或者provider.xml配置文件
  • ⑤. 启动provider服务进行测试
  • 四. 搭建消费者Consumer模块
  • ①. pom.xml配置文件
  • ②. 订单的实现类OrderServiceImpl
  • ③. 启动类上注解添加
  • ④. 配置文件修改application.yml或者使用consumer.xml配置文件
  • ⑤. Controller 接口编写
  • ⑤. 启动consumer服务进行测试
  • 五. Dubbo整合SpringBoot三种配置方式
  • ①. 使用@DubboService(暴露服务),@DubboReference(引用服务)
  • ②. 保留Dubbo 相关的xml配置文件
  • ③. 使用 注解API的方式
  • 六. 集群下dubbo负载均衡配置
  • ①. Random LoadBalance 基于权重的随机负载均衡机制
  • ②. RoundRobin LoadBalance 基于权重的轮询负载均衡机制
  • ③. LeastActive LoadBalance最少活跃数负载均衡机制
  • ④. ConsistentHash LoadBalance一致性hash 负载均衡机制
  • 七. 整合hystrix,服务熔断与降级处理
  • ①. 服务降级
  • ②. 集群容错
  • 1. Failfast Cluster
  • 2. Failsafe Cluster
  • 3. Failback Cluster
  • 4. Forking Cluster
  • 5. Broadcast Cluster
  • ③. 整合hystrix
  • 八. GitHub源码地址


一. Dubbo架构图

spring boot启动dubbo spring boot+dubbo_spring

二. 搭建一个Common模块存放接口+实体类

spring boot启动dubbo spring boot+dubbo_ci_02

①. UserAddress 实体类

package com.xizi.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress;
    private String userId;
    private String consignee;
    private String phone;
    private String isDefault;
}

②. 用户和订单接口

spring boot启动dubbo spring boot+dubbo_spring boot启动dubbo_03

package com.xizi.service;

import com.xizi.pojo.UserAddress;

import java.util.List;

/**
 * @author xizizzz
 * @description: TODO
 * @date 2021-7-21上午 09:41
 */
public interface UserService {
    List<UserAddress> getUserAddressList(String userId);
}
package com.xizi.service;

import com.xizi.pojo.UserAddress;

import java.util.List;

/**
 * @author xizizzz
 * @description: TODO
 * @date 2021-7-21上午 09:49
 */


public interface OrderService {
    List<UserAddress> initOrder(String userId);
}

三. 搭建一个生产者Provider模块

①. pom.xml依赖导入

spring boot启动dubbo spring boot+dubbo_ide_04

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.12</version>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>2.7.12</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.xizi</groupId>
            <artifactId>service_common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

②. 用户实现类UserServiceImpl

spring boot启动dubbo spring boot+dubbo_spring boot启动dubbo_05

@Service
@DubboService(timeout = 0)  //暴露服务
public class UserServiceImpl implements UserService {

    @HystrixCommand
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("userService1.....");
        UserAddress userAddress1 = new UserAddress(1, "江西南昌", "00000", "xizizzz", "15652211111", "1");
        UserAddress userAddress2 = new UserAddress(2, "浙江杭州", "00001", "xizzz", "17911111111", "1");
        if(Math.random()>0.5) {
            throw new RuntimeException();
        }
        return Arrays.asList(userAddress1, userAddress2);
    }
}

③. 启动类上注解添加

spring boot启动dubbo spring boot+dubbo_ci_06

//@ImportResource(locations ="classpath:provider.xml") //第二种方式 使用dubbo xml配置文件
@SpringBootApplication
@EnableDubbo(scanBasePackages = "com.xizi") //开启基于注解的dubbo
@EnableHystrix //开启服务容错
public class UserServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceProviderApplication.class, args);
    }

}

④. 配置文件修改application.yml或者provider.xml配置文件

  • 本地记得开启Zookeeper注册中心

spring boot启动dubbo spring boot+dubbo_spring boot启动dubbo_07

server:
  port: 9000

dubbo:
  application:
    name: user-service-provider
  registry:
    protocol: zookeeper
    address: 127.0.0.1:2181
  protocol:
    name: dubbo
    port: 20080

使用xml配置文件也可以,启动类上开启注解扫描

spring boot启动dubbo spring boot+dubbo_ide_08

<?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://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
		http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

	<!-- 1、指定当前服务/应用的名字(同样的服务名字相同,不要和别的服务同名) -->
	<dubbo:application name="boot-user-service-provider"></dubbo:application>
	
	<!-- 2、指定注册中心的位置 -->
	<!-- <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> -->
	<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
	
	<!-- 3、指定通信规则(通信协议?通信端口) -->
	<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
	
	<!-- 4、暴露服务   ref:指向服务的真正的实现对象 -->
	<dubbo:service interface="com.xizi.service.UserService"
		ref="userServiceImpl01" timeout="1000" version="1.0.0">
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
	</dubbo:service>
	
	<!--统一设置服务提供方的规则  -->
	<dubbo:provider timeout="1000"></dubbo:provider>
	
	
	<!-- 服务的实现 -->
	<bean id="userServiceImpl01" class="com.xizi.service.UserServiceImpl"></bean>
	
	
	<!-- 连接监控中心 -->
	<dubbo:monitor protocol="registry"></dubbo:monitor>
	
</beans>

⑤. 启动provider服务进行测试

spring boot启动dubbo spring boot+dubbo_ci_09

spring boot启动dubbo spring boot+dubbo_ci_10


spring boot启动dubbo spring boot+dubbo_dubbo_11

四. 搭建消费者Consumer模块

①. pom.xml配置文件

spring boot启动dubbo spring boot+dubbo_spring boot启动dubbo_12

<dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.12</version>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>2.7.12</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.xizi</groupId>
            <artifactId>service_common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

②. 订单的实现类OrderServiceImpl

spring boot启动dubbo spring boot+dubbo_dubbo_13

package com.xizi.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.xizi.pojo.UserAddress;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

/**
 * @author xizizzz
 * @description: TODO
 * @date 2021-7-21上午 09:50
 */

@Service
@DubboService
public class OrderServiceImpl  implements OrderService{

    @Reference(loadbalance="random",timeout=1000)
//    @Autowired
    UserService userService;

    @HystrixCommand(fallbackMethod="hello")
    @Override
    public List<UserAddress> initOrder(String userId) {
        System.out.println("用户id:"+userId);
        //1、查询用户的收货地址
        List<UserAddress> addressList = userService.getUserAddressList(userId);
        for (UserAddress userAddress : addressList) {
            System.out.println(userAddress.toString());
        }
        return addressList;
    }

    // 服务报错后置方法
    public List<UserAddress> hello(String userId) {
        return Arrays.asList(new UserAddress(10, "测试地址", "1", "测试", "测试", "Y"));
    }
}

③. 启动类上注解添加

spring boot启动dubbo spring boot+dubbo_dubbo_14

//@ImportResource(locations ="classpath:consumer.xml") //第二种方式 使用dubbo xml配置文件
@SpringBootApplication
@EnableDubbo
@EnableHystrix
public class UserServiceConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceConsumerApplication.class, args);
    }

}

④. 配置文件修改application.yml或者使用consumer.xml配置文件

spring boot启动dubbo spring boot+dubbo_ide_15

server:
  port: 9001

dubbo:
  application:
    name: order-service-consumer
  registry:
    protocol: zookeeper
    address: 127.0.0.1:2181
  protocol:
    port: 20881

使用xml配置文件也可以,启动类上开启注解扫描

spring boot启动dubbo spring boot+dubbo_spring_16

<?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"
	xmlns:context="http://www.springframework.org/schema/context"
	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-4.3.xsd
		http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
		http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	<context:component-scan base-package="com.xizi.service"></context:component-scan>


	<dubbo:application name="order-service-consumer"></dubbo:application>
	
	<dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
	
	<!--  配置本地存根-->
	
	<!--声明需要调用的远程服务的接口;生成远程服务代理  -->
	<!-- 
		1)、精确优先 (方法级优先,接口级次之,全局配置再次之)
		2)、消费者设置优先(如果级别一样,则消费方优先,提供方次之)
	-->
	<!-- timeout="0" 默认是1000ms-->
	<!-- retries="":重试次数,不包含第一次调用,0代表不重试-->
	<!-- 幂等(设置重试次数)【查询、删除、修改】、非幂等(不能设置重试次数)【新增】 -->
	<dubbo:reference interface="com.xizi.service.UserService"
		id="userService" timeout="5000" retries="3" version="*">
		<!-- <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method> -->
	</dubbo:reference>
		
	<!-- 配置当前消费者的统一规则:所有的服务都不检查 -->
	<dubbo:consumer check="false" timeout="5000"></dubbo:consumer>

	<dubbo:monitor protocol="registry"></dubbo:monitor>
	<!-- <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor> -->
</beans>

⑤. Controller 接口编写

package com.xizi.controller;

import java.util.List;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xizi.pojo.UserAddress;
import com.xizi.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class OrderController {

	@Autowired
	OrderService orderService;
	
	@ResponseBody
	@RequestMapping("/initOrder")
	public List<UserAddress> initOrder(@RequestParam("uid")String userId) {
		return orderService.initOrder(userId);
	}

}

spring boot启动dubbo spring boot+dubbo_ide_17

⑤. 启动consumer服务进行测试

spring boot启动dubbo spring boot+dubbo_ci_18

spring boot启动dubbo spring boot+dubbo_ci_19

spring boot启动dubbo spring boot+dubbo_spring_20


spring boot启动dubbo spring boot+dubbo_ide_21

五. Dubbo整合SpringBoot三种配置方式

①. 使用@DubboService(暴露服务),@DubboReference(引用服务)

spring boot启动dubbo spring boot+dubbo_ide_22

spring boot启动dubbo spring boot+dubbo_dubbo_23

②. 保留Dubbo 相关的xml配置文件

  • 导入dubbo-starter,使用@ImportResource导入Dubbo的xml配置文件

spring boot启动dubbo spring boot+dubbo_spring_24

③. 使用 注解API的方式

  • 将每一个组件手动配置到容器中,让dubbo来扫描其他的组件
package com.xizi.config;

import java.util.ArrayList;
import java.util.List;

import com.xizi.service.UserService;
import org.springframework.context.annotation.Bean;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.MethodConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;

//@Configuration  第三种方式 使用Config配置文件手动创建
public class MyDubboConfig {
	@Bean
	public ApplicationConfig applicationConfig() {
		ApplicationConfig applicationConfig = new ApplicationConfig();
		applicationConfig.setName("boot-user-service-provider");
		return applicationConfig;
	}
	//<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
	@Bean
	public RegistryConfig registryConfig() {
		RegistryConfig registryConfig = new RegistryConfig();
		registryConfig.setProtocol("zookeeper");
		registryConfig.setAddress("127.0.0.1:2181");
		return registryConfig;
	}
	
	//<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
	@Bean
	public ProtocolConfig protocolConfig() {
		ProtocolConfig protocolConfig = new ProtocolConfig();
		protocolConfig.setName("dubbo");
		protocolConfig.setPort(20882);
		return protocolConfig;
	}
	
	/**
	 *<dubbo:service interface="com.atguigu.gmall.service.UserService" 
		ref="userServiceImpl01" timeout="1000" version="1.0.0">
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
	</dubbo:service>
	 */
	@Bean
	public ServiceConfig<UserService> userServiceConfig(UserService userService){
		ServiceConfig<UserService> serviceConfig = new ServiceConfig<>();
		serviceConfig.setInterface(UserService.class);
		serviceConfig.setRef(userService);
		serviceConfig.setVersion("1.0.0");
		
		//配置每一个method的信息
		MethodConfig methodConfig = new MethodConfig();
		methodConfig.setName("getUserAddressList");
		methodConfig.setTimeout(1000);
		
		//将method的设置关联到service配置中
		List<MethodConfig> methods = new ArrayList<>();
		methods.add(methodConfig);
		serviceConfig.setMethods(methods);
		
		//ProviderConfig
		//MonitorConfig
		return serviceConfig;
	}
}

spring boot启动dubbo spring boot+dubbo_ci_25

六. 集群下dubbo负载均衡配置

①. Random LoadBalance 基于权重的随机负载均衡机制

  • 随机,按权重设置随机概率。 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

spring boot启动dubbo spring boot+dubbo_dubbo_26


spring boot启动dubbo spring boot+dubbo_dubbo_27


spring boot启动dubbo spring boot+dubbo_ide_28


spring boot启动dubbo spring boot+dubbo_dubbo_29

spring boot启动dubbo spring boot+dubbo_dubbo_30

spring boot启动dubbo spring boot+dubbo_spring_31


spring boot启动dubbo spring boot+dubbo_dubbo_32

spring boot启动dubbo spring boot+dubbo_dubbo_33

②. RoundRobin LoadBalance 基于权重的轮询负载均衡机制

  • 轮循,按公约后的权重设置轮循比率。 存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

spring boot启动dubbo spring boot+dubbo_ci_34

③. LeastActive LoadBalance最少活跃数负载均衡机制

  • 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

spring boot启动dubbo spring boot+dubbo_spring_35

④. ConsistentHash LoadBalance一致性hash 负载均衡机制

  • 一致性 Hash,相同参数的请求总是发到同一提供者。 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

spring boot启动dubbo spring boot+dubbo_dubbo_36


spring boot启动dubbo spring boot+dubbo_spring_37

七. 整合hystrix,服务熔断与降级处理

①. 服务降级

  • 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

②. 集群容错

  • 在集群调用失败时,Dubbo 提供了多种容错方案。

1. Failfast Cluster

  • 快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

2. Failsafe Cluster

  • 失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

3. Failback Cluster

  • 失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

4. Forking Cluster

  • 并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=“2” 来设置最大并行数。

5. Broadcast Cluster

  • 广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

③. 整合hystrix

  • Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能
  • spring boot启动dubbo spring boot+dubbo_spring boot启动dubbo_38


<!--hystrix服务治理-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

spring boot启动dubbo spring boot+dubbo_spring boot启动dubbo_39

spring boot启动dubbo spring boot+dubbo_spring boot启动dubbo_40

spring boot启动dubbo spring boot+dubbo_ide_41

八. GitHub源码地址

https://github.com/xizizzz/Dubbo_Study

spring boot启动dubbo spring boot+dubbo_ci_42