文章目录
-
-
- SpringCloud整合Hystrix熔断器
-
- 1、什么是Hystrix?
- 2、服务调用雪崩
- 3、线程隔离和服务降级
-
- ①线程隔离原理
- ②服务降级
- 4、实现Hystrix服务降级★
-
- ①导入springCloud的Hystrix依赖
- ②注解启动类开启熔断
- ③服务降级处理演示
-
- 1>针对方法进行服务降级
- 2>针对整个类进行服务降级
- ④配置服务降级超时时间
- 5、Hystrix服务熔断★
-
- ①服务熔断原理
- ②服务熔断模型
- ③服务熔断处理演示
-
SpringCloud整合Hystrix熔断器
1、什么是Hystrix?
Hystrix是开源的延迟和容错库,用于隔离访问远程服务,第三方库,放置出现级联失败。
2、服务调用雪崩
微服务中,服务间的调用关系错综复杂,一个请求,可能需要调用多个微服务接口才能实现,会形成非常复杂的调用链路,**一旦其中的某个服务出现问题,就会造成整个请求失败,调用的过程就会等待,请求阻塞,用户请求得不到响应,则tomcat的这个线程不会释放,于是越来越多的请求到来,就会有越来越多的请求阻塞。请求一直阻塞导致服务器资源耗尽。**这就是雪崩问题。
Hystrix使用服务降级解决雪崩问题。一旦某一个服务请求超时就进行服务降级,返回给用户一个类似网络拥堵的提示。
Hystrix解决雪崩问题主要就是服务降级,包括:
- 线程隔离: 用户请求不直接访问服务,而是使用线程池中空闲的线程访问服务,加速访问失败判断的时间。
- 服务降级: 及时返回服务调用失败的结果,让线程不因为等待服务而阻塞。
3、线程隔离和服务降级
①线程隔离原理
线程池中存在空闲的线程,就使用空闲的线程去访问服务,一旦线程耗尽,就直接返回拥堵状态。Hystrix为每个依赖调用分配一个小的线程池,如果线程池已满调用将立即被拒绝,默认不采用排队,加速失败的判断时间。
②服务降级
用户 请求故障时候,不会被阻塞,更不会无休止的等待或者看到系统崩溃,至少可以看到一个执行结果(例如返回预先设定好的提示信息)。
服务降级虽然会导致请求的失败,但是不会导致阻塞,而且最多会影响这个依赖服务对应的线程池中的资源,对其他服务没有影响。
服务降级:有限保证核心服务,而非核心服务不可用或者弱可用。
服务降级的触发情况:
- 线程池已满
- 请求超时
4、实现Hystrix服务降级★
以下默认已经完成了eureka、feign,以及其他相关的业务操作。
示例为:ORDER服务远程调用PRODUCT服务进行服务降级。
①导入springCloud的Hystrix依赖
<!--Hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<!--在同一版本管理中,版本号可以不写-->
<version>2.1.5.RELEASE</version>
</dependency>
②注解启动类开启熔断
/**
*@SpringCloudApplication注解==>
* @EnableCircuitBreaker:开启熔断
* @SpringBootApplication:声明启动类
* @EnableDiscoveryClien:声明Eureka客户端
*/
@EnableFeignClients //声明这是一个EnableFeignClients的客户端,必须要有
@EnableDiscoveryClient //声明这是一个Eureka客户端
@SpringBootApplication
@EnableCircuitBreaker //开启Hystrix的熔断
//@SpringCloudApplication
public class UdaiOrderApplication {
public static void main(String[] args) {
SpringApplication.run(UdaiOrderApplication.class, args);
}
}
③服务降级处理演示
1>针对方法进行服务降级
ORDER服务:
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private ProductControllerApi productControllerApi;
/**
* 订单中查询商品信息,调用商品服务。
* @param productId
* @return
*/
@RequestMapping("getProductInfoById")
@HystrixCommand(fallbackMethod = "hystrixFallback") //注解设置服务降级的回调方法
public JsonBean getProductInfoById(@RequestParam("productId") Integer productId) {
System.out.println("进入ORDER服务,getProductFromProduct" + productId);
return productControllerApi.getProductInfoById(productId);
}
/**
* 服务降级执行的方法:必须给一个和请求接口相同的参数以及相同的返回值
* @return
*/
public JsonBean hystrixFallback(Integer productId) {
return new JsonBean(0, "温馨提示:网络拥堵,请稍后再试:" + productId, null);
}
}
1、方法服务降级是在调用的接口上面加上注解@HystrixCommand(fallbackMethod = “hystrixFallback”)并指定fallbackMethod 参数值,去实现这个方法。
2、服务降级的方法必须同调用的接口有相同的参数以及返回值。
当前接口服务降级结果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1gTNwUDM0ATM5EjNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2>针对整个类进行服务降级
ORDER服务全局默认降级:
@RestController
@RequestMapping("order")
@DefaultProperties(defaultFallback = "defaultFallback") //默认服务降级调用的方法
public class OrderController {
@Autowired
private ProductControllerApi productControllerApi;
/**
* 订单中查询商品信息,调用商品服务。
*
* @param productId
* @return
*/
@RequestMapping("getProductInfoById")
//@HystrixCommand(fallbackMethod = "hystrixFallback") //注解设置服务降级的回调方法
@HystrixCommand
public JsonBean getProductInfoById(@RequestParam("productId") Integer productId) {
System.out.println("进入ORDER服务,getProductFromProduct" + productId);
return productControllerApi.getProductInfoById(productId);
}
/**
* 服务降级执行的方法:必须给一个和请求接口相同的参数以及相同的返回值
*
* @return
*/
public JsonBean hystrixFallback(Integer productId) {
return new JsonBean(0, "温馨提示:网络拥堵,请稍后再试:" + productId, null);
}
/**
* 默认服务降级
* @return
*/
public JsonBean defaultFallback() {
return new JsonBean(0, "默认温馨提示:网络拥堵,请稍后再试", null);
//return "温馨提示:网络拥堵,请稍后再试"; //返回类型必须和方法一致
}
}
1、全局服务降级,是在类上面加注解@DefaultProperties(defaultFallback = “defaultFallback”),并指定defaultFallback 参数的值,去在当前类实现这个方法。并在需要降级的方法上面加上注解@HystrixCommand不配置任何参数。
2、与方法上面的降级不同的是,这个默认降级不需要参数,但是需要相同的返回值类型。
当前接口使用全局服务降级结果:
④配置服务降级超时时间
不配置服务降级时间的话,Hystrix默认服务降级时间是一秒,时间太短了,需要在yml文件里面进行配置或者在注解中进行配置。
#此项内容也可以通过注解去设置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 #服务降级时间2秒
5、Hystrix服务熔断★
①服务熔断原理
在服务熔断中,使用熔断器,也叫作断路器(Circuit Breaker)。
Hystrix熔断的机制类似于电路短路熔断保护。在分布式系统应用中应用服务熔断后,服务可以自行判断哪些服务反应慢或者存在大量超市,可以针对这些服务进行熔断防止拖垮整个系统。
②服务熔断模型
-
Closed:
熔断器关闭状态。
-
Open:
熔断器打开转态。当失败请求达到阈值服务降级。
阈值:服务失败达到一定的值是,断路器将会打开。请求的次数最少不低于20次,当失败的请求占比50%,断路器打开。
-
Half Open:
熔断器半开,允许部分请求进行访问。熔断器打开后,休眠五秒(默认)进行半开,如果再次失败仍然会打开熔断器,成功后会关闭熔断器。
③服务熔断处理演示
模拟某一个请求是错误的,导致整个服务都降级请求不了:
请求getProductInfoById方法,productId=2,多次请求导致服务降级。导致其他成功的服务也随之降级。
http://localhost:8080/order/getProductInfoById?productId=2
@RestController
@RequestMapping("order")
@DefaultProperties(defaultFallback = "defaultFallback") //默认服务降级调用的方法
public class OrderController {
@Autowired
private ProductControllerApi productControllerApi;
/**
* 订单中查询商品信息,调用商品服务。
*
* @param productId
* @return
*/
@RequestMapping("getProductInfoById")
//@HystrixCommand(fallbackMethod = "hystrixFallback") //注解设置服务降级的回调方法
@HystrixCommand
public JsonBean getProductInfoById(@RequestParam("productId") Integer productId) {
//模拟某一个请求是错误的,导致整个服务都降级请求不了
if(productId == 2){
throw new RuntimeException("熔断测试");
}
System.out.println("进入ORDER服务,getProductFromProduct" + productId);
return productControllerApi.getProductInfoById(productId);
}
/**
* 服务降级执行的方法:必须给一个和请求接口相同的参数以及相同的返回值
*
* @return
*/
public JsonBean hystrixFallback(Integer productId) {
return new JsonBean(0, "温馨提示:网络拥堵,请稍后再试:" + productId, null);
}
/**
* 默认服务降级
* @return
*/
public JsonBean defaultFallback() {
return new JsonBean(0, "默认温馨提示:网络拥堵,请稍后再试", null);
//return "温馨提示:网络拥堵,请稍后再试";
}
}
productId=1成功的服务:
请求getProductInfoById方法,productId=1。
http://localhost:8080/order/getProductInfoById?productId=1
多次请求productId=2失败,导致productId=1服务降级:
修改服务熔断的默认配置:
#此项内容也可以通过注解去设置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 #服务降级时间2秒
circuitBreaker:
errorThresholdPercentage: 50 #触发熔断错误比例阈值,默认50%
sleepWindowInMilliseconds: 10000 #熔断后休眠时长,默认5秒
requestVolumeThreshold: 10 #熔断触发最小请求次数,默认值是20,修改为10