SpringCloud学习笔记(五)——hystrix
一、服务雪崩的概念
1.1 什么是服务雪崩
1.2 服务雪崩怎么解决
1.修改调用时长
2.设置拦截器
二、Hystrix简介
三、Hystrix快速入门
3.1 首先我们正常写一个openFeign调用的程序
1.先创建一个rent-car-service,修改其boot和cloud版本,然后添加配置文件,主类增加上相应注解,然后创建一个接口供调用即可,注册到eureka服务器上即可。
这里贴一下接口代码:
@RestController public class TestController { @GetMapping("rentcar") public String rentcar() { return "租车成功!"; } }
2.再创建一个user-service,同样修改版本、添加配置文件,主类中除了增加eurekaClient注解外,还要加上feignClient注解,然后创建feign接口并且创建controller接口利用feign调用远程服务,最后注册到eureka服务器上。
feign接口代码如下:
@FeignClient("rent-car-service") public interface UserRentCarFeign { @GetMapping("rentcar") public String rentcar(); }
controller类接口代码如下:
@RestController public class TestController { @Autowired private UserRentCarFeign userRentCarFeign; @GetMapping("testHystrix") public String testHystrix() { String result = userRentCarFeign.rentcar(); return result; } }
3.测试
3.2 现在我们给这个程序加上Hystrix熔断器
1.首先要在调用端即user-service这里增加一个feign接口的实现类,我们把这个实现类放在feign/hystrix包路径下,代码如下:
代码如下:
@Component
public class UserRentCarHystrix implements UserRentCarFeign { @Override public String rentcar() { return "我是hystrix实现类,是备份"; } }
2.在feignClient注解下增加一个备用类的属性
@FeignClient(value="rent-car-service",fallback= UserRentCarHystrix.class)
3.yml配置文件中开启hystrix
注:在F版本之前是不用开启的,默认开启,因为之前只有这一种熔断器,现在熔断器种类多了,所以需要手动控制开启
feign: hystrix: enabled: true #开启断路器的使用
4.然后开启服务进行测试
rent-car-service宕机以后,再访问就会到自己的实现类。
3.3 在 Ribbon 中使用 Hystrix(了解)
四、手写熔断器
4.1 断路器的设计
4.2 手写断路器(利用AOP切面编程)
五、Hystrix的一些配置
hystrix: #hystrix 的全局控制 command: default: #default 是全局控制,也可以换成单个方法控制,把 default 换成方法名即可 fallback: isolation: semaphore: maxConcurrentRequests: 1000 #信号量隔离级别最大并发数 circuitBreaker: enabled: true #开启断路器 requestVolumeThreshold: 3 #失败次数(阀值) sleepWindowInMilliseconds: 20000 #窗口时间 errorThresholdPercentage: 60 #失败率 execution: isolation: Strategy: thread #隔离方式 thread 线程隔离集合和 SEMAPHORE 信号量隔离
#隔离方式 两种隔离方式 thread 线程池 按照 group(10 个线程)划分服务提供者,用户请求的线程 和做远程的线程不一样 # 好处 当 B 服务调用失败了 或者请求 B 服务的量太大了 不会对 C 服务造成影响 用户访问比较大的情 况下使用比较好 异步的方式 # 缺点 线程间切换开销大,对机器性能影响 # 应用场景 调用第三方服务 并发量大的情况下 # SEMAPHORE 信号量隔离 每次请进来 有一个原子计数器 做请求次数的++ 当请求完成以后 -- # 好处 对 cpu 开销小 # 缺点 并发请求不易太多 当请求过多 就会拒绝请求 做一个保护机制 # 场景 使用内部调用 ,并发小的情况下 # 源码入门 HystrixCommand AbstractCommand HystrixThreadPool
六、项目结构分析
组织结构方式一:
组织结构方式二:
七、按组织结构方式二创建一个fegin项目
7.1 项目结构
domain中存放实体类,api中存放接口,这两个是不需要运行启动的,也不需要注册到eureka中,他俩的作用就是存放这些类,然后供其他服务调用的,就类似于jar包的作用。
7.2 创建项目
7.2.1 创建父类项目
因为要整明白项目之间的父子关系,所以不能直接创建springboot项目,需要创建一个maven项目,然后自己添加依赖,并指定父项目(我感觉直接创建springboot项目好像也可以?)。
刚创建出来的配置文件是啥都没有的:
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>project-openfegin</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> </project>
然后修改其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"> <modelVersion>4.0.0</modelVersion> <!-- 指明父项目 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>org.example</groupId> <artifactId>project-openfegin</artifactId> <version>1.0-SNAPSHOT</version> <!--指明打包方式,这个是不用写,因为一旦创建子模块就会自动生成 --> <packaging>pom</packaging> <!-- 用来定义公共的版本号控制--> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR12</spring-cloud.version> </properties> <!-- 这里的依赖,所有的子模块都会有--> <dependencies> <dependency> <!-- 注意:这里不用写版本号,因为父模块中已经定义好了默认的了 --> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <!-- 加在这里的依赖不会被真的引进项目,只是做一个版本控制--> <dependencyManagement> <!-- 控制springcloud的版本--> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- 打包、仓库相关的配置--> <build> </build> </project>
7.2.2 创建子项目
首先创建project-domain
创建其余子项目:
然后我们按照设计的图里搞明白输入关系,即api依赖domain,其余客户端依赖api,需要在对应的pom文件中注入依赖,这样调用各个模块的类时才能调用到
api中加入domain的依赖:
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>project-domain</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
其余客户端加入api的依赖:
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
接下来首先完成domain模块的编写:
首先创建包,然后在包中增加需要用到的实体类,注意每个模块的报名要保持一致,这里我们所有模块的报名统一全部使用com.example.
Order类代码如下:
@Data @AllArgsConstructor @NoArgsConstructor @Builder public class Order { private Integer id; private String name; private Double price; }
接下来完成order-center模块的编写
首先要补充依赖。springweb和eureka的依赖,增加依赖如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- eureka的客户端的依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
因为这个模块最后需要被打成jar包,所以需要配置上打包插件:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
然后因为是创建的maven项目,所以需要在这个模块下自己创建一个新的主类:
@SpringBootApplication @EnableEurekaClient public class OrderCenterApplication { public static void main(String[] args) { SpringApplication.run(OrderCenterApplication.class, args); } }
然后新建controller,注意包名保持一致。然后本来我们是要创建一个接口方法的,但是因为这个方法和fegin中的接口是一致的,这个方法只是个实现类而已。所以我们要把这个接口抽象到commom-api这个模块内,所以这里建议先看完commom-api模块的编写后,在继续看这一部分。
因为我们在api模块已经实现了fegin接口,所以在这个controller中我们只要实现api的接口就可以了。
public class OrderController implements UserOrderFeign { @Override public Order getOrderById(Integer id) { System.out.println("得到了输入的id:"+id); Order order = Order.builder() .id(100) .name("猪肉炖粉条").price(15.5).build(); return order; } }
最后别忘了创建yml文件,并将其注册到eureka服务器上。
server: port: 8081 spring: application: name: order-center eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: instance-id: ${spring.application.name}:${server.port} prefer-ip-address: true
然后把这个模块运行起来就好了。
接下来完成commom-api模块的编写
首先是在pom配置文件中添加上feign的依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
然后新建一个feign包,下边新建一个UserOrderFeign接口(只要是user调用order的方法都写到这个接口下,调用其它模块的再新建接口),写上对应抽象方法,代码如下:
@FeignClient(value = "order-center") public interface UserOrderFeign { @GetMapping("/order/getOrderById") Order getOrderById(@RequestParam Integer Id); }
接下来完成user模块的编写
和order模块一样,同样需要添加依赖、配置打包插件、添加yml配置文件,添加主类。
搞完上述这些以后,创建一个controller类,在里边写接口调用order-center。
@RestController public class UserController { @Autowired public UserOrderFeign userOrderFeign; @GetMapping("find") public Order findOrder(Integer id) { return userOrderFeign.getOrderById(id); } }
注意:这里不同模块的包名一定得保持一致,否则自动注入会失败,因为他可能会扫描不到feign接口,也就没法把它加入到IOC容器中。
注意:不要忘记在主类中将当前模块注册为feign的客户端
@SpringBootApplication @EnableEurekaClient @EnableFeignClients public class UserCenterApplication { public static void main(String[] args) { SpringApplication.run(UserCenterApplication.class,args); } }
这里才踩了一个坑,实现接口的时候,把形参的Id改成了id,这导致了访问失败,就不要多手,什么东西能保持一致就尽量保持一致。
然后在浏览器中输入http://localhost:8082/find,可以发现访问成功。
然后我们在当前的结构上增加hystrix熔断器的配置
其实熔断器配置在api模块或者user模块都是可以的。这里我们选择将hystrix配置在api模块里。
首先创建fegin的hystrix实现类:
@Component public class UserOrderHystrix implements UserOrderFeign { @Override public Order getOrderById(Integer id) { Order order = Order.builder().id(1).name("备份").price(0.0).build(); return order; } }
然后在FeignClient注解下增加回调函数:
@FeignClient(value = "order-center",fallback = UserOrderHystrix.class) public interface UserOrderFeign { @GetMapping("/order/getOrderById") Order getOrderById(@RequestParam Integer id); }
最后在user模块的yml配置文件中将hystrix的配置开启:
feign: hystrix: enabled: true #开启断路器的使用
然后开启两个客户端测试:
然后关掉order模块的测试端再测试:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)