Skip to content

Feign Hystrix 熔断

🏷️ Feign

熔断示例

bootstrap.yml 中开启熔断,设置熔断的超时时间。

yaml
# Feign
feign:
  hystrix:
    enabled: true

# 熔断
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            # 超时时间
            timeoutInMilliseconds: 5000

关于超时时间,我的理解是最好设置成大于 当前 Ribbon 的超时时间 x 重试次数。关于重试次数,不知道我的理解对不对。

javascript
ribbon.ReadTimeout * ((ribbon.MaxAutoRetriesNextServer + 1) * (ribbon.MaxAutoRetries + 1))

关于熔断的回调处理可以使用 FeignClient 注解的 fallback 或者 fallbackFactory 参数。

使用 fallbackFactory 参数的方法可以参考 => feign 自定义 fallback 方法

fallback 参数用法和 fallbackFactory 参数类似,下面是示例代码。

使用 fallback 参数

TestServiceInterface.java

java
package com.octopus.middle.api.services.test;

/**
 * Created by liujiajia on 2019/1/21.
 */

import com.octopus.middle.api.model.base.Parameter;
import com.octopus.middle.api.result.base.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Test Service
 */
@FeignClient(name = "${service.test}", fallback = TestService.class)
public interface TestServiceInterface {
    /**
     * Not Found
     *
     * @param parameter
     * @return
     */
    @RequestMapping(value = "api/test/not-found", method = RequestMethod.POST)
    Result notFound(Parameter parameter);

    /**
     * Time Out
     *
     * @param parameter
     * @return
     */
    @RequestMapping(value = "api/test/time-out", method = RequestMethod.POST)
    Result timeOut(Parameter parameter);
}

TestServer.java

java
package com.octopus.middle.api.services.test;

import com.octopus.middle.api.model.base.Parameter;
import com.octopus.middle.api.result.base.Result;
import org.springframework.stereotype.Component;

/**
 * Test Service
 */
@Component
public class TestService implements TestServiceInterface {
    /**
     * 测试
     *
     * @param parameter
     * @return
     */
    @Override
    public Result notFound(Parameter parameter) {
        return new Result() {{
            setIsSuccess(false);
            setMsg("请求测试接口报错!");
        }};
    }

    /**
     * Time Out
     *
     * @param parameter
     * @return
     */
    @Override
    public Result timeOut(Parameter parameter) {
        return new Result() {{
            setIsSuccess(false);
            setMsg("请求 Time Out 接口报错!");
        }};
    }
}

使用 fallbackFactory 参数

TestServiceInterface.java

java
package com.octopus.middle.api.services.test;

/**
 * Created by liujiajia on 2019/1/21.
 */

import com.octopus.middle.api.model.base.Parameter;
import com.octopus.middle.api.result.base.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Test Service
 */
@FeignClient(name = "${service.test}", fallbackFactory = TestServiceFallBackFactory.class)
public interface TestServiceInterface {
    /**
     * Not Found
     *
     * @param parameter
     * @return
     */
    @RequestMapping(value = "api/test/not-found", method = RequestMethod.POST)
    Result notFound(Parameter parameter);

    /**
     * Time Out
     *
     * @param parameter
     * @return
     */
    @RequestMapping(value = "api/test/time-out", method = RequestMethod.POST)
    Result timeOut(Parameter parameter);
}

TestServiceFallBackFactory.java

java
package com.octopus.middle.api.services.test;

import com.octopus.middle.api.model.base.Parameter;
import com.octopus.middle.api.result.base.Result;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

/**
 * Test Service Factory
 * Created by liujiajia on 2019/1/21.
 */
@Component
public class TestServiceFallBackFactory implements FallbackFactory<TestServiceInterface> {
    @Override
    public TestServiceInterface create(Throwable cause) {
        return new TestServiceInterface() {
            /**
             * 测试
             *
             * @param parameter
             * @return
             */
            @Override
            public Result notFound(Parameter parameter) {
                return new Result() {{
                    setIsSuccess(false);
                    setMsg("请求测试接口报错!");
                }};
            }

            /**
             * Time Out
             *
             * @param parameter
             * @return
             */
            @Override
            public Result timeOut(Parameter parameter) {
                return new Result() {{
                    setIsSuccess(false);
                    setMsg("请求 Time Out 接口报错!");
                }};
            }
        };
    }
}

参考

  1. Feign 性能优化注意事项
  2. feign 自定义 fallback 方法
  3. 为 Spring Cloud Ribbon 配置请求重试(Camden.SR2+)
  4. Spring cloud 微服务架构之 Ribbon/Fegin 连接超时 ReadTimeout 问题