如何在 curl 中禁用 keepalive

如何在 curl 中禁用 keepalive

我试图弄清楚如何在通过 发出 HTTP 请求的各种客户端计算机上一致地关闭 keepalive curl

这是我的目标服务器:

- Ubuntu 18.04.2 LTS
- 4.15.0-47-generic
- HA-Proxy version 1.8.19-1ppa1~bionic 2019/02/12

这是我正在发布的客户端 1 curl(原始安装):

- Ubuntu 16.04.3 LTS
- 4.4.0-62-generic
- curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3

这是我正在发布的客户端 2 curl(原始安装):

- Ubuntu 18.04 LTS
- 4.15.0-20-generic
- curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3

为了关闭 keepalive,我尝试使用-H "Connection: close"--no-keepalive并且--keepalive-time 1只有第一个选项似乎有效,但仅限于客户端 1。

在客户端 1 (Ubuntu 16) 上,连接不会保持打开状态,但在客户端 2 (Ubuntu 18) 上,连接会保持打开状态,直到超时。我通过查看目标服务器watch -n 0.1 "netstat -na | fgrep CLIENT_IP_ADDRESS"或在两个客户端上使用来确认这-vvv一点,在客户端 1 上始终为* Closing connection 0,在客户端 2 上始终为* Connection #0 to host www.example.com left intact

客户端 1 和 2 之间的区别显然是 Ubuntu 版本和 curl 版本。是什么原因导致客户端 1 中的连接已关闭,而客户端 2 中的连接未关闭?

我还发现,如果我将目标服务器更改为另一台运行旧发行版和旧 apache httpd 的机器,那么我是否发送消息Connection: close没有任何区别,并且我的两个客户端始终使用 keepalive。因此,我认为目标服务器配置也在其中发挥了一定作用。

编辑:事情变得更加复杂,如果我从客户端 1 和 2 通过 向目标服务器发出请求,ab则连接会立即中断。这是意料之中的,因为ab使用的是HTTP/1.0而不是HTTP/1.1。但是,如果我使用 Apache 定位旧发行版,那么在这两种情况下,连接都保持打开状态。这意味着,接收端确实也发挥了作用。

编辑2:我/proc/sys/net/ipv4/通过以下方式获取了两个客户端的所有设置:

for file in /proc/sys/net/ipv4/*
do
  echo "$file $(cat $file)"
done

这些可以在这里找到:

答案1

--no-keepalive 选项仅对 TCP keepalive 数据包有用,正如 curl 网站上的这个存档线程中提到的那样:https://curl.haxx.se/mail/archive-2013-04/0037.html

听起来你需要特别禁用 HTTP keepalive 数据包,这可以在你的服务器上使用 keepalive_timeout 0 来完成;正如这个 stackoverflow 线程中提到的那样https://stackoverflow.com/questions/24924237/linux-curlnginx-cant-request-with-no-keepalive

如果格式不正确,请见谅,这是我的第一篇帖子 :)

希望有帮助!

答案2

https://everything.curl.dev/usingcurl/persist

curl 将始终尝试保持连接处于活动状态并尽可能重用现有连接。

因此,您不能直接使用这些工具来使用它。

正如 @pl-nowlan 在他们的回答中提到的,唯一的方法是在服务器端。

答案3

尝试添加 -H“连接:关闭”

使用 -v (详细模式)您应该看到差异。

答案4

您可以使用选项 --no-keepalive。更多信息请参阅 man curl

--no-keepalive 禁用 TCP 连接上的保持活动消息,因为 curl 默认启用它们。

请注意,这是记录的否定选项名称。因此,您可以使用 --keepalive 来强制执行 keepalive。

相关内容