AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 845171
Accepted
Mindaugas Bernatavičius
Mindaugas Bernatavičius
Asked: 2017-04-19 14:11:18 +0800 CST2017-04-19 14:11:18 +0800 CST 2017-04-19 14:11:18 +0800 CST

代理尝试向上游发送数据到部分关闭的连接(重置数据包)后生成的 HTTP 502 响应

  • 772

我收到代理服务器返回的零星 502。检查数据包流时,我看到 nginx 向原始服务器已发送 [FIN,ACK] 的套接字发送 POST 请求。我想了解这怎么可能以及任何潜在的解决方案。是源的问题(它仅在发送响应后 5 秒后才发送 FIN、ACK)还是代理的问题?

这是说明问题的 PCAP 屏幕截图: 在此处输入图像描述

我的理解:

  • 来自源的响应是 [PSH, ACK];
  • 代理为使用该 [P.] 接收的数据发送一个 [ACK](wireshark 确认下一个 [ACK] 是针对之前收到的 [PSH-ACK]);
  • 7 秒过去了(注意时间戳 btw/ [FIN, ACK] 和我们的 POST ([PSH, ACK]));
  • origin 发送一个 [FIN, ACK]。当发送第一个 [FIN, ACK] 时,源 TCP 状态机应该处于 FIN_WAIT_1 状态。
  • 然后我们发送另一个 POST 导致 [RST] 作为回报,因为源不期望 [PSH, ACK]。

问题:

  • 这种情况的可能解释是什么?
  • 如果代理 (nginx) 已经收到 FIN 并且实际上正在确认它,为什么还要发送另一个请求!(POST [PSH, ACK] 数据包中的 ack 号实际上是 [FIN,ACK] 的 SEQ_NUMBER + 1 - 所以它是在确认幻位 FIN。
  • 来源仅在 5 秒后而不是立即返回 [FIN,ACK] 的可能原因是什么?读取超时/空闲超时?

我不拥有原产地 - 所以无法在那里捕获。

额外细节:

代理上的错误日志(nginx错误日志):

2017/04/17 06:51:07 [error] 123091#0: *225010841 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"

此屏幕截图中显示了最后一个请求的 SEQ 和 ACK 编号:

在此处输入图像描述

networking
  • 2 2 个回答
  • 4892 Views

2 个回答

  • Voted
  1. Best Answer
    Pedro Perez
    2017-04-19T15:08:04+08:002017-04-19T15:08:04+08:00

    这种情况的可能解释是什么?

    源上约 5 秒的空闲计数器与可变的客户端活动之间的竞争条件。第三个涉及的变量当然是网络延迟。

    源站上似乎有一个约 5 秒的空闲计时器,而您的客户端需要约 5 秒的时间通过 Nginx 代理发出第二个请求(POST)。如果前者比后者长(包括网络延迟),那么您就没有问题。如果发送客户端请求只需要一点点时间,那么您就有问题了。

    你可以看到来自 Nginx 的 POST 和 FIN,ACK 是如何一起发送的:分别在源的 FIN,ACK 之后 2.4 毫秒和 2.6 毫秒。这可能会让您偏离正轨,因为我认为 POST 根本不是对来源的 FIN,ACK 的响应。因为它是在源端的 FIN,ACK 之后 2.4ms 发送的

    如果代理 (nginx) 已经收到 FIN 并且实际上正在确认它,为什么还要发送另一个请求!(POST [PSH, ACK] 数据包中的 ack 号实际上是 [FIN,ACK] 的 SEQ_NUMBER + 1 - 所以它是在确认幻位 FIN。

    POST 数据包上的 ACK 号很可能是针对“200 OK”数据包的。在 HTTP 响应之后没有来自服务器端的额外数据,因此来自客户端的任何 ACK 都将 ACKing 相同的数字。

    更新:我们现在知道 POST 数据包的 ACK 号增加了 1,因此 Nginx 知道 [FIN,ACK]。进一步的调查表明这很好:如果机器在收到远程端的响应后不打算继续连接,它可能会发送一个请求并以 [FIN,ACK] 结束,远程端将发送回请求的数据并结束继续 [FIN,ACK] 过程。

    这并没有改变这样一个事实,即源端决定在空闲 5 秒后关闭连接,从而忽略之后不久出现的 POST 数据包(甚至发回 RST - 尽管不清楚这个 RST 是否会'无论如何都已发送)。

    来源仅在 5 秒后而不是立即返回 [FIN,ACK] 的可能原因是什么?读取超时/空闲超时?

    您不必立即返回 FIN,ACK,尤其是在 HTTP 1.1 和持久连接的引入之后。这约 5 秒似乎是原点上的空闲计时器。

    这两件事都在这里得到确认:https ://en.wikipedia.org/wiki/HTTP_persistent_connection - 包括 Apache 2.2 或更高版本中默认的 5 秒空闲超时。

    建议的解决方案

    在不了解您的基础架构的情况下,我无法真正提出解决方案,但粗略地说,您有几个选择:

    • 调查为什么客户端需要 5 秒来发送第二个请求。缺点:耗时且可能意味着应用程序更改。
    • 将原点(Apache?)的超时时间增加到 10 秒。缺点:当您保持更多资源闲置时,问题会扩展。可能需要更改应用程序以尽快处理连接。
    • 不要通过发出“Connection: Close”标头来为第二个 HTTP 请求重用 TCP 连接。缺点:每个请求的成本较高,因为您必须建立一个新的 TCP 会话。可能需要应用程序更改以发布所有请求的标头或 Nginx 上的更改,从而偏离您的默认配置(增加管理成本)。
    • 在上游配置中使用 Nginx 上的“keepalive”选项将 keepalive 设置为低于 5 秒。缺点:很多额外的交通/噪音。

    希望这可以帮助 :)

    • 3
  2. sdcuike
    2018-03-14T01:52:30+08:002018-03-14T01:52:30+08:00

    我认为这是上游服务器socket keep alive超时造成的,socket会被关闭,默认socket.setsolinger不会打开。

    我想我们可以让nginx上游服务器keepalive超时。这里另一个作者解决了,请看这个

    • 0

相关问题

  • 谁能指出我的 802.11n 范围扩展器?

  • 我怎样才能得到一个网站的IP地址?

  • 在一个 LAN 中使用两台 DHCP 服务器

  • 如何在 Linux 下监控每个进程的网络 I/O 使用情况?

  • 为本地网络中的名称解析添加自定义 dns 条目

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve