关于开启熔断之后,请求一直报401异常错误的问题

   附上原文作者:  http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/

#服务熔断
feign.hystrix.enabled = true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds = 5000

 

 这是我在公司开发项目时配置熔断的时候踩的一个坑,接下来贴上来一般常用的拦截器所用的一段代码

  

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

    当你开启熔断后会遇到一个问题就是attributes取到的上下文为空,这是因为Hystrix有隔离策略:THREAD和SEMAPHORE,所以当你的隔离策略为THREAD的时候是拿不到Threadlocal里面的值的。

    这边我用了两种方法直接贴上我的解决方案:

    第一种:

    直接添加配置修改默认的隔离策略:

    

#服务熔断
feign.hystrix.enabled = true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds = 5000
hystrix.command.default.execution.isolation.strategy = SEMAPHORE

   修改配置文件把默认策略改成SEMAPHORE就能拿到ThreadLoacl里的值了当然不推荐这样做

    第二种:

    创建一个重写类

package com.jusda.common.Interceptor;

import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.concurrent.Callable;

/**
 * @author wanglinfeng
 * @version 1.0
 * @className RequestAttributeHystrixConcurrencyStrategy
 * @description 获取开启Hystrix后的上下文封装
 * @date 2019/8/12 9:32
 */
public class RequestAttributeHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
    private static final Logger logger= LoggerFactory.getLogger(RequestAttributeHystrixConcurrencyStrategy.class);
    public RequestAttributeHystrixConcurrencyStrategy(){
        HystrixPlugins.reset();
        HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
    }

    /**
     * 装饰线程hystrix callable
     *
     * @return {@link Callable}
     */

    @Override
    public <T> Callable<T> wrapCallable(Callable<T> callable ){
        RequestAttributes requestAttribute = RequestContextHolder.getRequestAttributes();
        return new WrappedCallable<>(callable,requestAttribute);
    }
    static class WrappedCallable<T> implements Callable<T>{
        private final Callable<T> target;
        private final RequestAttributes requestAttributes;
        public WrappedCallable(Callable<T> target,RequestAttributes requestAttributes){
            this.target = target;
            this.requestAttributes = requestAttributes;
        }
        @Override
        public T call() throws Exception{
            try {
                //在调用call方法前,我们可以将当前上下文信息放入
                RequestContextHolder.setRequestAttributes(requestAttributes);
                //call()传播上下文信息
                return target.call();
            }finally {
                RequestContextHolder.resetRequestAttributes();
            }
        }
    }
}

如图所示自定义并发策略重写wrapCallable继承HystrixConcurrencyStrategy

此代码经测试能正常工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Gateway提供了`CircuitBreakerGatewayFilterFactory`工厂类来实现请求熔断的功能。该工厂类可以在请求失败率达到一定阈值时,自动开启熔断模式,避免请求不断地失败。 配置请求熔断的步骤如下: 1. 在`application.yml`或`application.properties`中配置熔断策略: ``` spring: cloud: gateway: routes: - id: example uri: http://example.org predicates: - Path=/example/** filters: - CircuitBreaker=exampleCircuitBreaker # 指定熔断器名称 # CircuitBreaker配置项 CircuitBreaker: enabled: true # 开启熔断器 name: exampleCircuitBreaker # 熔断器名称 fallbackUri: forward:/fallback # 指定熔断后的转发地址 fallbackHeaders: X-Fallback-Reason: test # 指定转发请求头 statusCodes: - BAD_GATEWAY # 触发熔断的状态码 volumeThreshold: 5 # 熔断触发的最小请求数 sleepWindow: 10s # 熔断持续时间 errorThresholdPercentage: 50 # 失败率阈值 ``` 上述配置会对`/example/**`路径下的请求进行熔断,当请求失败率达到50%时,会触发熔断,持续10秒钟。 2. 在`FallbackController`中实现熔断后的请求转发逻辑: ``` @RestController public class FallbackController { @RequestMapping("/fallback") public ResponseEntity<String> fallback() { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Fallback"); } } ``` 需要注意的是,`CircuitBreakerGatewayFilterFactory`会对请求进行统计,当请求失败率达到阈值时,会自动开启熔断模式,所有请求都会转发到指定的熔断地址。在熔断模式下,如果请求成功,则会逐渐恢复正常模式,否则会继续保持熔断状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值