欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 熔断降级 请求合并 请求缓存 线程池隔离 信号量隔离 openfeign整合Hystrix

熔断降级 请求合并 请求缓存 线程池隔离 信号量隔离 openfeign整合Hystrix

2024/10/25 10:27:21 来源:https://blog.csdn.net/weixin_45939821/article/details/142583778  浏览:    关键词:熔断降级 请求合并 请求缓存 线程池隔离 信号量隔离 openfeign整合Hystrix

〇、Hystrix的解决策略和预防措施:

        熔断降级是解决远程调用已经出现问题的解决方案。

        请求合并 请求缓存 线程池隔离 信号量隔离都是预防性措施

        使用Hystrix启动类上需要添加注解开启注解支持:

        @EnableHystrix@EnableCircuitBreaker

        测试Hystrix需要的依赖坐标如下:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version></parent><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR12</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version> <!-- 请使用最新的版本号 --><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 容灾处理依赖。 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency></dependencies>

一、熔断降级 

                熔断是在远程调用的服务器出现问题后,访问不会再进行远程调用甚至调用方法get()。

                降级是访问不会再进行远程调用,而是转而调用getDownGrade()方法返回托底数据。

//  熔断 熔断熔断熔断熔断熔断熔断熔断     熔断      熔断   熔断@HystrixCommand(fallbackMethod = "getDownGrade",commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS,value = "5000"), // 统计周期,默认10秒@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED,value = "true"), // 是否开启熔断,默认true@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value = "2"), // 统计周期内,错误几次,开启熔断, 默认20@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,value = "50"), // 统计周期内,错误百分比达到多少,开启熔断, 默认50@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,value = "3000"), // 开启熔断后,多少毫秒不访问远程服务,默认5000毫秒@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_FORCE_OPEN,value = "false"), // 是否强制开启熔断器, 默认false@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_FORCE_CLOSED,value = "false") // 是否强制关闭熔断器, 默认false})public String get(){String forObject = restTemplate.getForObject("http://application-service/getNoParams", String.class);return forObject;}public String getDownGrade(){return "服务器繁忙";}


二、请求合并 

        远程调用的服务器端c2有两个方法。一个是针对单个id的,还有一个是针对多个id的相同操作的合并

        多个根据id查询user的请求发送至要进行 远程调用的服务器端c1,这时开启请求处理的多个线程阻塞,并将多个id合并为一个List发送一个请求到c2.然后返回的值放在相应线程的FutureTask中。

//请求合并 请求合并 请求合并 请求合并请求合并 请求合并请求合并 请求合并请求合并 请求合并请求合并 请求合并请求合并 请求合并@HystrixCollapser(batchMethod = "getUserByIds",scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,collapserProperties = {@HystrixProperty(name =HystrixPropertiesManager.MAX_REQUESTS_IN_BATCH,value = "2"), // 最多合并多少个请求@HystrixProperty(name =HystrixPropertiesManager.TIMER_DELAY_IN_MILLISECONDS,value = "2000") // 最多等待多少毫秒})public Future<User> getUserById(Integer id){System.out.println("正常请求,无请求合并:id="+id);restTemplate.postForObject("http://application-service/getUserById", id, User.class);return null;}@HystrixCommandpublic List<User> getUserByIds(List<Integer>ids) throws JsonProcessingException {List<LinkedHashMap> list = restTemplate.postForObject("http://application-service/getUserByIds", ids, List.class);System.out.println("执行合并方法");List<User> list1 = new ArrayList<>();for (LinkedHashMap linkedHashMap : list) {ObjectMapper objectMapper = new ObjectMapper();String s = objectMapper.writeValueAsString(linkedHashMap);User user = objectMapper.readValue(s, User.class);list1.add(user);}return list1;}


三、请求缓存

         这里使用spring cache技术连接redis数据库,在配置文件中配置redis的地址。

        @Cacheable()注解自动将方法的返回值存储redis中。

        启动类上添加@EnableCaching  开启相关注解支持

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
//请求缓存 请求缓存       请求缓存请求缓存请求缓存请求缓存@Cacheable(cacheNames = "getForObject",key = "#id")public String cache(Integer id){System.out.println("cache方法执行");String forObject = restTemplate.getForObject("http://application-service/getNoParams", String.class);return forObject;}


四、线程池隔离

                和船体底部的小船舱一样,底部破了仍然有隔板挡着。

                线程池是事先针对远程调用准备的多个线程。

                如果不准备线程池,一个远程调用崩了,导致线程阻塞不能释放最终会导致整个服务崩掉。

  //线程池隔离   线程切换  线程池隔离   线程切换 线程池隔离   线程切换线程池隔离   线程切换@HystrixCommand(groupKey = "TbItem",commandKey = "selectItemService",threadPoolKey = "pool-name",threadPoolProperties = {@HystrixProperty(name = HystrixPropertiesManager.CORE_SIZE,value = "3"), // 线程池容量@HystrixProperty(name = HystrixPropertiesManager.KEEP_ALIVE_TIME_MINUTES,value = "5"), // 线程空闲时,最大存活时间是多少分钟@HystrixProperty(name = HystrixPropertiesManager.MAX_QUEUE_SIZE,value = "5"), // 线程池占满时,最多由多少个请求阻塞等待@HystrixProperty(name = HystrixPropertiesManager.QUEUE_SIZE_REJECTION_THRESHOLD,value = "5") // 当阻塞队列MAX_QUEUE_SIZE占满时,可以由多少个// 请求同时阻塞等待后续处理。})public String selectItemService() {System.out.println("selectItemService---"+Thread.currentThread().getName());String forObject = restTemplate.getForObject("http://application-service/getNoParams", String.class);return forObject;}


五、信号量隔离

        在一定时间内只允许有限个线程远程调用,其他线程降级。

        进行远程调用的线程会拿到许可证,线程结束释放许可证。

//信号量隔离  信号量隔离信号量隔离信号量隔离//在一定时间内只允许2个线程远程调用,其他线程降级@HystrixCommand(fallbackMethod = "getDownLoad",commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY,value = "SEMAPHORE"), // 隔离方案。默认线程池隔离。 THREAD | SEMAPHORE@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS,value = "1"), // 最大信号量@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "5000") // 超时时间。信号量隔离中无效,线程池隔离中有效。默认1秒})public String sign(){String forObject = restTemplate.getForObject("http://application-service/getNoParams", String.class);return forObject;}public String getDownLoad(){return "服务器繁忙";}


六、openfeign整合Hystrix

       1)openfeign中使用Hystrix很简单,只需要修改配置文件即可,因为内置好了Hystrix的基础功能容灾处理。

                可以看到如果需要Hystrix的其他预防措施还是需要引入Hystrix依赖坐标

        2)修改配置文件:

feign:hystrix:enabled: true
hystrix: # hystrix 容灾配置command: # hystrix 命令配置,就是具体的容灾方案default: # 默认环境,相当于全局范围,后续的配置,参考HystrixPropertiesManager中的常量配置circuitBreaker: # 熔断配置, 常用。 其他配置不常用。enabled: truerequestVolumeThreshold: 2sleepWindowInMilliseconds: 2000errorThresholdPercentage: 50

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com