springCould中的Hystrix【上】-从小白开始【7】

目录

1.简单介绍❤️❤️❤️

2.主要功能 ❤️❤️❤️

3.正确案例❤️❤️❤️

4.使用jmeter压测 ❤️❤️❤️

5.建模块 80❤️❤️❤️

6.如何解决上面问题 ❤️❤️❤️

7.对8001进行服务降级❤️❤️❤️

8.对80进行服务降级 ❤️❤️❤️

9.通用降级方法❤️❤️❤️

10.在Feign接口实现降级 ❤️❤️❤️


1.简单介绍❤️❤️❤️

Hystrix是一个用于处理分布式系统延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

2.主要功能 ❤️❤️❤️

  • 服务隔离:通过将不同的依赖服务调用分配给不同的线程池来隔离服务之间的调用,防止一个服务的故障导致整个系统的崩溃。
  • 服务降级当依赖服务出现延迟故障Hystrix可以提供一个备用的响应,避免用户等待超时或出现错误。
  • 服务熔断Hystrix可以根据依赖服务的错误率和延迟来决定是否打开断路器,当断路器打开时所有的请求将直接返回,避免对依赖服务的继续调用。
  • 服务限流Hystrix可以限制对依赖服务的并发调用数量,避免因过多的请求导致依赖服务的崩溃。
  • 实时监控和报警:Hystrix提供了实时的监控仪表盘,可以监控依赖服务的调用情况和错误率,并提供报警机制。

3.正确案例❤️❤️❤️

1.建模块

在父工程下创建,注意jdk和maven版本

2.写pom

1.springboot依赖

2.mysql依赖

3.mybatis依赖

4.eureka依赖

5.hystrix依赖

  <dependencies><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.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.16</version></dependency><!--mysql-connector-java--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</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><!--引入自己的api--><dependency><groupId>org.example</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!--eureka的client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--hystrix--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency></dependencies>

3.写yml

1.服务端口

2.服务名称

3.数据库连接池

4.mybatis配置

5.入住到服务注册中心(eureka)

server:port: 8001spring:application:name: cloud-provider-hystrix-paymentdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/springcloudusername: rootpassword: 123456
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.xz.springcloud.entityeureka:client:register-with-eureka: truefetch-registry: trueservice-url:defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

4.主启动类

@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class);}
}

5.编写业务

创建两个方法:

1.正常方法没有延迟

2.错误方法有延时,Thread.sleep()模拟程序执行时间

@RestController
public class PaymentController {@Autowiredprivate PaymentService paymentService;@Value("${server.port}")private String serverPort;@GetMapping("/payment/hystrix/ok/{id}")public CommonResult paymentInfo_Ok(@PathVariable("id") Integer id) {Payment result = paymentService.getById_Ok(id);if (result != null) {return new CommonResult(200, "查寻成功,端口:" + serverPort+",线程池:"+Thread.currentThread().getName(), result);} else {return new CommonResult(404, "查询失败,端口:" + serverPort+",线程池:"+Thread.currentThread().getName());}}@GetMapping("/payment/hystrix/timeout/{id}")public CommonResult paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException {int timeOut = 3;Payment result = paymentService.getById_TimeOut(id);if (result != null) {TimeUnit.SECONDS.sleep(3);return new CommonResult(200, "查寻成功,端口:"+ serverPort+",线程池:"+Thread.currentThread().getName()  + ",超时时间:" + timeOut, result);} else {return new CommonResult(404, "查询失败,端口:"+ serverPort+",线程池:"+Thread.currentThread().getName()  + ",超时时间:" + timeOut);}}
}

 6.测试:

1.paymentInfo_ok,没有延迟,直接查询到

2.paymentInfo_TimeOut,有延迟,三秒后查询到

4.使用jmeter压测 ❤️❤️❤️

  • 1.创建线程组-取样器-HTTP请求

  • 2.设置压测数据 

 

  • 3.启动压测,同时刷新正常的请求Ok 

 

发现之前没有设置延迟的接口,访问时也变得十分缓慢。。。 

原因:tomcat的默认的工作线程数被打满了,没有多余的线程来分解压力和处理。

这就导致,我们访问同一服务下的其他接口地址也变得缓慢

5.建模块 80❤️❤️❤️

1.建模块

在父工程下创建,注意jdk版本和maven版本

2.写pom

1.springboot依赖

2.通用依赖

3.eureka依赖

4.OpenFeign依赖

5.Hystri依赖

 <dependencies><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.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><dependency><groupId>org.example</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!--eureka的Client端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency></dependencies>

3.加yml

1.服务端口

2.入住eureka配置信息

server:port: 80
eureka:client:register-with-eureka: falseservice-url:defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

4.主启动

使用OpenFeign,添加@EnableFeignClients

@SpringBootApplication
@EnableFeignClients
public class OrderHystrixMain80 {public static void main(String[] args) {SpringApplication.run(OrderHystrixMain80.class);}}

5.@FeignClient接口

1.使用@Component,交给spring管理

2.添加@FeignClient(value="要访问服务的名称")

3.要访问服务的哪个接口

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {@GetMapping("/payment/hystrix/ok/{id}")public CommonResult paymentInfo_Ok(@PathVariable("id") Integer id);@GetMapping("/payment/hystrix/timeout/{id}")public CommonResult paymentInfo_TimeOut(@PathVariable("id") Integer id);}

6.编写业务

@RestController
public class OrderHystrixController {@Autowiredprivate PaymentHystrixService paymentHystrixService;@GetMapping("/consumer/payment/hystrix/ok/{id}")public CommonResult paymentInfo_Ok(@PathVariable("id") Integer id) {return paymentHystrixService.paymentInfo_Ok(id);}@GetMapping("/consumer/payment/hystrix/timeout/{id}")public CommonResult paymentInfo_TimeOut(@PathVariable("id") Integer id) {return paymentHystrixService.paymentInfo_TimeOut(id);}
}

7.压测

当正常访问ok方法时,浏览器返回基本是刹那间

当我们压测timeout方法时,再去使用80访问ok方法,结果发现直接返回错误页面。

8001同一层次的其它接口服务被困死,因为tomcat线程池里面的工作线程已经被挤占完毕

6.如何解决上面问题 ❤️❤️❤️

  • 对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
  • 对方服务(8001)down机了,调用者(80)不能一直卡死等待,必须有服务降级
  • 对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者)自己处理降级

7.对8001进行服务降级❤️❤️❤️

1.添加@HystrixCommand注解

属性:

1.fallbackMethod:当超时后,要返回的兜底方法

2.@HystrixProperty:设置多少秒没有响应,返回兜底方法

@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")})@GetMapping("/payment/hystrix/timeout/{id}")public CommonResult paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException {int timeOut = 5;Payment result = paymentService.getById_TimeOut(id);if (result != null) {TimeUnit.SECONDS.sleep(3);return new CommonResult(200, "查寻成功,端口:"+ serverPort+",线程池:"+Thread.currentThread().getName()  + ",超时时间:" + timeOut, result);} else {return new CommonResult(404, "查询失败,端口:"+ serverPort+",线程池:"+Thread.currentThread().getName()  + ",超时时间:" + timeOut);}}

2.创建兜底方法

  public CommonResult paymentInfo_TimeOutHandler(@PathVariable("id") Integer id){Payment result = paymentService.getById_TimeOut(id);if (result != null) {return new CommonResult(200, "系统繁忙!稍后重试~");} else {return new CommonResult(404, "备用~查询失败,端口:" + serverPort+",线程池:"+Thread.currentThread().getName());}}

3.主启动类添加@EnableCircuitBreaker

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class);}
}

4.测试

1.当调用的接口超时,返回兜底数据

2.放调用的接口中存在运行时错误,也会返回兜底数据

8.对80进行服务降级 ❤️❤️❤️

1.改yml

启用Hystrix作为Feign的断路器

feign:hystrix:enabled: true

2.添加@HystrixCommand注解 

   @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")})@GetMapping("/consumer/payment/hystrix/timeout/{id}")public CommonResult paymentInfo_TimeOut(@PathVariable("id") Integer id) {return paymentHystrixService.paymentInfo_TimeOut(id);}

3.创建兜底方法

注意方法的返回值类型必须原方法一致!

 public CommonResult  paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){return new CommonResult(200,"我是消费80,系统繁忙,稍后重试~");}

4.主启动添加@Enablehystrix

@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class OrderHystrixMain80 {public static void main(String[] args) {SpringApplication.run(OrderHystrixMain80.class);}}

5.测试

1.当使用feign调用的方法超时,返回兜底数据

2.当feign调用的方法存在运行时错误,返回兜底数据

9.通用降级方法❤️❤️❤️

1.问题

配置降级服务时,每个方法都要有降级的方法。显然代码膨胀,不好管理

 @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")})

2.解决(@DefaultProperties

使用@DefaultProperties(defaultFallback="全局降级的方法")

需要服务降级的方法,仍需要添加@HystrixCommand

@RestController
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystrixController {@HystrixCommand@GetMapping("/consumer/payment/hystrix/timeout/{id}")public CommonResult paymentInfo_TimeOut(@PathVariable("id") Integer id) {return paymentHystrixService.paymentInfo_TimeOut(id);}//全局fallbackpublic CommonResult payment_Global_FallbackMethod(){return new CommonResult(200,"全局配置处理,系统繁忙,稍后重试");}}

3.测试

10.在Feign接口实现降级❤️❤️❤️ 

1.改yml

启用Hystrix作为Feign的断路器

feign:hystrix:enabled: true

2.创建实现Feign接口类

1.创建一个类,实现有@FeignClient标记的接口

2.添加@Component注解,交给spring管理

@Component
public class PaymentFallbackService implements PaymentHystrixService{@Overridepublic CommonResult paymentInfo_Ok(Integer id) {return new CommonResult(200,"payment_ok,系统繁忙,稍后重试~");}@Overridepublic CommonResult paymentInfo_TimeOut(Integer id) {return new CommonResult(200,"payment_TimeOut,系统繁忙,稍后重试~");}
}

3.在@FeignClien中添加属性:fallback

fallback:返回的兜底类(实现当前接口的类)

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {@GetMapping("/payment/hystrix/ok/{id}")public CommonResult paymentInfo_Ok(@PathVariable("id") Integer id);@GetMapping("/payment/hystrix/timeout/{id}")public CommonResult paymentInfo_TimeOut(@PathVariable("id") Integer id);}

4.测试

当服务8001宕机之后,访问正常接口ok时,返回兜底数据

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/321150.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏缺少emp.dll详细修复教程,快速解决游戏无法启动问题

在现代游戏中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“emp.dll丢失”。emp.dll是一个动态链接库文件&#xff0c;它包含了许多程序运行所需的函数和数据。当一个程序需要调用这些函数时&#xff0c;系统会从emp.dll文件中加载相应的内容。因此&#x…

Docker-Compose部署Redis(v7.2)主从模式

文章目录 一、前提准备1. redis配置文件2. 下载redis镜像3. 文件夹结构 二、docker-compose三、主从配置1.主节点配置文件 环境 docker desktop for windows 4.23.0redis 7.2 一、前提准备 1. redis配置文件 因为Redis 7.2 docker镜像里面没有配置文件&#xff0c;所以需要…

Pikachu--数字型注入(post)

Pikachu--数字型注入&#xff08;post&#xff09; 进入页面 输入 127.0.0.1/pikachu 选择sql注入&#xff08;数字型&#xff09; 2&#xff09;打开foxy代理&#xff0c;输入值“1”进行bp抓包 3&#xff09;将这个获取的包转发到Repeater中 判断注入点 4&#xff09;用单…

lvs+keepalived+nginx实现四层负载+七层负载

目录 一、lvs配置 二、nginx配置 三、测试 3.1 keepalived负载均衡 3.2 lvskeepalived高可用 3.3 nginx高可用 主机IPlvs01-33 11.0.1.33 lvs02-3411.0.1.34nginx0111.0.1.31nginx0211.0.1.32VIP11.0.1.30 4台主机主机添加host [rootnginx01 sbin]# cat /etc/hosts 127.0.0.…

【UEFI基础】EDK网络框架(UNDI)

UNDI UNDI代码综述 UNDI全称Universal Network Driver Interface&#xff0c;它虽然属于UEFI网络框架的一部分&#xff0c;但是并没有在EDK开源代码中实现。不过目前主流网卡厂商都会提供UEFI下的网络驱动&#xff0c;并且大部分都实现了UNDI&#xff0c;这样BIOS下就可以通过…

Alice Bob推出16量子比特量子处理单元——“Helium 1”

​&#xff08;图片来源&#xff1a;网络&#xff09; 容错量子计算机硬件开发商Alice & Bob宣布已成功流片一款新芯片“Helium 1”&#xff0c;希望能借助该芯片降低随着量子比特数增加而提高的错误率&#xff0c;这是该公司第一个纠错逻辑量子比特&#xff08;纠错量子计…

C++_模板

目录 1、函数模板 1.2 模板原理 2、多个模板参数 3、模板的显示实例化 4、模板的匹配 5、类模板 结语&#xff1a; 前言&#xff1a; 在C中&#xff0c;模板分为函数模板和类模板&#xff0c;而模板的作用就是避免了重复的工作&#xff0c;把原本是程序员要做的重复工作…

解决docker容器内无法连接宿主redis

背景 小程序的发短信服务挂了&#xff0c;随查看日志&#xff0c;该报错日志如下 Error 111 connecting to 127.0.0.1:6379. Connection refused. 6379是监听redis服务的端口&#xff0c;那大概是redis出错了。 首先查看了redis是否正常启动&#xff0c;检查出服务正常。 由于小…

C# WinForm MessageBox自定义按键文本 COM组件版

c# 更改弹窗MessageBox按钮文字_c# messagebox.show 字体-CSDN博客 需要用到大佬上传到百度云盘的Hook类&#xff0c;在大佬给的例子的基础上改动了点。 应用时自己加GUID和ProgID。 组件实现&#xff1a; using System; using System.Collections.Generic; using System.L…

Python计算圆的面积

Python 计算圆的面积 圆的面积公式为 &#xff1a; 公式中 r 为圆的半径。 # 定义一个方法来计算圆的面积 def findArea(r): PI 3.142 return PI * (r*r) # 调用方法 r float( input("请输入圆的半径:") ) print( "圆的面积为 %.3f&qu…

C 练习实例16 - 最大公约数和最小公倍数

题目&#xff1a;输入两个正整数a和b&#xff0c;求其最大公约数和最小公倍数 数学&#xff1a;最大公约数*最小公倍数a*b 例如&#xff1a;a16&#xff0c;b20。最小公倍数80&#xff0c;最大公约数4。80*416*20。 算法&#xff1a;辗转相除法&#xff0c;又称欧几里德算法…

【LeetCode-剑指offer】-- 23.相交链表

23.相交链表 方法一&#xff1a;哈希集合 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public class Solution {public ListNode getIn…