聊聊nginx与tomcat的5xx

本文主要讲述一下nginx与tomcat的502、504、503错误及其常见的产生原因。

502

定义

502 Bad Gateway : 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

常见原因

  • 后端服务挂了的情况,直接502
  • 后端服务在重启

实例

将后端服务关掉,然后向nginx发送请求后端接口,日志如下:

  • access.log
127.0.0.1 - - [22/Dec/2017:20:44:38 +0800] "GET /timeout/long-write HTTP/1.1" 502 537 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36"
  • error.log
2017/12/22 20:45:12 [error] 1481#0: *3 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /timeout/long-write HTTP/1.1", upstream: "http://[::1]:8080/timeout//long-write", host: "localhost:8888"

504

定义

504 Gateway Timeout : 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。注意:某些代理服务器在DNS查询超时时会返回400或者500错误

常见原因

  • 该接口太耗时,后端服务接收到请求,开始执行,未能在设定时间返回数据给nginx
  • 后端服务器整体负载太高,接受到请求之后,由于线程繁忙,未能安排给请求的接口,导致未能在设定时间返回数据给nginx

实例

  • 前端返回
<html>
<head><title>504 Gateway Time-out</title></head>
<body bgcolor="white">
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>openresty/1.9.15.1</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
  • access.log
192.168.99.1 - - [22/Dec/2017:21:58:20 +0800] "GET /timeout/long-resp HTTP/1.1" 504 591 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36" "-" "-"
  • error.log
2017/12/22 21:58:20 [error] 5#5: *7 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.99.1, server: , request: "GET /timeout/long-resp HTTP/1.1", upstream: "http://192.168.99.100:8080/timeout//long-resp", host: "192.168.99.100:8686"
  • nginx.conf
        location /timeout/long-resp {
            proxy_connect_timeout    30;
            proxy_read_timeout       100;
            proxy_send_timeout       10;
            proxy_pass http://192.168.99.100:8080/timeout/long-resp ;
        }
  • java代码
    @GetMapping("/timeout/long-resp")
    public String longResp() throws InterruptedException {
        TimeUnit.SECONDS.sleep(120);
        return "finish";
    }

服务器接受请求一直没有返回,nginx在等待100秒后报Connection timed out,返回504;但是后端继续执行,在第120秒才执行完。

503(相对少见)

定义

503 Service Unavailable : 表示服务器当前处于暂时不可用状态,无论是有意还是无意,当服务器端处于无法应答的状态时,就会返回该状态码。其中,服务端因维护需要而停止服务属于有意的情况。而当服务器自身负载过高,处于无法响应的状态时,则属于无意的情况。另外,负载均衡器或者web服务器的前置机等这些地方的服务器也有可能返回503.

常见原因

  • nginx进行限流,超过限速则返回503
  • 后端服务进行常规维护,比如pause tomcat

nginx限流返回503实例

  • config
http{
    ## test 503
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
        listen 8686;
        location /timeout {
            limit_conn addr 1;
            proxy_connect_timeout    30;
            proxy_read_timeout       100;
            proxy_send_timeout       2;
            proxy_pass http://192.168.99.100:8080/timeout/ ;
        }
    }
}
  • error.log
2017/12/24 20:58:29 [error] 5#5: *1473 limiting connections by zone "addr", client: 192.168.99.1, server: , request: "GET /timeout/busy HTTP/1.1", host: "192.168.99.100:8686"
  • access.log
192.168.99.1 - - [24/Dec/2017:20:58:39 +0800] "GET /timeout/busy HTTP/1.1" 503 219 "-" "-" "-" "-"
  • client
wrk -t12 -c200 -d100s -T60s  --latency http://192.168.99.100:8686/timeout/busy
➜  ~ curl -i http://192.168.99.100:8686/timeout/busy
HTTP/1.1 503 Service Temporarily Unavailable
Server: openresty/1.9.15.1
Date: Sun, 24 Dec 2017 12:58:26 GMT
Content-Type: text/html
Content-Length: 219
Connection: keep-alive
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body bgcolor="white">
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>openresty/1.9.15.1</center>
</body>
</html>

tomcat返回503实例

  • Http11Processor
    tomcat-embed-core-8.5.23-sources.jar!/org/apache/coyote/http11/Http11Processor.java
    @Override
    public SocketState service(SocketWrapperBase<?> socketWrapper)
        throws IOException {
        RequestInfo rp = request.getRequestProcessor();
        rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);

        // Setting up the I/O
        setSocketWrapper(socketWrapper);
        inputBuffer.init(socketWrapper);
        outputBuffer.init(socketWrapper);

        // Flags
        keepAlive = true;
        openSocket = false;
        readComplete = true;
        boolean keptAlive = false;
        SendfileState sendfileState = SendfileState.DONE;

        while (!getErrorState().isError() && keepAlive && !isAsync() && upgradeToken == null &&
                sendfileState == SendfileState.DONE && !endpoint.isPaused()) {
                //......

                if (endpoint.isPaused()) {
                    // 503 - Service unavailable
                    response.setStatus(503);
                    setErrorState(ErrorState.CLOSE_CLEAN, null);
                } else {
                    keptAlive = true;
                    // Set this every time in case limit has been changed via JMX
                    request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
                    if (!inputBuffer.parseHeaders()) {
                        // We've read part of the request, don't recycle it
                        // instead associate it with the socket
                        openSocket = true;
                        readComplete = false;
                        break;
                    }
                    if (!disableUploadTimeout) {
                        socketWrapper.setReadTimeout(connectionUploadTimeout);
                    }
                }

        }    
    }        

只要endpoint的状态是paused,则返回503

  • AbstractEndpoint
    tomcat-embed-core-8.5.23-sources.jar!/org/apache/tomcat/util/net/AbstractEndpoint.java
    /**
     * Pause the endpoint, which will stop it accepting new connections.
     */
    public void pause() {
        if (running && !paused) {
            paused = true;
            unlockAccept();
            getHandler().pause();
        }
    }

    /**
     * Resume the endpoint, which will make it start accepting new connections
     * again.
     */
    public void resume() {
        if (running) {
            paused = false;
        }
    }

这里是endpoint的pause以及resume方法

  • 请求

当请求进入Http11Processor的service方法到执行endpoint.isPaused()方法期间,tomcat被pause了,这个时候,就会返回503,如下:

➜  ~ curl -i http://localhost:8080/demo/test
HTTP/1.1 503
Transfer-Encoding: chunked
Date: Sun, 24 Dec 2017 14:10:16 GMT
Connection: close

小结

  • 502
    通常是后端服务挂了或在重启
  • 504
    通常是请求的接口执行耗时,亦或是后端服务负载高,执行耗时
  • 503
    通常是nginx限流或后端服务pause进行维护

doc

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • Page 1:nginx 服务器安装及配置文件详解 CentOS 6.2 x86_64 安装 nginx 1.1 ...
    xiaojianxu阅读 8,524评论 1 41
  • 本文将介绍Linux环境下如何安装Web服务基础运行环境,包括以下内容: 安装jdk安装Tomcat安装MySQL...
    daling菜鸟阅读 2,831评论 0 9
  • nginx在工作中已经有好几个环境在使用了,每次都是重新去网上扒博客,各种编译配置,今天自己也整理一份安装文档和n...
    AndyChin阅读 2,292评论 0 4
  • 当前工作已经接近尾声看着熙芸预测的结果一步步变成现实我既是观众又是演员甚至还是导演看着公司一步步走到这个阶段有一种...
    承谦阅读 157评论 0 0