Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布是系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性
通过断路器的故障监控,向调用方返回一个符合预期的、可处理的备选响应(Fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的的线程不会被长时间、不必要的占用,从而避免对了故障在分布式系统中分蔓延、雪崩
比如当某个服务繁忙,不能让客户端的请求一直等待,应该立刻返回给客户端一个备选方案
哪些情况可能出现降级:
先模拟场景
server:
port: 8001
spring:
application:
name: cloud-provider-hystrix-payment
eureka:
client:
register-with-eureka: true # true向服务中心注册自己
fetch-registry: true # 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
service-url:
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka # 注册地址和端口
instance:
instance-id: payment-hystrix-8001
prefer-ip-address: true # 访问路径可以显示IP地址
5
秒【paymentInfo_TimeOut】@EnableEurekaClient
注解,注册进Eureka注册中心此时再建一个客户端模块cloud-consumer-feign-hystrix-order80,模拟在服务提供者自身承载着比较大的压力的情况下,此时消费者也来调用服务的场景
server:
port: 80
eureka:
client:
register-with-eureka: false # true向服务中心注册自己
service-url:
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka # 注册地址和端口
#记得配置这两个属性,否则会发生超时异常
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
@EnableFeignClients
注解@Component
@FeignClient(value = "cloud-provider-hystrix-payment")
public interface PaymentHystrixService {
@GetMapping("payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
@RestController
@Slf4j
public class OrderHystrixController {
@Resource
private PaymentHystrixService paymentHystrixService;
@GetMapping("consumer/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id){
return paymentHystrixService.paymentInfo_OK(id);
}
@GetMapping("consumer/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
return paymentHystrixService.paymentInfo_TimeOut(id);
}
}
对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
对方服务(8001)宕机了,调用者(80)不能一直卡死等待,必须有服务降级
对方服务(8001)没问题,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者,自己处理降级)
@HystrixCommand
,启用服务降级,并添加降级方法paymentInfo_TimeOut_Handler
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOut_Handler", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
})
fallbackMethod
表示降级的方法的方法名(自定义),commandProperties后面部分表示,设置自身调用超时时间的峰值为3秒,峰值内可以正常运行,超过了需要有兜底的方法处理,做服务降级fallback
2. 在主启动类上添加@EnableCircuitBreaker
注解,激活服务降级
3. 8001自测,是否因为休眠导致超时或者发生异常,就会服务降级,执行fallback方法。
feign:
hystrix:
enabled: true
@EnableHystrix
注解@HystrixCommand
注解,并定义降级方法paymentTimeOutFallbackMethod
@GetMapping("consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
})
上述的做法存在的问题:
@DefaultProperties(defaultFallback="方法名")
,这样,除了个别专门配置了降级方法的,其他只有@HystrixCommand
这一个注解(注解后没其他属性)标注的方法,都可以通过defaultFallback指定的方法来做统一的处理(服务提供端与服务消费方操作一样)feign.hystrix.enabled=true
,然后在接口
的@FeignClient的
注解中添加一个fallback属性的配置@FeignClient(value = “cloud-provider-hystrix-payment”, ·fallback =PaymentFallbackService.class
)。@HystrixCommand
注解了,如果加了,@HystrixCommand
的优先级更高一些。当某个服务出现问题卡死了,不能让用户一直等待,需要关闭所有对此服务的访问,然后调用服务降级
// 服务熔断
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),// 是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// 请求次数峰值
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),// 时间窗口期,失败后等待多久再进行重试,单位为毫秒
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")// 失败率达到多少后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id){
if(id < 0){
throw new RuntimeException("=============id不能为负数============");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName()+"\t"+"调用成功,流水号为"+serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
return "id不能为负数,请稍后再试,id为"+id;
}
属性配置在这个类中可以查看
com.netflix.hystrix.HystrixCommandProperties
2. 在controller中调用
3. 测试:大量调用会产生异常的方法,马上请求调用正常的方法,会发现熔断器打开,没法调用正常的方法,但会慢慢恢复
熔断开启的条件
一段时间后(默认5秒),这个时候熔断器是半开状态,会让其中一个请求进行转发,如果成功,断路器会关闭,如果失败,继续开启,重新计时。
熔断整体流程:
断路器逻辑
限流,比如秒杀场景,不能让用户瞬间都访问服务器,限制一次只可以有多少请求
后面学习sentinal时再总结
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
server:
port: 9001
@EnableHystrixDashboard
注解http://localhost:9001/hystrix
/**
* 此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
* ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream"
* 只要在自己的项目里配置上下面的servlet就可以了
* I
*/
@Bean
public ServletRegistrationBean getservlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsstreamServlet");
return registrationBean;
}
填入监控服务的IP+端口/hystrix.stream
对cloud-provider-hystrix-payment8001
的访问都可以在Dashboard上监控到
END
本文地址:https://blog.csdn.net/K_kzj_K/article/details/107360512
如对本文有疑问, 点击进行留言回复!!
3年以上Android开发的中高级面试宝典(准备金九银十,大厂直通)
网友评论