编程语言
首页 > 编程语言> > php-如何在测试公共代理服务器时可靠地重现curl_multi超时

php-如何在测试公共代理服务器时可靠地重现curl_multi超时

作者:互联网

相关信息:issue 3602 on GitHub

我正在从事一个收集和测试公共/免费代理的项目,并注意到当我使用curl_multi接口测试这些代理时,有时会遇到很多28(超时)错误.如果我仅测试每个代理,就永远不会发生这种情况.

问题在于此问题是无法可靠地重现的,并且并不总是显示出来,可能是卷曲的东西或其他东西.

不幸的是,我不是一个如此深的网络调试器,我也不知道如何在更深层次上调试此问题,但是我编写了2个C测试程序(其中一个最初是written by Daniel Stenberg,但我对其进行了一些修改).这2个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线程进行的超时是稳定的(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上.

curl-threads程序(预期行为)

在407个代理中,有63个成功的连接和158个连接超时.

>这是程序output.
>这是Wireshark .pcapng raw file.

curl_multi程序(意外行为)

0个成功连接和407个代理中的272个连接超时.

>这是程序output.
>这是Wireshark .pcapng raw file.

您可以使用Wireshark打开.pcapng文件,并在我的计算机上看到记录的流量,同时出现两种预期/意外的行为.我过滤了到407个代理IP的流量,并在30秒的卷曲限制后将Wireshark保持打开状态一会儿,因为我注意到某些数据包仍在显示.我不知道Wireshark和这种级别的网络连接,但是我认为这可能很有用.

注意带宽:

在wireshark中打开curl_threads程序的.pcapng文件(正常行为),然后转到“统计信息”>“>”.对话.您会看到一个这样的窗口

enter image description here

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

The ENTIRE bandwidth needed to work normally is about 692.8 KB.

解决方法:

对我来说,您似乎对curl本身没有问题,但是如果拒绝连接,则可以同时与代理服务器建立太多连接.您可能会被永久列入黑名单或一段时间.

通过从当前IP运行curl并检查状态来进行检查:建立了多少个连接,拒绝了多少个,超时了多少个.重复几次并收集平均值.然后将服务器更改为其他具有不同IP的服务器,并检查那里的统计信息.第一次运行时,您应该有更好的统计信息,如果您在新IP上重复测试,可能只会变得更糟.
好的主意可能是不使用代理的所有池来进行统计,而是从它们中选择一个片段并检查实际IP并在新IP上重复该检查,因此,如果原因是您滥用服务,则不要将自己列入黑名单所有代理,但如果确实如此,仍需要下一组“未修改”的代理在新IP上对其进行测试.
请注意,即使代理的IP位于不同的位置,它们也可以属于同一服务提供商.该代理的所有代理服务可能都有一个滥用列表,因此,如果您对在一个国家/地区进行的请求数量不满意,甚至在连接到另一个国家/地区代理之前,也可能在另一个国家/地区遭到屏蔽.

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

你会需要
docker可以安装在Win / Mac / Linux上
创建代理的proxy image之一
为容器创建网络tutorial(桥接应该可以)
将容器连接到网络–network
可以为每个代理容器设置其–ip
通过–volume的mountig错误日志/配置文件/镜像,使每个代理容器都可以读取配置和写入错误日志(因此您可以阅读为什么它们断开连接的原因)
并且所有代理容器都应该运行

您可以通过两种方式连接到在容器内运行的代理.
如果您希望在这些容器外面卷曲,则需要使用-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的维护者进行复制.

只需将上述所有命令创建所有代理,即可将它们连接到网络等文件中,例如,以

#!/bin/sh

and your comands here

保存该文件并发出然后命令

chmod +x ./replicate.sh

使它可执行.

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

./replicate.sh

并将curl的维护者发送到您遇到问题的环境.

如果您不想放置很多命令(如doker run)来运行代理,则可以使用docker compose代替,它允许您在一个文件中定义整个测试环境.

如果您运行大量容器,则可以限制资源,例如每个容器消耗的资源memory,可能在代理过多的情况下为您提供帮助

标签:c-3,php,curl,bug-tracking,curl-multi
来源: https://codeday.me/bug/20191010/1887805.html