Spring Cloud H (五)初战服务降级和熔断Hystrix(豪猪哥)
目录
目录
前言
概述
服务雪崩
服务限流
服务降级
服务熔断
如何理解服务降级和熔断之间的关系
代码实战
Hystrix支付微服务构建
订单微服务调用支付服务出现卡顿
Hystrix之服务降级支付侧fallback
Hystrix之服务降级订单侧fallback
Hystrix之全局服务降级DefaultProperties
Hystrix之通配服务降级FeignFallback
Hystrix之服务熔断案例
Hystrix图形化Dashboard搭建
参考
前言
Hystrix是Netflix的一个开源框架,地址如下:官网
中文名为“豪猪”,即平时很温顺,在感受到危险的时候,用刺保护自己;在危险过去后,还是一个温顺的肉球。
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
"断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
所以整个框架的核心业务也就是这两点:何时需要保护和如何保护
概述
分布式系统需要面对的问题
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。
服务雪崩
假设存在上述服务调用链。在此时服务A的流量的波动很大,流量将常会突然性的增加。那么在这种情况下,就算是服务A抗住了流量的压力,服务B和服务C也不一定扛得住。
假设服务C没有抗住这么大的压力而变得不可用。那么紧接着服务B的请求也会被堵塞,慢慢耗尽服务B的线程资源,服务B慢慢也会变得不可用。紧接着服务A也会变得不可用。那么就像是这样一个服务的失败会导致整条链路的服务都失败的情形我们称之为服务雪崩。
那么我们的服务降级和服务熔断就是解决服务雪崩的手段之一。
服务限流
秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行。
服务降级
什么时候需要服务降级?
当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!
服务A需要调用服务B,但是当这个调用失败达到一定阈值的时候,服务A就不会再调用服务B了,而是回去执行本地的降级方法。 对于这么一套机制:在Spring cloud中结合Hystrix,将其称为熔断降级!
通俗一点讲解它的原理就是服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback。
服务熔断
当下游的服务器因为某种原因变得不可用或者响应过慢,上游的服务器为了保证自身的正常运转,不在调用下游的这个目标服务器,而是之间返回从而达到快速释放资源。如果目标服务的运转情况好转的话则慢慢恢复调用。
那么这套熔断机制的设计,基本上业内用的是断路器模式
,如Martin Fowler
提供的状态转换图如下所示
1.熔断关闭状态(Closed)
服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制。
2.熔断开启状态(Open)
在固定时间内(Hystrix默认是10秒),接口调用出错比率达到一个阈值(Hystrix默认为50%),会进入熔断开启状态。进入熔断状态后, 后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法。
3.半熔断状态(Half-Open)
在进入熔断开启状态一段时间之后(Hystrix默认是5秒),熔断器会进入半熔断状态。所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。
业内目前流行的熔断器很多,例如阿里出的Sentinel,以及最多人使用的Hystrix。
如何理解服务降级和熔断之间的关系
其实应该这样理解
服务降级有很多种降级方式!如开关降级、限流降级、熔断降级!
服务熔断属于降级方式的一种!
代码实战
Hystrix支付微服务构建
将cloud-eureka-server7001改配置成单机版,取消集群配置
(1)建moudle——新建cloud-provider-hygtrix-payment8001
(2)改POM
<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>cloud2020</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-provider-hystrix-payment8001</artifactId><dependencies><!--hystrix--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><!--eureka client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies></project>
(2)写YML
server:port: 8001spring:application:name: cloud-provider-hystrix-paymenteureka:client:register-with-eureka: truefetch-registry: trueservice-url:#defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eurekadefaultZone: http://eureka7001.com:7001/eureka
(4)主启动
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;/***/
@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8001
{public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class, args);}
}
(5)业务类
service
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;/***/
@Service
public class PaymentService {/***/public String paymentInfo_OK(Integer id){return "线程池: "+Thread.currentThread().getName()+" paymentInfo_OK,id: "+id+"\t"+"O(∩_∩)O哈哈~";}public String paymentInfo_TimeOut(Integer id){try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }return "线程池: "+Thread.currentThread().getName()+" id: "+id+"\t"+"O(∩_∩)O哈哈~"+" 耗时(秒): 3";}
}
controller
import com.lun.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/***/
@RestController
@Slf4j
public class PaymentController
{@Resourceprivate PaymentService paymentService;@Value("${server.port}")private String serverPort;@GetMapping("/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentService.paymentInfo_OK(id);log.info("*****result: "+result);return result;}@GetMapping("/payment/hystrix/timeout/{id}")public String paymentInfo_TimeOut(@PathVariable("id") Integer id){String result = paymentService.paymentInfo_TimeOut(id);log.info("*****result: "+result);return result;}
}
测试:
访问
- http://localhost:8001/payment/hystrix/ok/1
- http://localhost:8001/payment/hystrix/timeout/1
订单微服务调用支付服务出现卡顿
(1)建Moudle——cloud-consumer-feign-hystrix-order80
(2)POM
<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>LearnCloud</artifactId><groupId>com.lun.springcloud</groupId><version>1.0.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-consumer-feign-hystrix-order80</artifactId><dependencies><!--openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--hystrix--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><!--eureka client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.lun.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--一般基础通用配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies></project>
(3)YML
server:port: 80eureka:client:register-with-eureka: falseservice-url:defaultZone: http://eureka7001.com:7001/eureka/
(4)主启动
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;/***/
@SpringBootApplication
@EnableFeignClients
//@EnableHystrix
public class OrderHystrixMain80
{public static void main(String[] args){SpringApplication.run(OrderHystrixMain80.class,args);}
}
(5)业务类
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/***/
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" /*,fallback = PaymentFallbackService.class*/)
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);
}
import com.lun.springcloud.service.PaymentHystrixService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@Slf4j
public class OrderHystirxController {@Resourceprivate PaymentHystrixService paymentHystrixService;@GetMapping("/consumer/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentHystrixService.paymentInfo_OK(id);return result;}@GetMapping("/consumer/payment/hystrix/timeout/{id}")public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {String result = paymentHystrixService.paymentInfo_TimeOut(id);return result;}
}
测试
7.高并发测试
2W个线程压8001
消费端80微服务再去访问正常的Ok微服务8001地址
http://localhost/consumer/payment/hystrix/ok/32
消费者80被拖慢
原因:8001同一层次的其它接口服务被困死,因为tomcat线程池里面的工作线程已经被挤占完毕。
Hystrix之服务降级支付侧fallback
设置自身调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法处埋,作服务降级fallback。—旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。
@Service
public class PaymentService{@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler"/*指定善后方法名*/,commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")})public String paymentInfo_TimeOut(Integer id){//int age = 10/0;try { TimeUnit.MILLISECONDS.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }return "线程池: "+Thread.currentThread().getName()+" id: "+id+"\t"+"O(∩_∩)O哈哈~"+" 耗时(秒): ";}//用来善后的方法public String paymentInfo_TimeOutHandler(Integer id){return "线程池: "+Thread.currentThread().getName()+" 8001系统繁忙或者运行报错,请稍后再试,id: "+id+"\t"+"o(╥﹏╥)o";}}
//上面故意制造两种异常://int age = 10/0,计算异常
//我们能接受3秒钟,它运行5秒钟,超时异常。
//当前服务不可用了,做服务降级,兜底的方案都是paymentInfo_TimeOutHandler
主启动类激活——添加新注解@EnableCircuitBreaker
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker//添加到此处
public class PaymentHystrixMain8001{public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class, args);}
}
Hystrix之服务降级订单侧fallback
80订单微服务,也可以更好的保护自己,自己也依样画葫芦进行客户端降级保护
server:port: 80eureka:client:register-with-eureka: falseservice-url:defaultZone: http://eureka7001.com:7001/eureka/#开启
feign:hystrix:enabled: true
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableFeignClients
@EnableHystrix//添加到此处
public class OrderHystrixMain80{public static void main(String[] args){SpringApplication.run(OrderHystrixMain80.class,args);}
}
import com.lun.springcloud.service.PaymentHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@Slf4j
public class OrderHystirxController {@Resourceprivate PaymentHystrixService paymentHystrixService;@GetMapping("/consumer/payment/hystrix/timeout/{id}")@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")})public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {//int age = 10/0;String result = paymentHystrixService.paymentInfo_TimeOut(id);return result;}//善后方法public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o";}}
Hystrix之全局服务降级DefaultProperties
目前问题1 每个业务方法对应一个兜底的方法,代码膨胀
解决方法
1:1每个方法配置一个服务降级方法,技术上可以,但是不聪明
1:N除了个别重要核心业务有专属,其它普通的可以通过@DefaultProperties(defaultFallback = “”)统一跳转到统一处理结果页面
通用的和独享的各自分开,避免了代码膨胀,合理减少了代码量
import com.lun.springcloud.service.PaymentHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystirxController {@Resourceprivate PaymentHystrixService paymentHystrixService;@GetMapping("/consumer/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentHystrixService.paymentInfo_OK(id);return result;}@GetMapping("/consumer/payment/hystrix/timeout/{id}")
// @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
// @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
// })@HystrixCommand//用全局的fallback方法public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {//int age = 10/0;String result = paymentHystrixService.paymentInfo_TimeOut(id);return result;}public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o";}// 下面是全局fallback方法public String payment_Global_FallbackMethod(){return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~";}
}
Hystrix之通配服务降级FeignFallback
目前问题2 统一和自定义的分开,代码混乱
服务降级,客户端去调用服务端,碰上服务端宕机或关闭
本次案例服务降级处理是在客户端80实现完成的,与服务端8001没有关系,只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦
未来我们要面对的异常
运行
超时
宕机
修改cloud-consumer-feign-hystrix-order80
根据cloud-consumer-feign-hystrix-order80已经有的PaymentHystrixService接口,
重新新建一个类(AaymentFallbackService)实现该接口,统一为接口里面的方法进行异常处理
PaymentFallbackService类实现PaymentHystrixService接口
import org.springframework.stereotype.Component;@Component
public class PaymentFallbackService implements PaymentHystrixService
{@Overridepublic String paymentInfo_OK(Integer id){return "-----PaymentFallbackService fall back-paymentInfo_OK ,o(╥﹏╥)o";}@Overridepublic String paymentInfo_TimeOut(Integer id){return "-----PaymentFallbackService fall back-paymentInfo_TimeOut ,o(╥﹏╥)o";}
}
YML
server:port: 80eureka:client:register-with-eureka: falseservice-url:defaultZone: http://eureka7001.com:7001/eureka/#开启
feign:hystrix:enabled: true
PaymentHystrixService接口
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,//fallback = PaymentFallbackService.class)//指定PaymentFallbackService类
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);
}
Hystrix之服务熔断案例
修改cloud-provider-hystrix-payment8001
import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;import java.util.concurrent.TimeUnit;@Service
public class PaymentService{ ...//=====服务熔断@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 不能负数,请稍后再试,/(ㄒoㄒ)/~~ id: " +id;}}
HystrixCommandProperties配置类
package com.netflix.hystrix;...public abstract class HystrixCommandProperties {private static final Logger logger = LoggerFactory.getLogger(HystrixCommandProperties.class);/* defaults *//* package */ static final Integer default_metricsRollingStatisticalWindow = 10000;// default => statisticalWindow: 10000 = 10 seconds (and default of 10 buckets so each bucket is 1 second)private static final Integer default_metricsRollingStatisticalWindowBuckets = 10;// default => statisticalWindowBuckets: 10 = 10 buckets in a 10 second window so each bucket is 1 secondprivate static final Integer default_circuitBreakerRequestVolumeThreshold = 20;// default => statisticalWindowVolumeThreshold: 20 requests in 10 seconds must occur before statistics matterprivate static final Integer default_circuitBreakerSleepWindowInMilliseconds = 5000;// default => sleepWindow: 5000 = 5 seconds that we will sleep before trying again after tripping the circuitprivate static final Integer default_circuitBreakerErrorThresholdPercentage = 50;// default => errorThresholdPercentage = 50 = if 50%+ of requests in 10 seconds are failures or latent then we will trip the circuitprivate static final Boolean default_circuitBreakerForceOpen = false;// default => forceCircuitOpen = false (we want to allow traffic)/* package */ static final Boolean default_circuitBreakerForceClosed = false;// default => ignoreErrors = false private static final Integer default_executionTimeoutInMilliseconds = 1000; // default => executionTimeoutInMilliseconds: 1000 = 1 secondprivate static final Boolean default_executionTimeoutEnabled = true;...
}
@RestController
@Slf4j
public class PaymentController
{@Resourceprivate PaymentService paymentService;...//====服务熔断@GetMapping("/payment/circuit/{id}")public String paymentCircuitBreaker(@PathVariable("id") Integer id){String result = paymentService.paymentCircuitBreaker(id);log.info("****result: "+result);return result;}
}
Hystrix图形化Dashboard搭建
除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。
Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。
(1)新建moudel——cloud-consumer-hystrix-dashboard9001
(2)pom
<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>LearnCloud</artifactId><groupId>com.lun.springcloud</groupId><version>1.0.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-consumer-hystrix-dashboard9001</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies></project>
(3)yml
server:port: 9001
(4)HystrixDashboardMain9001+新注解@EnableHystrixDashboard
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001
{public static void main(String[] args) {SpringApplication.run(HystrixDashboardMain9001.class, args);}
}
(5)所有Provider微服务提供类(8001/8002/8003)都需要监控依赖配置
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
启动cloud-consumer-hystrix-dashboard9001该微服务后续将监控微服务8001
浏览器输入http://localhost:9001/hystrix
(1)修改cloud-provider-hystrix-payment8001
注意:新版本Hystrix需要在主启动类PaymentHystrixMain8001中指定监控路径
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001
{public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class, args);}/***此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑*ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",*只要在自己的项目里配置上下面的servlet就可以了*否则,Unable to connect to Command Metric Stream 404*/@Beanpublic ServletRegistrationBean getServlet() {HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);registrationBean.setLoadOnStartup(1);registrationBean.addUrlMappings("/hystrix.stream");registrationBean.setName("HystrixMetricsStreamServlet");return registrationBean;}
}
9001监控8001 - 填写监控地址 - http://localhost:8001/hystrix.stream 到 http://localhost:9001/hystrix页面的输入框。
测试地址
http://localhost:8001/payment/circuit/1
http://localhost:8001/payment/circuit/-1
测试通过
先访问正确地址,再访问错误地址,再正确地址,会发现图示断路器都是慢慢放开的。
————————————————
版权声明:本文为CSDN博主「巨輪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011863024/article/details/114298282
参考
https://mp.weixin.qq.com/s?src=11×tamp=1625747199&ver=3178&signature=LXKUbPcfuBH*xcEoc*EvAw6*9NMBAZuB*u1lr9WCIPs159Pi9ZE*ykX-kNOTGu-vPs3n6WPibYXL2v8DJxCzn0XbdLIQ5k7uUJYoq1vQxu1ANF-mCEakQDLaYVWeCSuo&new=1
Spring Cloud H (五)初战服务降级和熔断Hystrix(豪猪哥)相关推荐
- Spring Cloud入门-Sentinel实现服务限流、熔断与降级(Hoxton版本)
文章目录 Spring Cloud入门系列汇总 摘要 Sentinel简介 安装Sentinel控制台 创建sentinel-service模块 限流功能 创建RateLimitController类 ...
- 用Spring Cloud Alibaba开发微服务会更香吗?
关注DD,除了前沿消息,还有每周福利哦 Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案,它是Spring Cloud组件被植入Alibaba元素之后的产物. 利用Spri ...
- 《深入理解 Spring Cloud 与微服务构建》第十七章 使用 Spring Cloud OAuth2 保护微服务系统
<深入理解 Spring Cloud 与微服务构建>第十七章 使用 Spring Cloud OAuth2 保护微服务系统 文章目录 <深入理解 Spring Cloud 与微服务构 ...
- Spring Cloud(5)---基于 Spring Cloud 完整的微服务架构实战
基于 Spring Cloud 完整的微服务架构实战 技术栈 Spring boot - 微服务的入门级微框架,用来简化 Spring 应用的初始搭建以及开发过程. Eureka - 云端服务发现,一 ...
- Spring Cloud Hoxton 版本微服务项目搭建 admin 监控客户端
Spring Cloud Hoxton 版本微服务项目搭建 admin 监控客户端 前言 在上一篇文章博主已经讲解了admin 管理中心服务项目如何创建,不会的话可以前往学习,传送门:Spring C ...
- Spring Cloud H SR5集成 Jaeger
Spring Cloud H SR5 集成Jaeger 该文章主要讲述Spring Cloud H SR5集成 opentracing-spring-jaeger-cloud-starter 3.1. ...
- Spring Cloud Alibaba 分布式微服务高并发数据平台化(中台)思想+多租户saas企业开发架构技术选型和设计方案
基于Spring Cloud Alibaba 分布式微服务高并发数据平台化(中台)思想+多租户saas设计的企业开发架构,支持源码二次开发.支持其他业务系统集成.集中式应用权限管理.支持拓展其他任意子 ...
- Spring Cloud(一)服务的注册与发现(Eureka)
Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布式会话和集 ...
- Spring Cloud第二篇:服务消费者RestTemplate+Ribbon
在上一篇文章,讲了服务的注册和发现.在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的.Spring cloud有两种服务调用方式,一种是ribbon+r ...
最新文章
- Codeforces Round #323 (Div. 2) A. Asphalting Roads
- 配置免密码登录Linux服务器
- 黑客入侵“在线影院”全过程2
- Mastering Caching in Asp.net
- JVM调优总结 系列文章
- Duplicate methods named spliterator with the parameters () and () are inherited from the types Colle
- 存储过程和存储函数的区别
- 汉字区位码查询与算法
- QImage、QPainter绘图
- java开源bi_poli-java开源BI软件
- 使用SDK Manager给TX2刷机且安装OpenCV3.4.0、CUDNN7.6.5、Pytorch、Miniforge(含百度云安装包)
- 笔记-5:mysql数据更新
- Layer子域名挖掘机
- 利用rfcomm实现树莓派与手机通信_树莓派可以这样玩
- ArcEngine旋转IRotateTracker
- 矩阵分析与应用-05-向量空间、内积空间与线性映射02
- 【Docker】Docker进阶(二)
- linux sed 替换符号,linux sed 批量替换文件中的字符串或符号
- C#语言实例源码系列-实现加密exe文件
- MATLAB导入EXCEL数据D=xlsread()的一种情况