• feign配置hystrix,增加熔断降级,两种情况的不同配置


    由于对接的系统比较多,为了避免某一个系统接口挂了之后影响整体服务,就想着加一下熔断。选择了hystrix,不过这个有个缺点就是据说好像已经停止迭代了。
    首先需要引入jar包,pom依赖如下:

    <!-- feign -->
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
            <!-- hystrix-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
    

    之后在启动类上加@EnableHystrix注解,之后还需要在yaml配置文件上写上配置参数

    feign:
      hystrix:
      #打开hystrix
        enabled: true
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 1000 #设置hystrix的超时时间为1000ms
          circuitBreaker:
            #在当10秒的时间内,最近10次调用请求,请求错误率超过50%,则触发熔断5秒,期间快速失败,以下都是默认值
            requestVolumeThreshold: 10
            errorThresholdPercentage: 50
            sleepWindowInMilliseconds: 5000
          #设置统计的时间窗口值的毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。
          #若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,
          #每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000。
          metrics:
            rollingStats:
            #rolling window大小设置
              timeInMilliseconds: 10000
              #分的buckets的数量
              numBuckets: 10
    

    接下里就是代码里的配置了,根据你的feign的使用方式不同,可以分为两种情况:

    情况一:

    feign的调用未使用@FeignClient注解,使用方式为配置feignBuilder。
    未设置熔断器时,feignBuilder用的是feign类里的builder,如果使用熔断器,则要使用HystrixFeign的builder,源码其实这个类是feign的子类。
    在这里插入图片描述
    然后需要写一个fallback类,该类需要继承你的client接口,
    下边这个是我的client接口

    public interface ReportClient {
        @RequestLine("POST /report/data/report")
        @Headers({"Content-Type: application/json", "Accept: application/json"})
        JSONObject report(@RequestBody Map<String,Object> params);
    
    
        @RequestLine("GET /api/hotList/getHotList")
        R<List<Long>> getHotIds(@QueryMap Map<String,Object> params);
    }
    

    这个则是我的client对应的fallback类:

    @Component
    public class ReportClientFallBack implements ReportClient{
    
        @Override
        public JSONObject report(Map<String, Object> params) {
            return new JSONObject();
        }
    
        @Override
        public R<List<Long>> getHotIds(Map<String, Object> params) {
            System.out.println("hystrix success.");
            return R.fail("hystrix.");
        }
    }
    

    重写的方法则是熔断后的默认返回。
    最后则是在你的feign工厂类中配置好fallback

    @Configuration
    public class ReportFactory {
    
        @Value("${URL.reportSystem}")
        private String REPORT_URL;
        @Resource(name = "report")
        private HystrixFeign.Builder feignBuilder;
        @Resource
        private ReportClientFallBack reportClientFallBack;
    
        @Bean("reportClient")
        public ReportClient getReportClient() {
            return feignBuilder
                    .target(ReportClient.class, REPORT_URL,reportClientFallBack);
        }
    }
    

    本地测试的话,需要把配置文件中的错误次数改为1,同时将调用路径改为错误路径即可,postman测试效果如下(服务的路径改为404路径,但是前端感知不到错误,只是获取的数据源是空,交互友好性提升):
    在这里插入图片描述

    情况二:

    feign调用使用的是@FeignClient方式:
    同样需要写一个fallback,但是fallback的类不一样:
    这是我的fallback:

    @Component
    @Sl4j
    public class AppletPushRemoteServiceFallbackFactory implements FallbackFactory<AppletPushRemoteService> {
    
        @Override
        public AppletPushRemoteService create(Throwable throwable) {
            return new AppletPushRemoteService() {
                @Override
                public R<Boolean> baiduBroadcast(BaiduBroadcastMessage message) {
                    try {
                        log.error("baiduBroadcast fail message={}", JsonUtil.toJson(message), throwable);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                    return R.fail("error");
                }
    
                @Override
                public R<Boolean> baiduSubscribe(BaiduSubscribeMessage message) {
                    try {
                        log.error("baiduSubscribe fail message={}", JsonUtil.toJson(message), throwable);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                    return R.fail("error");
                }
    
                @Override
                public R<Boolean> wechatSubscribe(WechatSubscribeMessage message) {
                    try {
                        log.error("wechatSubscribe fail message={}", JsonUtil.toJson(message), throwable);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                    return R.fail("error");
                }
            };
        }
    }
    

    然后在使用@FeignClient注解时即可指定fallback返回:

    @FeignClient(name = "", url = "${}", configuration = CustomFeignBuilder.class, fallbackFactory = AppletPushRemoteServiceFallbackFactory.class)
    public interface AppletPushRemoteService {
    
        @PostMapping(value = "/push/baidu/broadcast")
        R<Boolean> baiduBroadcast(@RequestBody BaiduBroadcastMessage message);
    
        @PostMapping(value = "/token/wechat")
        R<Boolean> baiduSubscribe(@RequestBody BaiduSubscribeMessage message);
    
        @PostMapping(value = "/token/wechat")
        R<Boolean> wechatSubscribe(@RequestBody WechatSubscribeMessage message);
    
    }
    

    以上就是Hystrix和feign搭配使用的步骤。

  • 相关阅读:
    Spring Boot中的SSE与缓存集成:使用Redis加速事件推送
    dp应试进阶:最大和子数组(区分:“序列”与“数组”,序列可以跳跃,数组必须连续)
    MySQL笔记1(数据库的好处,数据库的概念,数据库的特点,MySQL的启动,数据模型,SQL)
    谈一谈AI对人工的取代
    C/C++统计满足条件的4位数个数 2023年5月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
    初始Cpp之 八、类和对象
    数据同步、
    秋招腾讯!配套初级程序员到Java高级架构师学习路线+配套学习资源
    4.10、matlab生成脉冲序列:pulstran()函数
    Window下完全卸载MySQL教程
  • 原文地址:https://blog.csdn.net/weixin_45614626/article/details/127111010