查看之前的博客可以点击顶部的【分类专栏】
什么是服务熔断?
高并发的情况下,某一台服务器请求过大,导致服务异常,这时候 Hystrix 就触发熔断机制:所谓的熔断机制,就是将所有的请求转到 fallback 方法上,以保持整体的系统可用。
Hystrix 触发熔断是有条件的,默认情况下,它检测到10秒内请求的失败率超过50%,就触发熔断机制。每隔5秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求。
在前面的基础上,我们修改 order- server 的代码。
增加 Hystrix 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
ProductService 代码如下:我们模拟请求异常情况。if(id == i){throw new RuntimeException}
package com.study.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import com.study.api.ProductAPI;
import com.study.entity.ProductEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author biandan
* @description
* @signature 让天下没有难写的代码
* @create 2021-06-20 上午 2:01
*/
@Service
public class ProductService {
@Autowired
private ProductAPI productAPI;
SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//请求缓存:@Cacheable(cacheNames = "order:product",key = "#id") //Cacheable中cacheNames表示存储的key,id是传递的id值
//服务熔断
@HystrixCommand(
commandProperties = {
//10秒内请求大于10个就启动熔断器,当请求符合熔断条件触发 fallback 。默认20个
@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,
value = "10"),
//请求错误率大于 50% 就启动熔断器,然后 for 循环发起重试请求,当请求符合熔断条件触发 fallback 。
@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,
value = "50"),
//熔断多少秒后去重试请求,默认5秒
@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,
value = "5000")
},fallbackMethod = "getProductByIdFallback"
)
public ProductEntity getProductById(Integer id){
System.out.println("请求 getProductById:"+SDF.format(new Date()));
//模拟异常
if(id == 1){
throw new RuntimeException("查询 id=1 的商品出现异常!");
}
ProductEntity product = productAPI.getById(id);
return product;
}
//熔断方法
public ProductEntity getProductByIdFallback(Integer id){
System.out.println("**走托底接口*** "+SDF.format(new Date()));
ProductEntity product = new ProductEntity();
product.setId(2550);
product.setProductName("托底数据-熔断产品");
product.setPrice(new Float(1.25));
return product;
}
}
在启动类增加注解 @EnableHystrix //开启 Hystrix
然后我们重启 order-server 然后请求服务:http://127.0.0.1:9090/order/1 不断的刷新(长按 F5),查看控制台。
测试可知,在前面的请求中,因为遇到了异常,直接返回托底数据,熔断机制触发后,5秒之内所有的请求直接走托底数据的接口,而不会去请求正常的入口。然后每隔5秒之后,要是有请求进来,先尝试走正常的入口,如果还是报错,就走托底接口。说明我们的 Hystrix 熔断机制已经被触发。
服务降级
在高并发情况下,当某个服务不可用,使用 fallback 方法直接返回一个友好的错误提示(托底数据),防止用户一直等待,提高用户的体验感。
默认触发条件:
1、方法抛出 HystrixBadRequestException
2、方法调用超时
3、熔断器开启拦截调用
4、线程池、队列、信号量已满。
实现方式是所有方案中最简单的一种,只需要一个注解和一个 fallback 方法即可,我们直接使用 Hystrix 默认的降级机制。修改 order-server 的 ProductService 代码。
重启,测试:
说明触发了 Hystrix 的降级机制。