Spring Cloud Zuul 网关超时配置的几种方式

微服务项目在使用zuul作为网关时,由于zuul的线程模型,对下游接口必须要设置超时时间和熔断机制,本文主要是叙述设置路由超时的方式。


zuul的超时配置有两种方式:

  1. 直接使用url配置的路由,是基于httpclient来发送请求,可以直接设置socket的连接时间
  2. 使用ribbon的轮训机制,可以配置ribbon超时时间,也可以配置hystrix超时时间,两者取配置最小者

直接使用url路由配置事例:

  1. 适用于ApacheHttpClient,如果是okhttp无效。每个服务的http客户端连接池最大连接,默认是200.
    zuul.host.max-total-connections=1000
  2. 适用于ApacheHttpClient,如果是okhttp无效。每个route可用的最大连接数,默认值是20。
zuul.host.max-per-route-connections=500
zuul.host.socket-timeout-millis=3000
zuul.host.connect-timeout-millis=500
  1. 使用这种方式时,最好增加一个error的zuulFilter,以便处理异常,返回响应的文案:
public Object run() {
        try {
            RequestContext ctx = RequestContext.getCurrentContext();
            ctx.setSendZuulResponse(false);
            ctx.remove("throwable");
            ctx.remove("error.status_code");
            ctx.getResponse().setContentType("text/html;charset=UTF-8");
            ctx.getResponse().setCharacterEncoding("UTF-8");
            InputStream inputStream = ctx.getResponseDataStream();
            Map returnMap = RequsetReturnValueUtils.createReturnMap(
                  1, "服务器异常", new JSONObject());
            String returnJson = JSON.toJSONString(returnMap);
            InputStream inputStream ;
            inputStream = new ByteArrayInputStream(returnJson.getBytes("utf-8"));
            ctx.setResponseDataStream(inputStream);
            ctx.setResponseStatusCode(200);
            ctx.setResponseGZipped(false);
        } catch (Exception ex) {
            logger.error("CurrencyErrorFilter run(){}" ,ExceptionUtils.getFullStackTrace(ex));
        }
        return null;
    }

重点说下使用ribbon的配置

基于ribbon的serviceid的配置,可以用到hystrix等的降级、熔断等功能,hystrix按照serviceid 设置,同默认设置的优先级,由低到高:
1. hystrix.command.default.XXX
2. hystrix.command.[HystrixCommandKey].XXX
3. Hystrix代码内置属性参数值

具体配置代码如下:

zuul.routes.api-v1-config.path=/gw-passenger/config/**
api-v1-config.ribbon.listOfServers=http://test-inside-mp.***.com
zuul.routes.api-v1-config.sensitiveHeaders="*"
hystrix.command.api-v1-config.execution.isolation.thread.timeoutInMilliseconds=1000
hystrix.command.api-v1-config.execution.isolation.semaphore.maxConcurrentRequests=100 单独配置

最好增加fallback的实现,以便在超时时增加自定义处理逻辑

/**
 * 熔断fallback
 */
@Component
public class MyZuulFallbackProvider implements ZuulFallbackProvider {
    private static Logger logger = LoggerFactory.getLogger(MyZuulFallbackProvider.class);

    @Override
    public String getRoute() {
        return "*";//所有路由
    }

    @Override
    public ClientHttpResponse fallbackResponse() {
        logger.error("route fallback");
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }
            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }
            @Override
            public String getStatusText() throws IOException {
                return "OK";
            }
            @Override
            public void close() {
            }

            @Override
            public InputStream getBody() throws IOException {
                JSONObject returnObject = new JSONObject();
                returnObject.put("code", 1);
                returnObject.put("msg", "接口降级");
                returnObject.put("time", System.currentTimeMillis());
                return new ByteArrayInputStream(returnObject.toJSONString().getBytes("utf-8"));
            }
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
           headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

要使用hystrix的超时fallback,必须设置:

hystrix.command.default.execution.timeout.enabled=true  默认开启

hystrix相关配置

  • 设置隔离方式
    execution.isolation.strategy= THREAD|SEMAPHORE

  • zuul.semaphore.max-semaphores
    是一个绝对值,无时间窗口,相当于亚毫秒级的。当请求达到或超过该设置值后,其余请求会被拒绝。默认100,这个值最好是根据每个后端服务的访问情况,单独设置。

  • execution.isolation.thread.timeoutInMilliseconds
    用来设置thread和semaphore两种隔离策略的超时时间,默认值是1000。可以针对service-id单独设置。
    单独设置时,要根据所对应的业务和服务器所能承受的负载来设置,一般是大于平均响应时间的20%~100%,最好是根据压力测试结果来评估,这个值设置太大,会导致线程不够用而会导致太多的任务被fallback;设置太小,一些特殊的慢业务失败率提升,甚至会造成这个业务一直无法成功,在重试机制存在的情况下,反而会加重后端服务压力。

  • execution.isolation.semaphore.maxConcurrentRequests
    指任意时间点允许的并发数。当请求达到或超过该设置值后,其其余就会被拒绝。默认值是100。

  • execution.timeout.enabled
    要使用hystrix的超时fallback,必须设置,默认开启

  • execution.isolation.thread.interruptOnTimeout
    发生超时是是否中断线程,默认是true。

  • execution.isolation.thread.interruptOnCancel
    取消时是否中断线程,默认是false。
    *hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests
    设置fallback的线程数,默认是10,这个值在大量触发fallback逻辑时要注意调整。

总结:

spring cloud zuul 使用起来还是非常方便的,通过hystirx也能达到一些降级和熔断的功能,其pre、route、post三阶段机制很大程度上方便了我们做扩展,但是在路由配置方面不大方便,可以结合spring cloud config 或者直接通过统一配置来添加路由。

你可能感兴趣的:(Spring Cloud Zuul 网关超时配置的几种方式)