熔断降级 请求合并 请求缓存 线程池隔离 信号量隔离 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;
    }
    @HystrixCommand
    public 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: true
        requestVolumeThreshold: 2
        sleepWindowInMilliseconds: 2000
        errorThresholdPercentage: 50
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值