热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

有关服务端主动关闭socket带来的几个问题分析tcp四次握手半关闭问题导致

     一、场景:nginx开启keep-alive:     问题描述:  upstream prematurely closed connection

     一、场景:nginx开启keep-alive:


 

  问题描述:

 upstream prematurely closed connection while reading response header from upstream, client: X.90.10, server: www.example.com, request: "POST /web/?a=b HTTP/1.1", upstream: "http://X.32.238:80/web/?a=b", host: "www.example.com"

        问题根本原因:keep-alive设置空闲连接数过多,当上游服务器处于tcp半关闭状态的时候,空闲连接被启用发送数据,导致此问题会发生。

 解决途径:

(1)keep-alive设置建议尽可能小,需要根据tps设置,目的是让空闲的连接不要碰到那个半关闭的时间点

(2)nginx版本1.15.3增加了配置keepalive_timeout,让nginx主动关闭空闲连接,此值一定要设置的比上游服务器短。

(3)如果nginx版本比较低,可以用http://tengine.taobao.org/document/http_upstream_keepalive_timeout.html或https://github.com/nviennot/nginx-tcp-keepalive模块。


    

首先必须理解这个keep-alive配置:

 nginx此配置描述:

Syntax:    keepalive connections;
Default:    —
Context:    upstream
This directive appeared in version 1.1.4.

   Activates the cache for connections to upstream servers.

   The connections parameter sets the maximum number of idle keepalive connections to upstream servers that are preserved in the cache of each worker process. When this number is exceeded, the least recently used connections are closed.

   It should be particularly noted that the keepalive directive does not limit the total number of connections to upstream servers that an nginx worker process can open. The connections parameter should be set to a number small enough to let upstream servers process new incoming connections as well.

 

  一句话:连接池中空闲连接数目,但此数目不影响ningx与上游服务器连接数数目,官方建议此数设置的尽可能小。

   经过wireshark服务器命令行抓包,图形界面分析(当时让运维给我抓包分析的,因为线上的问题,机器没权限,主要根据nginx报错的时间慢慢找到的):

      此连接空闲了30秒,上游服务器发生了FIN标志(倒数第三行),但是此时此连接被重用发生数据了,由于tcp四次握手处于半关闭状态,上游服务器送了FIN标志包,就不能再向nginx发送数据了,但是还能接受nginx发送数据,所以问题就产生了。

 

  提供了几种解决方案,运维先调小了keep-alive数目,错误不再出现了。

 

二、用netty做了一个gateway项目,server端(接受web和移动端rest请求)和client端(与上游服务器交互,开启了长连接),当用ab压测的时候,总会卡住,并最终报错:ab (Apache Bench) error: apr_poll: The timeout specified has expired (70007) 

 

      项目中通过client端计数统计发生请求数目与返回数目对比,返回数目总是有少数几个没返回(是不是变成黑洞了)。

     寻找问题:测试接口增加查询参数a=请求顺序号,返回打印此顺序号,压测结束后,对日志分析,寻找丢失的返回序列号:

cat xx.log.info |grep '==========>>返回序列号'|awk '{print $8}'|sort -n | cat -n

   上述命令是为了过滤所有的返回序列号并排序,然后用cat -n增加顺序递增序列号,通过对比找到丢失的序列号,  这里找出一个:16916,通过此序列号,我们还必须对经过抓包的数据查询此序列号的请求:

ip.dst==10.2.4.19 && tcp.dstport==80 && http.request.uri  contains "a=16916"

 主要过滤查询为:http.request.uri  contains "a=16916",过滤后的数据:

beaverdeMacBook-Pro.local为本地机器。

       通过分析最后 的数据包,上游服务端主动关闭了连接。这条连接基本上没空闲,为什么会关闭呢(不是场景1的现象),我们分析一下上游服务器最近两次的返回http头信息发现:倒数第二次是Connection:keep-alive(上图红线),最后一次是Connection:close(下图红线),代表上游服务器返回后告知网关客户端,此连接马上关闭,不能再利用此连接了,但是后续发现,网关客户端又发生了数据(下图),由于网关客户端没能很好的处理关闭问题,导致了bug的发生,需要根据返回的http包来判断是不是还能重用此长连接。

 

 

 

先列出上面两个场景吧,其实这些都和TCP协议四次握手协议相关,需要抓包分析,然后根据现象分析问题产生原因。

 

参考:

https://serverfault.com/questions/845171/http-502-response-generated-by-a-proxy-after-it-tries-to-send-data-upstream-to-a/901372#901372

https://theantway.com/2017/11/analyze-connection-reset-error-in-nginx-upstream-with-keep-alive-enabled/

https://theantway.com/2017/11/analyze-connection-reset-error-in-nginx-upstream-with-keep-alive-enabled/

http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm

 


推荐阅读
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 如何在php文件中添加图片?
    本文详细解答了如何在php文件中添加图片的问题,包括插入图片的代码、使用PHPword在载入模板中插入图片的方法,以及使用gd库生成不同类型的图像文件的示例。同时还介绍了如何生成一个正方形文件的步骤。希望对大家有所帮助。 ... [详细]
  • 本文介绍了NetCore WebAPI开发的探索过程,包括新建项目、运行接口获取数据、跨平台部署等。同时还提供了客户端访问代码示例,包括Post函数、服务器post地址、api参数等。详细讲解了部署模式选择、框架依赖和独立部署的区别,以及在Windows和Linux平台上的部署方法。 ... [详细]
author-avatar
汽车时尚宠
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有