SpringCloud-整体学习(一)SpringCloud简介+版本选择
SpringCloud-整体学习(二)项目初始构建-加公共部分提取
SpringCloud-整体学习(三)Eureka、zookeeper、Consul(注册中心)
SpringCloud-整体学习(四)Ribbon(负载均衡+手写轮询算法)
SpringCloud-整体学习(五)OpenFeign(服务调用)
SpringCloud-整体学习(六)Hystrix(服务降级)
SpringCloud-整体学习(七)GateWay(服务网关)
SpringCloud-整体学习(八)Config、Bus、Stream(服务配置和消息交互)
为什么需要Hystrix
分布式面临的问题:
Hystrix是什么
相当于日常生活中的保险丝,可以在服务超时,或者失败率过高
该服务的断路器会打开。返回一个由开发者设定的fallback。
它可以做到:服务熔断(break)、服务降级(fallback)、接近实时的监控等。。。。
Hystrix停更进维
github :
https://github.com/Netflix/Hystrix/wiki
Hystrix的服务降级熔断限流概念初讲
服务降级(fallback):
服务器忙,请稍后再试,不让客户等待并立刻返回一个友好的提示
哪些情况会发生服务降级:
1、程序运行时异常
2、服务熔断触发服务降级
3、超时
4、线程池打满,也会导致服务降级
基本上就是服务器报错了。
服务熔断(break):
当达到最大服务访问量的时候,直接拒绝访问,调用服务降级的方法,返回友好提示。(A股熔断是一个道理- -)
服务限流(flowlimit):
秒杀高并发等操作,禁止一起全部过来。,一秒钟N个,有序进行。
Hystrix支付微服务构建
eureka恢复单机测试
构建cloud-provider-hystrix-payment8001
项目结构最后:
pom (其他跟之前的8001一致)
多加了下面的:
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
controller:
@Autowired
private 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;
}
Service:
/**
* 正常访问的方法
* @param id
* @return
*/
public String paymentInfo_OK(Integer id){
return "线程池: "+Thread.currentThread().getName()+"paymentInfo_OK,id :"+ id+"\t"+"成功访问";
}
public String paymentInfo_TimeOut(Integer id){
int time = 3;
try{
TimeUnit.SECONDS.sleep(time);
}catch (Exception e){
e.printStackTrace();
}
return "线程池: "+Thread.currentThread().getName()+"paymentInfo_TimeOut,id :"+ id+"\t"+"TimeOut调用成功 :耗时(秒)"+time;
}
main如果有url 连接相关错误 记得更改排除数据库连接的相关信息
@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class, DataSourceAutoConfiguration.class})
效果图:
JMeter高并发压测后卡顿
见视频:
主要目的是演示
同一个服务下 有不同的请求,如果一个请求压力过大,会对其他请求的访问造成影响。
订单微服务调用支付服务出现卡顿
新建cloud-provider-feign-hystrix-order80
pom(和之前的feign80项目的pom一致)
项目结构
yml:
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
启动类上记得加
@EnableFeignClients
service
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-SERVICE")
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 );
}
controller
@Autowired
private 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;
}
效果:
坑:
这个错误是默认的时间(和之前的ribbon类似)访问小于之前的3秒
ribbon:
# 指的是建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间
ConnectTimeout: 5000
类似这样的错误:
依次重启 7001 - 8001 80 再试一次
降级容错解决的维度要求
此时如果在2w左右的并发的情况下。80端口访问会有延迟访问的现象。
如果更大,可能会导致服务不可用。
目前可能会出现的问题:
超时访问到时服务器变慢(访问转圈) ----》超时不在等待
出错(宕机或者程序出错) – 不适合把500的错误信息页面输出的前端页面----》出错要有兜底的返回信息。
解决:
1、8001访问超时了 80 不在继续等待,要有服务降级
2、8001宕机了 80 不继续等待,要有服务降级
3、8001服务ok ,但是访问时间超过我想要的返回时间。(要有自我的时间要求)
自己处理降级。
Hystrix之服务降级支付侧fallback
在8001本身对外提供服务的时候就做处理
如果程序出错,或者超过本身设置的时间,就返回在@HystrixCommand注解中添加的方法返回信息。
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds" ,value = "3000")
})
public String paymentInfo_TimeOut(Integer id){
int time = 5;
int age = 10/0;
try{
TimeUnit.SECONDS.sleep(time);
}catch (Exception e){
e.printStackTrace();
}
return "线程池: "+Thread.currentThread().getName()+"paymentInfo_TimeOut,id :"+ id+"\t"+"TimeOut调用成功 :耗时(秒)"+time;
}
public String paymentInfo_TimeOutHandler(Integer id){
return "线程池: "+Thread.currentThread().getName()+"paymentInfo_TimeOutHandler,id :"+ id+"\t"+"兜底的返回";
}
服务降级一般配置在客户端的,但是原则上是都可以配置。
我觉得配置在客户端的原因是因为这样,可以更早的发现问题。
Hystrix之服务降级订单侧fallback
yml 添加:
feign:
hystrix:
enabled: true
main 添加:
@EnableHystrix
controller 改造(跟8001差不多。):
坑:
在我把两个调用时间都配置5000,但是调用时间只是sleep 3000了
的情况下,还是调用兜底方法。
当配置的超时间小于,调用服务的延迟时间就不会触发熔断机制。
#hystrix超时时间配置 (如果不配置的话默认是1000毫秒超时)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 10000
Hystrix之全局服务降级DefaultProperties
代码冗余问题,没有方法都需要兜底的方法就会冗余。
统一和自定义分开:
实现代码冗余的问题
@DefaultProperties(defaultFallback = “paymentGlobalFallbackMethod”)
在注解中的方法的参数类型也要一致
Hystrix之通配服务降级FeignFallback
新建一个类 实现service中的接口
实现代码业务逻辑混乱的问题
这样 在8001 没有启动的情况下(8001宕机)就会返回自己实现的
Hystrix之服务熔断理论
熔断是处理机制
降级是处理方法
熔断 —》 电路中的空开
Hystrix之服务熔断案例(上)
// 服务熔断
@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"), //错误率达到多少跳闸
})//10次请求里面有60%是错误的就熔断
HystrixCommandProperties
这个时候去测试就会发现
//10次请求里面有60%是错误的就熔断 -》就是输入正确也不行–》然后在慢慢的恢复
Hystrix图形化Dashboard搭建
新建 :
cloud-consumer-hystrix-dashboard9001
pom
<dependencies>
<!-- hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.lt.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<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>
yml
server:
port: 9001
效果
/**
* 此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
* ServletRegistrationBean因为SpringBoot的默认路径不是 “/hystrix.stream"
* 只要在自己的项目里配置上下的servlet就可以了
*/
@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;
}
坑:
一值 loading f12
解决办法 :
https://www.freesion.com/article/8641843040/
虽然改完之后f12还是报错,但是我的图片出来了。
打包jar文件:
https://blog.csdn.net/weixin_43550968/article/details/102861404