【OpenFeign】OpenFeign结合Hystrix和Sentinel实现熔断降级

OpenFeign可以与Hystrix和Sentinel结合使用,实现降级和熔断。

OpenFeign与Hystrix结合使用

使用OpenFeign需要引入OpenFeign的依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

spring-cloud-starter-openfeign引入的依赖如下:

shell 复制代码
[INFO] +- org.springframework.cloud:spring-cloud-starter-openfeign:jar:2.2.6.RELEASE:compile
[INFO] |  +- org.springframework.cloud:spring-cloud-openfeign-core:jar:2.2.6.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-aop:jar:2.3.2.RELEASE:compile
[INFO] |  |  |  \- org.aspectj:aspectjweaver:jar:1.9.6:compile
[INFO] |  |  \- io.github.openfeign.form:feign-form-spring:jar:3.8.0:compile
[INFO] |  |     +- io.github.openfeign.form:feign-form:jar:3.8.0:compile
[INFO] |  |     \- commons-fileupload:commons-fileupload:jar:1.4:compile
[INFO] |  +- io.github.openfeign:feign-core:jar:10.10.1:compile
[INFO] |  +- io.github.openfeign:feign-slf4j:jar:10.10.1:compile
[INFO] |  \- io.github.openfeign:feign-hystrix:jar:10.10.1:compile
[INFO] |     +- com.netflix.archaius:archaius-core:jar:0.7.6:compile
[INFO] |     \- com.netflix.hystrix:hystrix-core:jar:1.5.18:compile
[INFO] |        \- org.hdrhistogram:HdrHistogram:jar:2.1.9:compile

默认已经自动引入了hystrix的依赖,不再需要单独再引入hystrix了。

使用fallback实现降级方法

降级方法的类需要实现FeignClient的接口,同时这个类需要注入到Spring容器中:

java 复制代码
package com.morris.user.client;

import com.morris.user.entity.Order;
import com.morris.user.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class OrderFeignService implements OrderClient {

    @Override
    public List<Order> findOrderByUserId(Long userId) {
        log.error("findOrderByUserIdFall error {}", userId);
        return Collections.emptyList();
    }
}

@FeignClient注解中指定fallback属性:

java 复制代码
@FeignClient(value = "order-service", path = "/order", fallback = OrderFeignService.class)
public interface OrderClient {
... ...

在配置文件中开启hystrix:

shell 复制代码
feign:
  hystrix:
    enabled: true

使用fallbackFactory实现降级方法

使用fallback实现降级方法无法获取到异常信息,而使用fallbackFactory实现降级方法可以获取到异常信息。

降级方法的工厂类需要实现FallbackFactory的接口,同时这个类需要注入到Spring容器中:

java 复制代码
package com.morris.user.client;

import com.morris.user.entity.Order;
import com.morris.user.entity.User;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collections;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class OrderFeignFactory implements FallbackFactory {

    @Override
    public Object create(Throwable throwable) {
        log.error("OrderFeignFactory ", throwable);
        return new OrderClient() {
            @Override
            public List<Order> findOrderByUserId(Long userId) {
                return Collections.emptyList();
            }
        }
    }
}

@FeignClient注解中指定fallback属性:

java 复制代码
@FeignClient(value = "order-service", path = "/order", fallbackFactory = OrderFeignFactory.class)
public interface OrderClient {
... ...

在配置文件中开启hystrix:

shell 复制代码
feign:
  hystrix:
    enabled: true

Hystrix熔断的使用

Hystrix熔断的功能是默认开启的,commandKey为类名#方法名(参数类型),例如上面的方法对应的commandKey为OrderClient#findOrderByUserId(Long)

可以在配置文件中根据commandKey对熔断的一些参数进行设置:

shell 复制代码
hystrix:
  command:
    OrderClient#findOrderByUserId(Long):
      circuitBreaker:
        enabled: false
        requestVolumeThreshold: 2
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            #设置请求超时时间,默认1秒,超过指定的时间后,触发服务熔断
            timeoutInMilliseconds: 10000

OpenFeign与Sentinel结合使用

引入Sentinel的依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

并开启Sentinel的熔断降级功能:

shell 复制代码
spring:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080

feign:
  sentinel:
    enabled: true

降级的使用还是跟前面的一样,使用fallback和fallbackFactory实现。

Sentinel熔断的使用

虽然熔断的功能开启了,但是需要配置熔断规则,没有配置规则是不会触发熔断的。

配置如下降级规则测试熔断:

shell 复制代码
[
     {
          "count": 0.5,
          "grade": 1,
          "limitApp": "default",
          "minRequestAmount": 5,
          "resource": "GET:http://order-service/order/findOrderByUserId",
          "slowRatioThreshold": 1,
          "statIntervalMs": 5000,
          "timeWindow": 5000
     }
]

自定义全局异常

OpenFeign可以配置一个全局异常,来对请求过程中的其他异常进行包装,这样在fallbackFactory中获取到的是自定义的全局异常,而不是原始的异常。

java 复制代码
package com.morris.user.config;

import feign.Response;
import feign.Util;
import feign.codec.ErrorDecoder;
import feign.form.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.Reader;
import java.text.MessageFormat;

@Configuration
@Slf4j
public class FeignErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        Reader reader = null;
        try {
            reader = response.body().asReader(CharsetUtil.UTF_8);
            String errMsg = Util.toString(reader);
            log.error("FeignErrorDecoder {}", errMsg);
            return new RuntimeException(errMsg);
        } catch (IOException e) {
            return new RuntimeException(MessageFormat.format("自定义Feign错误信息出错:{0}", e.getMessage()));
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
相关推荐
转测试啦转测试啦4 天前
Redis哨兵(sentinel)
redis·sentinel·php
wclass-zhengge5 天前
SpringCloud篇(服务保护 - Sentinel)
spring·spring cloud·sentinel
cui_win8 天前
Redis高可用-Sentinel(哨兵)
redis·bootstrap·sentinel
菜菜-plus9 天前
分布式,微服务,SpringCloudAlibaba,nacos,gateway,openFeign
java·分布式·微服务·nacos·gateway·springcloud·openfeign
FIN技术铺10 天前
Redis集群模式之Redis Sentinel vs. Redis Cluster
数据库·redis·sentinel
cyt涛12 天前
Sentinel — 微服务保护
微服务·架构·sentinel·限流·熔断·降级·隔离
ketil2714 天前
Redis - 哨兵(Sentinel)
数据库·redis·sentinel
阿伟*rui15 天前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
茶馆大橘15 天前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel
Shenqi Lotus15 天前
Redis-“自动分片、一定程度的高可用性”(sharding水平拆分、failover故障转移)特性(Sentinel、Cluster)
redis·sentinel·cluster·failover·sharding·自动分片·水平拆分