如何通过命令行使cURL使用keepalive?


36

我正在尝试验证与正在运行的Tomcat Web服务器通信期间是否正在使用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

但是,如果使用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

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

curl -H "Keep-Alive: 60" -H "Connection: keep-alive" http://server:8080/path/to/resource

这是我的客户端计算机的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

如何获取curl以使用持久/ keepalive连接?我在这个问题上做了很多谷歌搜索,但是没有成功。应当指出,我还在links客户端计算机上使用过来检索资源,这确实使我ESTABLISHED在服务器上建立了连接。

让我知道是否需要提供更多信息。


Answers:


38

curl默认已经使用keepalive了。

举个例子:

curl -v http://www.google.com http://www.google.com

产生以下内容:

* 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

此代码段:

*托管www.google.com的#0连接保持不变
*重用现有连接!(#0)与主持人www.google.com

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

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

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


感谢您的回答。是的,我逐渐了解到,大多数HTTP客户端默认都使用keepalive。我想我要找出的原因就是为什么我只有在使用curl 时才看不到ESTABLISHED服务器上的连接。
罗布·赫鲁斯卡

7
如果您仅通过curl请求单个URL,则没有必要使用curl使任何内容保持活动。一旦获取了所有URL,卷曲过程就会终止。指定两个URL(甚至可能是同一URL两次),并注意“ curl -v”产生的输出。到netstat运行时,连接已经关闭,因为curl不再运行,并且不再需要保持连接打开的原因。
Roshan

1
那讲得通; 如果拥有该连接的进程完成,则保持连接无聊是没有意义的。谢谢你的帮助。
罗布·赫鲁斯卡

8

如果您的服务器允许“ 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

美丽。打圈时保持卷曲。
Michael Ozeryansky '16

我试图测试我的KeepAliveTimout更改是否已正确应用-这只是故障单。谢谢!
Dave Gregory

6

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

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

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

curl -K /tmp/file

在这段时间内,如果您使用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   

但是,当我们要求客户端使用不支持持久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       

由此可以确保TCP连接被重用。


5

--keepalive-time

男人卷曲...男人..:D


2
我已经阅读了手册页,谢谢。您是否--keepalive-time 60在我的示例中没有注意到?
罗布·赫鲁斯卡

3
哦...我现在觉得很蠢:(
Arenstar

8
如上所述建议的指定“ keepalive-time”不会影响HTTP级别的保持活动状态;它会影响底层TCP连接。在手册页(curl.haxx.se/docs/manpage.html)中:“此选项设置连接在发送keepalive探针之前需要保持空闲的时间以及各个keepalive探针之间的时间。” 我想很高兴有这么多种保持
活力
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.