SpringCloud如何实现负载均衡、服务降级与熔断的快速入门?

摘要:LoadBalancer 负载均衡 负载均衡的实现原理: 在添加@LoadBalanced注解后,会启用拦截器对我们发起的服务调用请求进行拦截,叫做LoadBalancerInterceptor,它实现ClientHttpRequestIn
LoadBalancer 负载均衡 负载均衡的实现原理: 在添加@LoadBalanced注解后,会启用拦截器对我们发起的服务调用请求进行拦截,叫做LoadBalancerInterceptor,它实现ClientHttpRequestInterceptor接口。 默认使用轮询的负载均衡策略,也可以选择随机负载均衡策略 如何修改负载均衡策略? 先创建随机分配策略的配置类(不用加@Configuration) public class LoadBanancerConfig { // 将官方提供的RandomLoadBalancer注册为bean @Bean public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory clientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RandomLoadBalancer(clientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name); } } 修改RestTemplate对应的配置类 @Configuration // 指定为user-service服务,只要调用此服务,就会使用我们指定的策略 //configuration = LoadBanancerConfig.class 指定我们自定义的策略类 @LoadBalancerClient(value = "user-service",configuration = LoadBanancerConfig.class) public class BeanConfiguration { @Bean // 负载均衡 @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } } 此时就完成了负载均衡策略的修改! OpenFegin实现负载均衡 Fegin和RestTemplate一样,也是http客户端请求工具,但是它的使用方式更加便捷。 先加入依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> 在启动类上加@EnableFeignClients注解。 @SpringBootApplication @EnableFeignClients public class AppBorrow { public static void main( String[] args ) { SpringApplication.run(AppBorrow.class, args); } } 当我们要调用其他微服务的接口改怎么做呢?先创建一个对应服务的接口类: // 声明为user-service服务的客户端,user-service表示服务名称 @FeignClient("user-service") public interface UserClient { // 路径和参数保持一致 @RequestMapping("/user/{uid}") User getUserById(@PathVariable("uid") int uid); } 实现具体业务: @Service public class BorrowServiceImpl implements BorrowService { @Autowired private BorrowMapper borrowMapper; @Autowired private RestTemplate restTemplate; @Autowired private UserClient userClient; @Autowired private BookClient bookClient; @Override public BorrowDetail findBorrowById(int uid) { List<Borrow> allByUid = borrowMapper.getAllByUid(uid); // 获取用户信息 localhost:8101 改成服务名user-service /*User user = restTemplate.getForObject("http://user-service/user/" + uid, User.class); // 获取每本书的详细信息 List<Book> bookList = allByUid.stream().map(borrow -> restTemplate.getForObject("http://book-service/book/" + borrow.getBid(), Book.class)) .collect(Collectors.toList());*/ //=====================使用openFeign============================== User user = userClient.getUserById(uid); // 获取每本书的详细信息 List<Book> bookList = allByUid.stream().map(borrow -> bookClient.getBookById(borrow.getBid())) .collect(Collectors.toList()); return new BorrowDetail(user, bookList); } } Hystrix服务熔断 思考以下场景:服务A调用服务B,服务B调用服务c,服务c调用服务d。 当服务d发生故障后,会导致服务abc全部崩溃。 当发生这种问题时,要怎么解决?此时就需要Hystrix熔断器组件,防止整条服务都崩溃了,还有大量的请求不断访问。 其工作机制由服务降级和服务熔断 服务降级和服务熔断 服务降级不会直接返回错误,而是可以提供一个补救措施,正常响应给请求者。这样相当于服务依然可用,但是服务能力肯定下降了。 服务熔断是在服务降级之后还是由大量的请求进来,此时会直接返回备选结果,不再执行正常方法,当服务恢复后,才会关闭熔断器。 先导入Hystrix依赖,由于springcloud中不再带有Hystrix,所以要自己单独导入 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.10.RELEASE</version> </dependency> 在启动类中添加注解@EnableHystrix 在Controller类中设置备选方案: // 指定备选方案 @HystrixCommand(fallbackMethod = "onError") @RequestMapping("/borrow/{uid}") public BorrowDetail getBorrowById(@PathVariable("uid") int id) { return borrowService.findBorrowById(id); } // 这个时备选方案 BorrowDetail onError(int id){ return new BorrowDetail(null, Collections.emptyList()); } 注意:Spring Boot3不支持Hystrix,所以会发现不生效! 结论:它能够对一段时间内出现的错误进行侦测,当侦测到出错次数过多时,熔断器会打开,所有的请求直接响应失败,这段时间内内,执行一定数量的请求;如果之后还是出现错误,那么继续保持打开状态,否则说明服务恢复正常,熔断器关闭。 OpenFeign实现降级 Hystrix也可以配合Feign进行降级,我们可以对接口中定义的远程调用单独进行降级操作。 比如我们测试时,关掉用户服务来测试服务降级,实际上就是借阅服务调用用户服务失败才导致的降级。那么可以给远程调用添加一个替代方案,比如远程调用失败,直接上替代方案。 具体的实现方案是:创建一个feign客户端接口的实现类,来替代原来的方案: 创建实现类 @Component public class UserFallbackClient implements UserClient { @Override public User getUserById(int uid) { User user = new User(); user.setName("我是补救方案!"); return user; } } 在UserClient接口类中指定替代方案 // 声明为user-service服务的客户端,user-service表示服务名称 // fallback指定替代方案的实现类 @FeignClient(value = "user-service",fallback = UserFallbackClient.class) public interface UserClient { // 路径和参数保持一致 @RequestMapping("/user/{uid}") User getUserById(@PathVariable("uid") int uid); } 在配置文件中开启熔断支持 spring: cloud: openfeign: circuitbreaker: enabled: true 这里就不用在controller类中使用@HystrixCommand(fallbackMethod = "onError")注解了,需要注释掉: // 指定备选方案 // @HystrixCommand(fallbackMethod = "onError") @RequestMapping("/borrow/{uid}") public BorrowDetail getBorrowById(@PathVariable("uid") int id) { return borrowService.findBorrowById(id); } 这里需要注意:由于我使用的是springcloud2025版本,需要额外引入一个依赖才能实现openfeign降级。 <!-- Resilience4j 熔断器(实现降级核心) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId> </dependency> 到此为止,openfeign降级就实现了。 监控页面部署 除了对服务进行降级和熔断处理,也可以对其进行实时监控,只需安装监控页面即可,具体步骤为: 创建一个新maven模块,并引入依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> <version>2.2.10.RELEASE</version> </dependency> 添加配置文件 server: port: 8900 hystrix: dashboard: #将localhost添加到白名单,不然打不开本地页面 proxy-stream-allow-list: "localhost" 创建启动类 @SpringBootApplication @EnableHystrixDashboard public class AppHystrixDashboard { public static void main( String[] args ) { SpringApplication.run(AppHystrixDashboard.class, args); } } 在需要监控的服务中添加Actuator依赖;Actuator是spring boot程序的监控系统,可以实现健康检查,记录信息等,只需要引入依赖,并作简单配置即可。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 在需要监控的服务中添加如下配置: management: endpoints: web: exposure: include: '*' 如果是springboot3.5.11 版本。官方已完全移除了hystrix依赖,所以无法演示,但是springboot2.x版本是正常支持的。 管理页面的地址是:http://localhost:8900/hystrix/ 在中间输入框填写具体要监控的服务地址(比如http://localhost:8301)+/actuator/hystrix.stream 然后点击Monitor Stream即可进入监控页面。