Nginx报错104:Connection reset by peer问题的解决及分析

目录
  • 问题解决
    • 应用部署环境
    • 现象
    • 解决
      • 过程
      • 最终解决
  • 问题分析
    • 连接重置
    • Tomcat 的 Connector
    • Nginx 104
  • 类似问题解决思路
  • 总结

问题解决

应用部署环境

  • 语言:java
  • 框架:ssm
  • web容器:tomcat
  • 负载:nginx
  • 外层代理:F5

现象

根据客户需求对接一个停车缴费的功能,发布到生产环境之后发现,少量账单同时支付没有问题,一旦同时支付的账单数量超过某个值,就会出现网路连接问题,稳定复现。

解决

过程

首先查看了应用的日志,发现用户提示网络异常的时候,服务端没有任何相关的日志打印,确定请求没有发到服务端

查看Nginx Error日志发现打印了错误信息

2021/09/09 08:38:56 [error] 16299#16299: *240963 readv() failed (104: Connection reset by peer) while reading upstream, client: ****, server: ****, request: "POST ****?formData=E172Rfbkeuw2Z6fFYyg95hUMDmDwaOZT7Mqopwu07lo%3CVxsdDikPopy1XjjtjmvSusJwb7UF3erixZi5Wy099%3CewyDvM3wWhvE8X/z/vxKow2ttM1iHPSmWn...

通过nginx日志发现,虽然是nginx层抛出了错误,但是以日志内容来看,其实nginx已经是将请求的报文完整的接收了下来(这个也是在解决问题之后才反应过来),所以其实问题应该是出在Nginx将请求转给被代理的应用服务的时候。

当时在排查问题的时候,没有考虑到还有一层tomcat,导致哪怕是当时怀疑了问题不在nginx这块,还是不敢相信自己,去网上一顿乱搜。

最终解决

在tomcat/conf/server.xml中,增加Connector中的参数配置maxHttpHeaderSize="65536",增加允许tomcat接收的最大请求头大小

<Connector port="****" protocol="org.apache.coyote.http11.Http11NioProtocol"
               URIEncoding="UTF-8"
                  maxHttpHeaderSize="65536"
               connectionTimeout="20000"
               acceptCount="500" maxThreads="500"
               redirectPort="****" />

问题分析

连接重置

TCP RST

正常情况,服务端使用socket建立一个服务端监听,客户端通过socket向服务端监听发起连接, 双方经过TCP握手协议之后,数据开始传输,TCP协议规定连接在建立之后,双方只要有一端发起关闭的信号,两端就会走放手协议的流程(四次挥手),不再进行数据传输。但是如果一端发起关闭信号之后,不再接收请求,另外一端依然不进入关闭流程,而是依然不停的发送数据,或者是关闭的一端缓存区的数据没有读完就进行了关闭,这时候,关闭的一端就会返回一个RST的信号,告诉另外一端连接被重置

其他情况的RST

除了上边的一种情况,RST还可能出现在客户端找不到服务端端口,服务端因为各种关闭不接收数据等等场景中,但是无一例外,最终就是一端的数据,没有被另外一端完整读取到 ,比如以下几种情况

  1. 客户端直接找不到想要连接的服务端
  2. 一端早就处于关闭的状态了,另外一端还在傻乎乎的给他传输数据
  3. 一端关闭的时候,没有读完另外一端发过来的数据

Tomcat 的 Connector

其实在一定程度上说,Tomcat和Nginx的作用相同,只不过两者的职责不同,Nginx使用了异步非阻塞高性能的组合,可以代理各种各样的URI资源,而Tomcat代理的是一个一个的Servlet容器,它可以容纳所有遵循Servlet规范的应用,并且统一将它们管理。Connector是其中最重要的一部分,它是一个HTTP连接器,它通过启动一个Socket监听,用来接收不同类型的请求,然后把他们解析成对应的Servlet规范的请求,才会将这些请求分发到不同的Servlet中进行处理。当然,内部做了很多其他的事情包括请求校验拦截,请求转化,请求异步线程处理等等。这里只是简单介绍一下,后续会增加关于tomcat部分的文章

Nginx 104

在我们这个案例的场景下分析,nginx要将拿到的请求转发给tomcat中的应用,需要跟tomcat的Connector建立连接,可以将nginx理解为客户端,将tomcat中的Connector理解为socket服务端。tomcat给Connector一套默认的配置,其中maxHttpHeaderSize默认的值是4096字节,也就是4kb。超过4kb的请求头大小的请求,不进行处理,当然这里也有可能发生两种情况,第一种是Connector一开始就知道nginx发过来的请求头过大,直接不接收,响应回去RST标识,还有一种是Connector没有管请求头的大小,直接去接收,但是因为没有将请求头数据读取完就关闭了,响应了RST。这部分没有细看,但是不论怎么说,都是因为上边说过的,没有正常处理完客户端发送过来所有的数据。

类似问题解决思路

在开始无脑查询的时候,其实有很多答案虽然错误码是104,但是报错的原因是不相同的,解决方案也是各不相同,看到过大概以下几种解决思路

  1. nginx的buffer太小,timeout太小。
  2. 长连接,增加长连接超时时间
  3. 将 http version改到1.1 (其实也是使用长连接解决,因为http1.1默认使用长连接)

虽然个人试其他解决方式的时候,都没有成功,也有可能是因为tomcat Connector 连接器的最大请求头4K大小的这个默认配置从最基础的环节直接给把其他配置砍掉了。但是不论使用何种方式解决,最终来说我们就一个思路(虽然说了很像没说),先找到是哪端没有将数据读取完毕,然后想办法让它正常读取

总结

本片文章根据个人发生的实际生产问题,着手解决并且进行问题分析,通过对nginx104的跟踪,对连接重置的概念有一个更详细的了解。

到此这篇关于Nginx报错104:Connection reset by peer问题的解决及分析的文章就介绍到这了,更多相关Nginx报错104:Connection reset by peer内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决nginx报错信息 client intended to send too large body: 1331696 bytes

    解决nginx报错信息 client intended to send too large body: 1331696 bytes 1,nginx后台error日志报错 2016/02/05 16:23:56 [error] 12024#0: *441106971 connect() failed (111: Connection refused) while connecting to upstream, client: 113.214.1.10, server: localhost, req

  • Nginx中报错:Permission denied与Connection refused的解决

    本文主要记录一下各种环境中 nginx 的错误和解决办法,下面话不多说了,来看看详细的介绍吧. 一.13: Permission denied Nginx错误: 2017/04/19 14:46:46 [crit] 4172#0: *671 open() "/data/vhosts/xunlei.com/test/" failed (13: Permission denied), client: 192.168.35.54, server: www.test.com, request:

  • nginx上传文件大小报错500的解决办法

    nginx上传文件大小报错500的解决办法 采用nginx作反向代理,出现了一个诡异的问题,小文件可以提交,大文件会报500内部错误.这个是什么原因导致的呢? 查wiki可知,上传文件大小相关的有三个配置 client_body_buffer_size 配置请求体缓存区大小, 不配的话, client_body_temp_path 设置临时文件存放路径.只有当上传的请求体超出缓存区大小时,才会写到临时文件中 client_max_body_size 设置上传文件的最大值 所以查出来,问题出现的原

  • Nginx报错104:Connection reset by peer问题的解决及分析

    目录 问题解决 应用部署环境 现象 解决 过程 最终解决 问题分析 连接重置 Tomcat 的 Connector Nginx 104 类似问题解决思路 总结 问题解决 应用部署环境 语言:java 框架:ssm web容器:tomcat 负载:nginx 外层代理:F5 现象 根据客户需求对接一个停车缴费的功能,发布到生产环境之后发现,少量账单同时支付没有问题,一旦同时支付的账单数量超过某个值,就会出现网路连接问题,稳定复现. 解决 过程 首先查看了应用的日志,发现用户提示网络异常的时候,服务

  • PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析

    本文实例讲述了PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法.分享给大家供大家参考,具体如下: 环境错误级别:error_reporting =E_ALL 某天我在研究一下php下的正则替换函数perg_replace(), 示例: 代码: $subject="2222<b>a</b>2222fff222222222A22222"; $pattern = "/(a)/e&q

  • PHP执行Curl时报错提示CURL ERROR: Recv failure: Connection reset by peer的解决方法

    最近在使用curl中遇到CURL ERROR: Recv failure: Connection reset by peer的报错提示,现把解决方法与大家共享,希望对大家有所帮助. 我们经常用curl来访问web站点,web站点目前主要分为http和https两种协议,众所周知https类型的网站都是通过ssl协议+http协议的,是目前最安全的网站协议,访问此类网站的时候,会走ssl协议,验证访问者的证书,检测是否安全. 通过curl访问此类网站也是如此流程,但是curl中需要添加相应的参数,

  • connection reset by peer问题总结及解决方案

    找遍了 中英文网站,翻遍了能找的角落,发现了出现故障的原因和原理,及改如何处理,这里记录下,希望能帮助到有需要的小伙伴,少走点弯路, 以上就整理内容: connection reset by peer问题总结及解决方案 1.服务器的并发连接数超过了其承载量,服务器会将其中一些连接关闭 如果知道实际连接服务器的并发客户端数并没有超过服务器的承载量,则有可能是中了病毒或者木马,引起网络流量异常. 解决方法:可以使用netstat -an命令查看网络连接情况. 2.客户端关掉了浏览器,而服务器还在给客

  • Laravel 5.4中migrate报错: Specified key was too long error的解决

    前言 大家都知道,我们经常做项目都团队协作开发,每个人都在自己本地的数据库,如果你曾经出现过让同事手动在数据库结构中添加字段的情况,数据库迁移可以解决你这个问题. 不仅如此,在线上部署的时候,也避免了手动导入数据库或手动修改数据结构的麻烦,数据迁移帮你方便的维护着数据结构. 但方便的同时也会伴随着一些问题,下面这篇文章将详细给大家介绍关于Laravel5.4中migrate报错Specified key was too long error的解决方法,下面话不多说了,来一起看看详细的介绍吧. 发

  • python报错: 'list' object has no attribute 'shape'的解决

    numpy.array可使用 shape.list不能使用shape. 可以使用np.array(list A)进行转换. (array转list:array B B.tolist()即可) 补充知识:Pandas使用DataFrame出现错误:AttributeError: 'list' object has no attribute 'astype' 在使用Pandas的DataFrame时出现了错误:AttributeError: 'list' object has no attribut

  • 安装Docker Desktop报错WSL 2 installation is incomplete的问题(解决报错)

    报错描述 我们安装Docker Desktop的时候,他会问我们是否需要使用WSL2(基于Windows的Linux子系统),如果我们不适用,就会使用Hyper-v虚拟机运行,不过相比于虚拟机,子系统在性能方面更加出色.在我们选择使用WSL2之后,并且我们也确定打开了如下图所示的Windows功能(如果没有打开,请先百度如何打开wsl.) 还是会出现一个下图所示的报错. 解决报错 更加报错提示,猜测可能是我们使用的wsl2版本老了,需要我们自己手动更新一下,我们根据提示去微软官网下载最新版的ws

  • 关于报错IDEA Terminated with exit code 1的解决方法

    本人亲测,在使用IDEA使用Maven模板创建项目或者在当前项目中New Project,Maven的以下三个配置参数会重置使用C:\Users\ZSAndroid\.m2的默认maven下载方式. Maven home path(Maven安装路径) User settings file(Maven下载使用的settings.xml) Local repository(Maven本地仓库,settings.xml下载存放资源的目录) 如果在IDEA构建项目时遇到下面这样的报错IDEA Term

  • phpmyadmin报错:#2003 无法登录 MySQL服务器的解决方法

    通过phpmyadmin连接mysql数据库时提示:"2003 无法登录 MySQL服务器"...很明显这是没有启动mysql服务,右击我的电脑-管理-找到服务,找到mysql启动一下,,是不是启动有报错: "无法启动mysql服务 错误1067:进程意外中止 " 然后就baidu google吧,多是说禁远程连接,要改my.ini文件,也有说防火墙的,总之对症下药. 不过同样的报错,导致它的原因并不是都是同样的.这就是看自己的经验和对问题的钻研了,好了不多 说了,

随机推荐