如何在测试公共代理时可靠地重现curl_multi超时

问题描述 投票:8回答:2

相关信息:issue 3602 on GitHub

我正在开发一个收集和测试公共/免费代理的项目,并注意到当我使用curl_multi接口测试这些代理时,有时我会得到很多28(timeout)错误。如果我单独测试每个代理,这种情况从未发生

问题是这个问题不可靠地重现,而且并不总是出现,它可能是卷曲或其他东西。

不幸的是,我不是一个如此深入的网络调试器,我不知道如何在更深层次上调试这个问题,但是我写了2个C测试程序(其中一个最初是written by Daniel Stenberg,但我修改了一下)。这些2 C程序使用curl测试407个公共代理

  1. 与curl_multi接口(有问题)
  2. 在许多线程上使用curl,每个curl都在一个线程上运行。 (没问题)

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-threads从不这样做?

我下载了Wireshark并用它来捕获每个2 C程序运行时的流量,我也filtered流量到2 C程序使用的代理列表,并将files保存在GitHub上。

the curl-threads program (the expected behavior)

407个代理中有63个成功连接和158个连接超时。

the curl_multi program (the unexpected behavior)

407个代理中有0个成功连接和272个连接超时。

您可以使用Wireshark打开.pcapng文件,并查看我的计算机上记录的流量,同时预期/意外行为。我将流量过滤到407代理IP,并在30秒的卷曲限制后让Wireshark打开一段时间,因为我注意到一些数据包仍在显示。我不知道Wireshark和这种级别的网络,但我认为这可能有用。


关于带宽的注意事项:

在wireshark中打开curl_threads程序的.pcapng文件(正常行为),然后转到Statistics> Conversations。你会看到这样一个窗口

enter image description here

我复制了数据并将它们保存在GitHuB上here,现在计算从A-> B和B-> A发送的字节的Sum

正常工作所需的整个带宽约为692.8 KB。

php c curl bug-tracking curl-multi
2个回答
1
投票

对我来说,看起来你没有卷曲问题本身,但如果连接被拒绝,与代理服务器同时进行太多连接。您可能会被永久列入黑名单或持续一段时间。

检查是否通过从当前IP运行curl并执行stat:建立了多少连接,拒绝了多少次,多少次超时。做几次并收集平均值。将服务器更改为具有不同IP的其他服务器并检查您在那里拥有的统计信息。在第一次运行时,您应该有更好的统计数据,可能如果您在新IP上重复测试将变得更糟。好主意可能是不使用所有代理池来连接到做stat,但是从它们中选择一个切片并检查实际IP并重复检查新IP,所以如果你滥用服务的原因你不要将自己列入黑名单所有代理但仍然有下一组“未触动”的代理在新IP上测试它们,如果确实如此。请注意,即使代理的IP位于不同的位置,它们也可以属于同一个服务提供商。对于他们所有的代理服务器,可能有一个滥用列表,因此,如果您在一个国家/地区的请求数量不太好,即使在连接到其他国家/地区代理之前,您也可能在其他国家/地区被阻止。

如果您仍想检查这是否不是卷曲,那么您可以设置具有多个服务的测试环境。您可以将此测试环境传递给curl维护者,以便他可以复制错误。您可以使用docker并创建10,20或100个代理服务器并连接到它们以查看curl是否有问题。

你需要docker它可以安装在Win / Mac / Linux上 其中一个proxy image创建代理 为容器创建网络tutorial(桥应该没问题) 将容器附加到网络--network 很高兴为每个代理容器设置他们的--ip 通过mountig错误日志/配置文件/ direcotires与--volume,使每个代理容器可以读取配置并写入错误日志(这样你可以读取它们为什么会断开连接) 并且所有代理容器都应该运行

您可以通过两种方式连接到容器内部运行的代理。如果你想在这些容器外面卷曲,那么你需要用-p这些代理的端口从容器暴露到外面的世界(在你的情况下卷曲)。

要么

您可以使用另一个具有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的维护者可以复制这些内容。

只需将上述所有命令设置为创建所有代理,将它们连接到网络等文件中,例如replicate.sh脚本,以

#!/bin/sh

and your comands here

保存该文件然后发出命令

chmod +x ./replicate.sh

使其可执行。

你可以运行它来仔细检查一切是否按预期工作

./replicate.sh

并发送curl的维护者来复制你遇到问题的环境。

如果你不喜欢运行很多像docker run这样的命令来运行代理,你可以使用docker compose代替它,它允许你在一个文件中定义整个测试环境。

如果你运行很多容器,你可以限制资源,例如每个消耗的memory,如果有这么多代理,可以帮助你


1
投票

尝试在一个线程中没有400个打开的连接。或者就此而言甚至处理。您可能会超载代理,因此他们可能会将您列入黑名单(拒绝服务安全)。或者您的出站网络可能会限制打开的连接数。

© www.soinside.com 2019 - 2024. All rights reserved.