一.dubbo 服务容错
1.1 Dubbo提供了多种容错方案,默认值为failover(重试)
1)、Failover Cluster(默认)
失败自动切换,当出现失败,重试其他服务器,通常用于读操作,但重试会带来更长延迟,可以通过属性retries来设置重试次数(不含第一次)
2)、Failfast Cluster
快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作,比如新增记录。
3)、Failsafe Cluster
失败安全,出现异常时,直接忽略,不做任何操作,通常用于写入审计日志等操作。
4)、Failback Cluster
失败自动重发,后台记录失败请求,定时重发,用于一些一定要成功的服务调用,例如消息通知等。
5)、Forking Cluster
并行调用多个服务器,只要有一个成功即返回,用于实时性较高的读操作,但需要浪费更多的服务资源,可通过forks=“2”来设置最大并行数量。
6)、Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则认为这次调用是失败的,适用于类似于同步的效果,例如通知所有提供者更新缓存或日志等本地资源信息。
配置方式(二选其一即可)
服务消费者
@Reference(cluster = "failsafe")
private UserService userService;
或配置文件:
<dubbo:reference id=“helloService” interface=“com.test.dubbo.IHello” registry=“zookeeper” version=“2” cluster=“failover” retries=“2”/>
服务提供者
@Component //org.springframework.stereotype.Component
@Service(cluster = "failsafe") //com.alibaba.dubbo.config.annotation.Service
public class UserServiceImpl implements UserService {
...
}
二.dubbo服务降级
降级的目的是为了保证核心服务可用。
降级可以有几个层面的分类: 自动降级和人工降级;
按照功能可以分为:读服务降级和写服务降级;
1.对一些非核心服务进行人工降级,在大促之前通过降级开关关闭那些推荐内容、评价等对主流程没有影响的功能
2.故障降级,比如调用的远程服务挂了,网络故障、或者RPC服务返回异常。 那么可以直接降级,降级的方案比如设置默认值、采用兜底数据(系统推荐的行为广告挂了,可以提前准备静态页面做返回)等等
3.限流降级,在秒杀这种流量比较集中并且流量特别大的情况下,因为突发访问量特别大可能会导致系统支撑不了。这个时候可以采用限流来限制访问量。当达到阀值时,后续的请求被降级,比如进入排队页面,比如跳转到错误页(活动太火爆,稍后重试等)
第一种降级方式: dubbo的降级方式: Mock
Mock测试
1、客户端增加TestMock类实现IHello接口(要对哪个服务做降级就实现哪个接口)如下:
2、配置文件中接口声明中增加moke配置如下:
<dubbo:reference id="helloService" interface="com.test.dubbo.IHello" registry="zookeeper" version="2" cluster="failover" retries="2" mock="com.test.dubbo.TestMock" timeout="1000"/>
3、通过超时异常来模拟服务异常超时的场景。设置timeout 为1 访问服务肯定会超时 ,超时后将执行TestMock中的实现 来降级。当服务端故障解除以后(timeout设置为1000),调用过程将恢复正常
如下:
第二种降级方式:
- 在dubbo-admin中进行动态配置来事项降级
其中动态配置中的参数可以定义超时时间
这里可以使用debug测试,让服务超时,很快消费者会报错
这里的mock值,这里有容错和屏蔽两个选择
屏蔽(mock=force):
mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响
消费者放直接返回null不远程调用服务
容错(mock=fail)
还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
如果调用失败后返回null
三.Dubbo服务降级与整合Hystrix实现断路器
Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。
演示代码,只显示重要部分,全部代码文章末尾有代码下载地址
3.1新建Maven项目

3.2dubbo-spring-boot-hystrix
3.2.1 pom.xml
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.niugang</groupId>
<artifactId>dubbo-spring-boot-hystrix</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!--dependencyManagement父类工程管理包 -->
<dependencyManagement>
<dependencies>
<!--引入springboot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--引入springcloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>dubbo-spring-boot-hystrix-api</module>
<module>dubbo-spring-boot-hystrix-provider</module>
<module>dubbo-spring-boot-hystrix-consumer</module>
</modules>
</project>
3.3dubbo-spring-boot-hystrix-provider
3.3.1pom.xml
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.niugang</groupId>
<artifactId>dubbo-spring-boot-hystrix</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-spring-boot-hystrix-provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入dubbo 集成springboot starter -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.niugang</groupId>
<artifactId>dubbo-spring-boot-hystrix-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--服务降级服务容错 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
</project>
3.3.2 对外暴露RPCs实现类
package org.niugang.service;
import java.util.Random;
import org.springframework.stereotype.Component;
import com.alibaba.dubbo.config.annotation.Service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
/**
*
* @ClassName: DefaultDemoService
* @Description:对外暴露接口实现类
* @author: niugang
* @date: 2018年8月17日 下午7:50:47
* @Copyright: 863263957@qq.com. All rights reserved.
*
*/
// demo.service.version 在application.properties中配置过了
@Service // dubbo注解
@Component
@Service // dubbo注解
@Component
public class DefaultServiceImpl implements DefaultApiService {
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") })
public String defaultMethod(String str) {
/*
* Hystrix超时配置的为2s,当实现类睡眠超过2s,服务调用者将执行服务降级函数
*/
int nextInt = new Random().nextInt(4000);
System.out.println("sleep " + nextInt + "ms");
try {
Thread.sleep(nextInt);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "HELLO " + str + " from Dubbo Spring Boot";
}
}
3.4 dubbo-spring-boot-hystrix-consumer
3.4.1 pom.xml
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.niugang</groupId>
<artifactId>dubbo-spring-boot-hystrix</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-spring-boot-hystrix-consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<!--redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--引入对外暴露的rpc -->
<dependency>
<groupId>org.niugang</groupId>
<artifactId>dubbo-spring-boot-hystrix-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--服务降级服务容错 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
</project>
3.4.2调用服务提供者
/**
* 引入服务提供者
*/
// com.alibaba.dubbo.config.annotation.Reference
@Reference
private DefaultApiService demoService;
@RequestMapping("/sayHello")
@HystrixCommand(fallbackMethod = "failBackMethod")
public String sayHello(@RequestParam String name) {
return demoService.defaultMethod(name);
}
/**
* 服务降级
* @param name
* @return
*/
public String failBackMethod(String name) {
return "service request fail";
}
5.结果
5.1成功调用
5.2失败调用