如何从命令行让 cURL 使用 keepalive?

Rob*_*ska 47 http netstat tcp keepalive curl

我正在尝试验证在与我正在运行的 Tomcat 网络服务器通信期间是否正在使用 HTTP 持久连接。目前,我可以从浏览器(例如 Chrome)检索服务器上的资源,并使用 netstat 验证连接已建立:

# visit http://server:8080/path/to/resource in Chrome
[server:/tmp]$ netstat -a
...
tcp        0      0 server.mydomain:webcache client.mydomain:55502 ESTABLISHED
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用 curl,则在 netstat 中看不到服务器上的连接。

[client:/tmp]$ curl --keepalive-time 60 --keepalive http://server:8080/path/to/resource
...

[server:/tmp]$ netstat -a
# no connection exists for client.mydomain
Run Code Online (Sandbox Code Playgroud)

我也尝试使用以下 curl 命令:

curl -H "Keep-Alive: 60" -H "Connection: keep-alive" http://server:8080/path/to/resource
Run Code Online (Sandbox Code Playgroud)

这是我的客户端机器的 curl 版本:

[server:/tmp]$ curl -V
curl 7.19.5 (x86_64-unknown-linux-gnu) libcurl/7.19.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5 libssh2/1.1
Protocols: tftp ftp telnet dict http file https ftps scp sftp
Features: IDN IPv6 Largefile NTLM SSL libz
Run Code Online (Sandbox Code Playgroud)

如何让 curl 使用持久/保持连接?我在这个主题上做了很多谷歌搜索,但没有成功。应该注意的是,我也在links客户端机器上使用过来检索资源,这确实为我提供ESTABLISHED了服务器上的连接。

如果我需要提供更多信息,请告诉我。

Ros*_*han 50

curl 已经默认使用 keepalive。

举个例子:

curl -v http://www.google.com http://www.google.com
Run Code Online (Sandbox Code Playgroud)

产生以下内容:

* About to connect() to www.google.com port 80 (#0)
*   Trying 74.125.39.99... connected
* Connected to www.google.com (74.125.39.99) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: www.google.com
> Accept: */*
> 
< HTTP/1.1 302 Found
< Location: http://www.google.ch/
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Set-Cookie: PREF=ID=0dd153a227433b2f:FF=0:TM=1289232886:LM=1289232886:S=VoXSLP8XWvjzNcFj; expires=Wed, 07-Nov-2012 16:14:46 GMT; path=/; domain=.google.com
< Set-Cookie: NID=40=sOJuv6mxhQgqXkVEOzBwpUFU3YLPQYf4HRcySE1veCBV5cPtP3OiLPKqvRxL10VLiFETGz7cu25pD_EoUq1f_CkNwOna-xRcFFsCokiFqIbGPrb6DmUO7XhcpMYOt3dB; expires=Tue, 10-May-2011 16:14:46 GMT; path=/; domain=.google.com; HttpOnly
< Date: Mon, 08 Nov 2010 16:14:46 GMT
< Server: gws
< Content-Length: 218
< X-XSS-Protection: 1; mode=block
< 
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.ch/">here</A>.
</BODY></HTML>
* Connection #0 to host www.google.com left intact
* Re-using existing connection! (#0) with host www.google.com
* Connected to www.google.com (74.125.39.99) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: www.google.com
> Accept: */*
> 
< HTTP/1.1 302 Found
< Location: http://www.google.ch/
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Set-Cookie: PREF=ID=8b531815cdfef717:FF=0:TM=1289232886:LM=1289232886:S=ifbAe1QBX915QGHr; expires=Wed, 07-Nov-2012 16:14:46 GMT; path=/; domain=.google.com
< Set-Cookie: NID=40=Rk86FyMCV3LzorQ1Ph8g1TV3f-h41NA-9fP6l7G-441pLEiciG9k8L4faOGC0VI6a8RafpukiDvaNvJqy8wExED9-Irzs7VdUQYwI8bCF2Kc2ivskb6KDRDkWzMxW_xG; expires=Tue, 10-May-2011 16:14:46 GMT; path=/; domain=.google.com; HttpOnly
< Date: Mon, 08 Nov 2010 16:14:46 GMT
< Server: gws
< Content-Length: 218
< X-XSS-Protection: 1; mode=block
< 
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.ch/">here</A>.
</BODY></HTML>
* Connection #0 to host www.google.com left intact
* Closing connection #0
Run Code Online (Sandbox Code Playgroud)

这个片段:

* 与主机 www.google.com 的连接 #0 保持不变
* 重新使用现有连接!(#0) 与主机 www.google.com

表示它重新使用了相同的连接。

curl -v http://my.server/url1 http://my.server/url2对您的服务器使用相同的 " " 调用并检查您是否看到相同的消息。

考虑使用 tcpdump 而不是 netstat 来查看数据包是如何处理的。netstat 只会让您暂时了解正在发生的事情,而使用 tcpdump 您会看到涉及的每个数据包。另一种选择是 Wireshark。

  • 如果您仅通过 curl 请求单个 URL,则 curl 没有理由让任何内容保持活动状态。一旦获取了所有 URL,curl 进程将终止。指定两个 URL(它甚至可以是两次相同的 URL)并留意“curl -v”产生的输出。到 netstat 运行时,连接已经关闭,因为 curl 不再运行,并且不再有保持连接打开的理由。 (10认同)
  • 这就说得通了; 如果拥有该连接的进程已经完成,那么保持该连接是没有意义的。感谢您的帮助。 (2认同)

AXE*_*abs 15

如果您的服务器允许“KeepAlive On”,您可以使用 telnet 来保持持久连接,如下所示:

$ while :;do echo -e "GET / HTTP/1.1\nhost: $YOUR_VIRTUAL_HOSTNAME\n\n";sleep 1;done|telnet $YOUR_SERVERS_IP 80
Run Code Online (Sandbox Code Playgroud)


小智 8

测试 HTTP 持久连接/Keep-Alive 的一种方法是查看 TCP 连接是否被重用于后续连接。

例如。我有一个包含多次重复的http://google.com链接的文件。

运行以下命令将使用相同的 TCP 连接多次打开http://google.com

curl -K /tmp/file
Run Code Online (Sandbox Code Playgroud)

并且在此期间,如果您使用 netstat,您会发现 TCP 连接没有变化,并且恢复了旧的连接(套接字保持不变)。

$ sudo netstat -pnt|grep curl
tcp        0      0 106.51.85.118:48682     74.125.236.69:80        ESTABLISHED 9732/curl       
$ sudo netstat -pnt|grep curl
tcp        0      0 106.51.85.118:48682     74.125.236.69:80        ESTABLISHED 9732/curl       
$ sudo netstat -pnt|grep curl
tcp        0      0 106.51.85.118:48682     74.125.236.69:80        ESTABLISHED 9732/curl   
Run Code Online (Sandbox Code Playgroud)

但是当我们要求客户端使用不支持持久性 HTTP 连接的 HTTP 1.0 时,套接字地址会发生变化

$ curl -0 -K /tmp/file

$ sudo netstat -pnt|grep curl
tcp        0      0 106.51.85.118:48817     74.125.236.69:80        ESTABLISHED 9765/curl       
$ sudo netstat -pnt|grep curl
tcp        0      0 106.51.85.118:48827     74.125.236.69:80        ESTABLISHED 9765/curl       
$ sudo netstat -pnt|grep curl
tcp        0     74 106.51.85.118:48838     74.125.236.69:80        ESTABLISHED 9765/curl       
Run Code Online (Sandbox Code Playgroud)

由此我们可以确定 TCP 连接是重用的。