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<String, Object> 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 或者直接通过统一配置来添加路由。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342