相关信息:issue 3602 on GitHub
我正在从事一个收集和测试公共/免费代理的项目,并注意到当我使用curl_multi接口测试这些代理时,有时会遇到许多28(timeout)
错误。如果我仅测试每个代理,就永远不会发生这种情况。
问题在于此问题的再现性不可靠,并且不会总是出现,可能是卷曲的东西或其他东西。
不幸的是,我不是一个如此深入的网络调试器,我也不知道如何在更深层次上调试此问题,但是我编写了2个C测试程序(其中一个最初是written by Daniel Stenberg,但我修改了一下)。这两个C程序使用curl测试了407个公共代理
具有curl_multi接口(有问题)
在许多线程上都有卷曲,每个卷曲都在一个线程上运行。 (没有问题)
These are the 2 C programs I wrote for testing我不是C开发人员,所以请让我知道您在2个程序中发现的任何错误。
这是一个月前我用来重现此问题的original PHP class。
还有these are the 2 C programs tests results。您会注意到,使用curl_multi超时进行的测试,而由curl-threads进行的超时是稳定的(407个代理中的大约50个正在工作)。
这是测试结果的样本。 请注意第4列和第5列,以了解卷发线程如何超时约170次并成功连接约40次。其中,curl_multi在407个代理中建立了0个成功的连接,并且超时约300次。
column(1) : #
column(2) : time(UTC)
column(3) : total execution time (seconds)
column(4) : no error 0 (how many requests result in no error CURLE_OK)
column(5) : error 28 (how many requests result in error 28 CURLE_OPERATION_TIMEDOUT)
column(6) : error 7 (how many requests result in error 7 CURLE_COULDNT_CONNECT)
column(7) : error 35 (how many requests result in error 35 CURLE_SSL_CONNECT_ERROR)
column(8) : error 56 (how many requests result in error 56 CURLE_RECV_ERROR)
column(9) : other errors (how many requests result in errors other than the above)
column(10) : program that used the curl
column(11) : cURL version
c(1) c(2) c(3)c(4)c(5)c(6)c(7)c(8)c(9) c(10) c(11)
267 2019-3-28 01:58:01 40 43 176 183 1 4 0 C (curl - threads) (Linux Fedora) 7.59.0
268 2019-3-28 01:59:01 30 0 286 110 1 10 0 C (curl-multi one thread) (Linux Fedora) 7.59.0
269 2019-3-28 02:00:01 30 46 169 181 1 8 2 C (curl - threads) (Linux Fedora) 7.59.0
270 2019-3-28 02:01:01 31 0 331 74 1 1 0 C (curl-multi one thread) (Linux Fedora) 7.59.0
271 2019-3-28 02:02:01 30 42 173 186 1 4 1 C (curl - threads) (Linux Fedora) 7.59.0
272 2019-3-28 02:03:01 30 0 277 116 1 13 0 C (curl-multi one thread) (Linux Fedora) 7.59.0
为什么curl_multi超时与大多数连接不一致,而curl线程却从来没有这样做?
我下载了Wireshark,并在运行2个C程序时用它捕获流量,我也filtered将该流量files到2 C程序使用的代理列表,并保存了{{3} }。
在407个代理中有63个成功的连接和158个连接超时。
0个成功连接和272个连接超时。
您可以使用Wireshark打开.pcapng
文件,并在我的计算机上看到记录的流量,同时出现两种预期/意外的行为。我过滤了到407个代理IP的流量,并在30秒的卷曲限制后将Wireshark保持打开状态一会儿,因为我注意到某些数据包仍在显示。我不知道Wireshark和这种级别的网络,但是我认为这可能很有用。
有关带宽的说明:
在wireshark中打开curl_threads程序的.pcapng
文件(正常行为),然后转到“统计信息”>“对话”。您会看到这样的窗口
我已经复制了数据并将它们here保存在GitHuB上,现在计算从A-> B和B-> A发送的字节的Sum
。
正常工作所需的整个带宽约为692.8 KB。
答案 0 :(得分:1)
对我来说,您似乎对curl本身没有问题,但是如果拒绝连接,则可以同时与代理服务器建立太多连接。您可能会被永久列入黑名单或一段时间。
通过从当前IP运行curl并检查状态,以检查是否建立了多少连接,拒绝了多少连接,超时了多少。重复几次并收集平均值。然后将服务器更改为其他具有不同IP的服务器,并检查那里的统计信息。第一次运行时,您应该有更好的统计信息,如果您在新IP上重复测试,可能只会变得更糟。 好的主意可能是不使用代理的所有池来进行统计,而是从它们中选择一个片段并检查实际IP并在新IP上重复该检查,因此,如果原因是您滥用服务,则不要将自己列入黑名单所有代理,但如果确实如此,仍需要下一组“未修改”的代理在新IP上对其进行测试。 请注意,即使代理的IP位于不同的位置,它们也可以属于同一服务提供商。该代理的所有代理服务可能都有一个滥用列表,因此,如果您对在一个国家/地区进行的请求数量不满意,甚至在连接到另一个国家/地区代理之前,您也可能会在另一个国家/地区遭到屏蔽。 / p>
如果您仍然想检查它是否不卷曲,则可以设置一个多份的测试环境。您可以将这个测试环境传递给curl维护人员,以便他可以复制错误。 您可以使用docker创建10、20或100个代理服务器并连接到它们,以查看curl是否有问题。
您将需要
docker它可以安装在Win / Mac / Linux
proxy image之一以创建代理
为容器创建网络tutorial(桥接应该可以)
将容器连接到网络--network
可以为每个代理容器设置其--ip
通过使用--volume
的mountig错误日志/配置文件/子目录,使每个代理容器都可以读取配置和写入错误日志(因此您可以阅读为什么它们断开连接的原因)
并且所有代理容器都应为runnig
您可以通过两种方式连接到在容器内运行的代理。 如果您希望在这些容器外部卷曲,则需要使用-p将这些代理的端口从容器暴露到外界(在您的情况下为curl)。
或
您可以使用另一个具有linux + curl的容器映像。例如,Alpine linux + curl并以与代理相同的方式将其连接到同一网络。如果这样做,则无需发布(公开)代理服务器的端口,也不必考虑应该为该特定代理服务器公开多少个代理服务器端口。
在每个步骤中您都可以发出命令
docker ps -a
查看所有容器及其状态。
停止并删除所有容器(不是来自它们的图像,而是正在运行的容器),以防容器中有些错误而退出。
docker stop $(docker ps -aq) && docker rm $(docker ps -aq)
或停止并从列表中删除特定容器
docker stop <container-id>
docker rm <container-id>
查看连接到网桥网络的所有容器(默认)
docker network inspect bridge
如果您确认与本地计算机上的代理服务器连接确实存在问题,则可以使curl的维护者进行复制。
只需将上述所有命令创建所有代理,即可将它们连接到网络等文件,例如以{p>开头的replicate.sh
脚本
#!/bin/sh
and your comands here
保存该文件,然后发出命令
chmod +x ./replicate.sh
使其可执行。
您可以运行它来仔细检查一切是否按预期进行
./replicate.sh
并将curl的维护者发送到您遇到问题的环境。
如果您不想放置诸如doker run之类的许多命令来运行代理,则可以使用docker compose来代替,它可以在一个文件中定义整个测试环境。
如果您运行大量容器,则可以限制资源,例如memory每个容器消耗的资源,可能在代理太多的情况下为您提供帮助
答案 1 :(得分:1)
尝试不在一个线程中具有400个开放连接。甚至处理,就此而言。您可能会超负荷使用代理,因此它们可能会将您列入黑名单(拒绝服务安全)。否则您的出站网络可能会限制打开的连接数。