Springboot-微服务-微服务组件之服务管理-服务熔断雪崩-Hystrix-线程超时-时长配置
Springboot-微服务-微服务组件之服务管理-服务熔断雪崩-Hystrix-线程超时-时长配置
1.Hystrix
1.1.简介
Hystrix,即熔断器。
Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。
1.2.熔断器的工作机制:
正常工作的情况下,客户端请求调用服务API接口:
当有服务出现异常时,直接进行失败回滚,服务降级处理:
当服务繁忙时,如果服务出现异常,不是粗暴的直接报错,而是返回一个友好的提示,虽然拒绝了用户的访问,但是会返回一个结果。
这就好比去买鱼,平常超市买鱼会额外赠送杀鱼的服务。等到逢年过节,超时繁忙时,可能就不提供杀鱼服务了,这就是服务的降级。
系统特别繁忙时,一些次要服务暂时中断,优先保证主要服务的畅通,一切资源优先让给主要服务来使用,在双十一、618时,京东天猫都会采用这样的策略。
Hystrix 解决服务雪崩问题,主要手段有两个:
- 线程隔离
- 服务熔断和降级
原理分系:
Hystix 为每一个依赖的服务调用分配一个小的线程池,如果线程池满了,则调用会立即拒绝。默认不采用排队,加速失败判定时间
用户的请求不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池满,或者请求超时,则会降级处理。
———什么是服务的降级?———
服务降级:优先保证核心服务,而非核心服务不可用或者弱可用。
用户请求故障时,不会被阻塞,也不会永远等待,或者你看到了一个系统奔溃的信息,这些都不会出现,唯一出现就是你设置的一个友好的返回信息。
服务降级,虽然会导致请求失败,但是不会阻塞,最多就是依赖这个服务对应的线程资源,对其它服务没有响应。
降级一般使用的地方
一般在服务的消费方,会去做服务的降级处理
入门操作
要点
-
引入Hystrix相关依赖
-
添加注解 @EnableHystrix / @EnableCircuitBreaker 这个两个注解都可以
-
在control 配置相关参数的配置,例如配置注解,超时时长。
引入引入Hystrix相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
在Spring启动类上添加注解
一个标准的eureka标准的客户端都需要配置以上三个注解,所以Spring 提供一个新的注解SpringCloudApplication包含的以上三个注解
package com.caicai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
//@EnableDiscoveryClient//开启eureka服务端的调用
//@SpringBootApplication
//@EnableCircuitBreaker //添加Hystrix
//@EnableHystrix
@SpringCloudApplication // 一个标准的eureka标准的客户端都需要配置以上三个注解,所以Spring 提供一个新的注解SpringCloudApplication包含的以上三个注解
public class ConsumerServiceApplication {
//Spring boot 调用的接口都是rest风格的接口,这里我们使用,Spring 自带的resTemplate 去调用,它包含了:http,post 等等
@Bean
@LoadBalanced//开启负载均衡注解
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class);
}
}
在control 配置相关参数的配置
配置要点
-
编写超时回调方法
-
配置所有方法的默认降级逻辑,在类上配置@DefaultProperties注解
-
回调方法类型,要和调用方法的类型要保持一致
-
针对某一个方法,配置单一的超时时长
-
配置全局的默认超时,时长。(在yml配置文件中,配置)
package com.caicai.Consumer.Control;
import com.caicai.Consumer.po.User;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("consumer")
@DefaultProperties(defaultFallback = "default_Fallback")//为所有方法添加降级处理逻辑
public class ConsumerControl {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
// @HystrixCommand(fallbackMethod = "queryById_Fallback")
@HystrixCommand // 开启降级处理逻辑
// @HystrixCommand(commandProperties = {
//
// @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000")//设置超时时长
// }) //配置单个超时,时长
public String queryById(@PathVariable("id") Long id)
{
String url = "http://user-service/user/"+id;
String user = restTemplate.getForObject(url,String.class);
return user;
}
//一对一的处理逻辑方法
public String queryById_Fallback( Long id)
{
return "系统繁忙!,请稍后再试!";
}
//通用的降级处理逻辑方法
public String default_Fallback()
{
return "系统繁忙!,请稍后再试!";
}
}
配置默认全局超时,时长
要点1: 该段时长,默认没有提示,需要手工去填写。
要点2: 可以针对某个服务或者方法配置相关时长
hystrix:
command:
default: #这里,填写服务名称/方法
execution:
isolation:
thread:
timeoutInMilliseconds: 3000