总结:浏览器与Nginx的keepalive时间需要等于Nginx与应用服务器keepalive的时间

从ingress的监控中心,我们看到,失败率虽然不高,但始终保持在0.05到0.1的水平:

我们用这样的条件去查询,发现绝大部分错误是502错误:


status>=500 | select status, count(*) a group by status order by a desc

那么502错误到底是个什么错误呢?百度百科给出的解释是:

502 Bad Gateway是指错误网关,无效网关;在互联网中表示一种网络错误。表现在WEB浏览器中给出的页面反馈。它通常并不意味着上游服务器已关闭(无响应网关/代理) ,而是上游服务器和网关/代理使用不一致的协议交换数据。鉴于互联网协议是相当清楚的,它往往意味着一个或两个机器已不正确或不完全编程。

还有人说是超时导致的:

马上在评论区有人反驳:

百度百科对504错误的解释:

504错误代表网关超时(Gateway timeout),是指服务器作为网关或代理,但是没有及时从上游服务器收到请求。服务器(不一定是Web 服务器)正在作为一个网关或代理来完成客户(如您的浏览器或我们的CheckUpDown 机器人)访问所需网址的请求。

显然,504错误才是超时,而502并不是。

而且从我们对502错误日志的进一步分析来看,发生502错误时的请求时间和响应时间都极短,不可能是超时。

查502与504的区别,只有这个说法相对靠谱:

也就是说我们后端的服务是能够响应的,但响应不符合要求,所以出现了502错误。但这种错误并不是必然的,如果是必然出现,则网站整体不可用,早就被发现了,正因为它是偶发的,所以有必要看一下在发生502的时候到底发生了什么。

为此我们把nginx的logtail日志的stderr输出打开:

此前这里本来是false,现在我们把它改成true,使它能够将错误日志输出出来,便于我们查找原因。

stderr错误输出之后,立刻就能在日志里看到大量的这种错误:


2022/04/02 16:59:55 [error] 11168#11168: *739601507 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 49.93.83.68, server: www.domain.com, request: "POST /myserver/service HTTP/1.1", upstream: "http://192.108.1.121:8080/myserver/service", host: "www.domain.com"

从字面意思来理解,是说上游服务器直接关闭了连接。但是上游服务器为什么要关闭连接呢?将错误信息放入搜索引擎进一步排查,很多文章将我们的思路导向了keepalive这个方向,最应该检查的是keepalive_timeout和keepalive_request这两个属性。

什么是keepalive?这是http 1.1协议的缺省配置,在http 1.0的时候,如果你的网页上有10个图片,那么浏览器和服务器之间要同时建立10个连接,把这10个图片发过去然后再关闭这10个连接,显然对于服务器来说,建立10个连接再关闭10个连接,消耗是比较大的。所以在http 1.1协议里增加了keepalive的功能,在发10张图片的时候只需要建立一个连接就够了,只要还有内容要传输,这个通道会始终保持开放状态,不会在传输完毕之后立刻关闭,这就是keepalive保活的意思。

但是keepalive不能把这个连接永远保持,如果没有内容了还继续保持,无疑也是一种浪费,所以这里就产生了超时的概念,keepalive_timeout的意思是说如果这个连接当中没有内容传输了并且超过了这个时间,那么就把这个连接断掉,keepalive_requests的意思是说我们这个连接最多允许传输多少个内容,超过这个内容那么也把它断掉。

那么这个keepalive_timout和我们的502错误之间有什么关系呢?因为所有网站的架构都不是浏览器直接连接后端的应用服务器,而一定是中间有nginx服务器做反向代理的,浏览器和nginx服务器之间建立keepalive连接,nginx再和后端的应用服务器建立keepalive连接,所以这是两种不同的keepalive连接。我们把浏览器和nginx之间的keepalive连接叫做ka1,把nginx和应用服务器之间的keepalive连接叫做ka2。

如果ka1的超时设置为100秒,也就是说如果100秒之内没有新内容要传输,就把nginx和浏览器之间的连接断掉。而同时,我们把ka2设置为50秒,也就是说如果nginx和应用服务器之间没有新内容要传输,那么就把应用服务器和nginx之间的连接断掉。那么这时候就会产生一个问题:前50秒没有传输内容,在第51秒的时候,浏览器向nginx发了一个请求,这时候ka1还没有断掉,因为没有到100秒的时间,所以这是没有问题的,但是当nginx试图向应用服务器发请求的时候就出问题了,ka2断了!因为ka2的超时设置是50秒,这时候已经超了,所以就断了,这时候nginx无法再从应用服务器获得正确响应,只好返回浏览器502错误!

但是我们根本就没有设置过这些参数啊,怎么会有这种问题呢?

这没关系,既然没有设置过,那系统肯定用的是缺省参数,我们来看一下ka1的缺省设置是多少,也就是nginx(ingress)和浏览器之间的缺省的keepalive_timeout值:

upstream-keepalive-timeout

Sets a timeout during which an idle keepalive connection to an upstream server will stay open. default: 60

ka1的缺省设置是60秒。

我们再看一下ka2的缺省设置是多少秒,Tomcat官方文档上说:

The number of milliseconds this Connector will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the connectionTimeout attribute. Use a value of -1 to indicate no (i.e. infinite) timeout.

缺省值等同于connectionTimeout的值,那connectionTimeout等于多少呢?

The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. Use a value of -1 to indicate no (i.e. infinite) timeout. The default value is 60000 (i.e. 60 seconds) but note that the standard server.xml that ships with Tomcat sets this to 20000 (i.e. 20 seconds). Unless disableUploadTimeout is set to false, this timeout will also be used when reading the request body (if any).

connectionTimeout的缺省值是60秒,但是,他们提供的标准的server.xml里把这个值设为了20秒!

那么现在问题就很清楚了,我们的ka1是60秒,而ka2是20秒,从21秒到60秒之间的任何时间有请求进来都会发生502错误。

找到了问题的根源,解决起来就好办了,我们只需要确保ka1的超时设置小于ka2的设置就够了。或者修改ka1,或者修改ka2,都是可以的。

我们先修改ka1看一下,对于ingress来说,要修改ka1需要在ingress的configMap中修改,所以我们找到configMap设置的地方,给它增加一个新的属性:

这里我们把upstream-keepalive-timeout设为4,确保它低于ka2的20,设置完之后,ingress会自动加载新设置,我们看一下结果:

原先不断产生的502错误彻底消失了!

再来看一下错误图:

注意那个黄颜色的5XX比例,从我们设置好的那一瞬间,永远趴在了地上!

我们是如何解决偶发性的 502 错误的相关推荐

  1. Linux下使用Nginx端口转发出现502错误的一种解决办法

    今天圈里的一个朋友在配置完nfinx80端口转发到5000后,发现一个问题 问题描述: 正确配置了Nginx80端口转5000端口,在CentOS上把.Net core WebAPI站点上传到cent ...

  2. [转]nginx+php-fpm.sock时504,502错误解决办法

    2019独角兽企业重金招聘Python工程师标准>>> 本文通过 OscPress 同步至oschina,获取最新版本和更好的阅读体验请查看原文: http://s.blog.cel ...

  3. nginx常见502错误提示原因和解决方法

    Nginx 502错误情况1: 网站的访问量大,而php-cgi的进程数偏少. 针对这种情况的502错误,只需增加php-cgi的进程数.具体就是修改/usr/local/php/etc/php-fp ...

  4. nginx 502错误原因和解决办法总结

    nginx 502错误原因和解决办法总结 一.NGINX 502错误排查 二.Nginx 413错误的排查:修改上传文件大小限制 三.Nginx 400错误排查:HTTP头/Cookie过大 一.NG ...

  5. Nginx 502错误原因和解决方法

    一.NGINX 502错误排查 NGINX 502 Bad Gateway错误是FastCGI有问题,造成NGINX 502错误的可能性比较多.将网上找到的一些和502 Bad Gateway错误有关 ...

  6. Nginx 502错误原因和解决方法总结

    一. 前沿 不管你是做运维还是做开发,哪怕你是游客,时不时会遇到502 Bad Gateway或504 Gateway Time-out.出现这页面,把服务重启下,再实在不行重启下服务器,问题就解决了 ...

  7. nginx常见502错误的解决方法

    Nginx 502错误情况1: 网站的访问量大,而php-cgi的进程数偏少. 针对这种情况的502错误,只需增加php-cgi的进程数.具体就是修改/usr/local/php/etc/php-fp ...

  8. 502网关错误解决_什么是502错误网关错误(以及如何解决)?

    502网关错误解决 A 502 Bad Gateway Error occurs when you try to visit a web page, but one web server gets a ...

  9. CentOS 7搭建GitLab服务器踩坑——解决Whoops, GitLab is taking too much time to respond 502 错误

    问题描述 按照官方教程GitLab Installation一步步操作下来,成功下载和安装了GitLab,相关配置也改了,external_url改成了服务器的ip和开放的端口号,端口号在防火墙上也开 ...

  10. nginx中的502错误

    遇到这种情况,首先看一下慢日志 [17-Aug-2015 13:13:43] WARNING: [pool www] child 27780, script '/data/s.com/index.ph ...

最新文章

  1. 如何从stackoverflow的api 中获取是数据_教你拼多多如何选款、测款,打造出爆款。...
  2. 1.一步一步移植ucos到stm32f103开发版(修订版)
  3. 中国文学发展史思维导图
  4. Java Vector与ArrayList的区别
  5. 【Java面试题视频讲解】字符串按指定长度分隔
  6. 数据结构---关键路径
  7. c语言线程传int值,如何用C语言实现多线程
  8. 【ES9(2018)】for await...of
  9. 风变Python8编程时,两大思维模式
  10. AngularJs(Part 3)--注册服务
  11. Spring Data Rest如何暴露ID字段
  12. PAT——1005. 继续(3n+1)猜想 (25)
  13. startActivity报错exposed beyond app through Intent.getData()
  14. 服务器snb芯片组,认识6系列主板芯片组
  15. ubuntu 18.04 pycharm生成快捷方式 ,亲测有效!!
  16. direct 3d 渲染红蓝立体效果
  17. gcc编译工具常用命令以及汇编语言
  18. SQL语句汇总(终篇)—— 表联接与联接查询
  19. 为个人信息安全加“保险锁” 多家快递公司启用隐私面单
  20. 李青云老人的长寿秘诀【转】

热门文章

  1. tk免费顶级域名注册及使用
  2. AiTrust下预训练和小样本学习在中文医疗信息处理挑战榜CBLUE表现
  3. Postman:脚本应用_pm对象
  4. 红包雨架构设计---1、技术架构
  5. Java——哈希值是什么?
  6. UG NX二次开发(C#)-分析-测量体对象的体积
  7. word2019关闭时无响应
  8. 分类模型中准确率、敏感度、特异度的理解
  9. ChineseWiki︱百万中文维基百科词条下载与整理
  10. python采集微信聊天信息_我用 Python 破解了微信聊天记录,自动同步微信文章