首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在测试公共代理时可靠地再现curl_multi超时

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

Stack Overflow用户
提问于 2019-02-22 12:40:19
回答 2查看 1K关注 0票数 10

相关信息:第3602期关于GitHub

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

问题是,这个问题是不可靠的重复性,它并不总是出现,它可能是什么卷曲或其他东西。

不幸的是,我不是一个深度网络调试器,我不知道如何在更深的层次上调试这个问题,但是我编写了2C测试程序(其中一个最初是丹尼尔·斯坦伯格( Daniel Stenberg ),但我将它的输出修改为与另一个C程序相同的格式)。这些2C程序使用curl测试407个公共代理。

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

这些是我为测试而编写的2C程序。,我不是C开发人员,所以请让我知道你在这两个程序中注意到的任何错误。

这是我一个月前用来复制这个问题的原始PHP类

这些是2C程序的测试结果。。您可以注意到使用curl_multi超时完成的测试,而由curl线程执行的超时是稳定的( 407个代理中大约有50个在工作)。

这是测试结果中的一个样本。请注意第4栏和第5栏,看看卷曲线程如何超时约170次,并成功连接~40次。其中,curl_multi在407个代理中进行了0次成功的连接和超时--300次。

代码语言:javascript
复制
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并使用它来捕获每个2C程序运行时的流量,我还将流量已过滤到2C程序使用的代理列表,并将文件保存在GitHub上。

curl线程程序(预期的行为)

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

curl_multi程序( _un_expected行为)

407个代理的成功连接和272个连接超时。

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

关于带宽的注:

在wireshark中打开curl_threads程序的curl_threads文件(正常行为),然后转到统计>会话。你会看到像这样的窗户

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

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

EN

回答 2

Stack Overflow用户

发布于 2019-03-31 14:18:53

我得到了可重复的行为,我在等待獾在GitHub上答复。尝试运行像Ettercap这样的程序来获得更多的信息。

票数 2
EN

Stack Overflow用户

发布于 2019-03-30 01:56:55

在我看来,您对curl本身没有问题,但是如果拒绝连接,则会同时与代理服务器进行过多的连接。你可能会被永久列入黑名单,或者被列入黑名单一段时间。

通过从当前IP和do运行您的curl来检查这一点:建立了多少连接,有多少拒绝,有多少超时。做几次然后收集一个平均值。然后将服务器更改为具有不同IP的其他服务器,并检查您在那里的状态。在第一次运行时,您应该有更好的统计数据,如果您在新IP上重复测试,可能只会变得更糟。好主意可能是不要使用代理的所有池连接做stat,而是从它们中选择一个片段,检查实际IP并重复检查新IP,因此如果您滥用服务,那么您不会在所有代理中列入黑名单,而是仍然有下一组“未触及”代理在新IP上测试,如果真的是这样的话。请注意,即使代理的IP位于不同的位置,它们也可以属于同一服务提供商。这可能有一个滥用名单为他们的所有代理服务,因此,如果你不清楚你在一个国家做的请求数量,你也可以在另一个国家,甚至在你连接到另一个国家的代理之前被封锁。

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

您需要docker,它可以安装在Win/Mac/Linux上。

创建代理的代理图像之一

为容器创建网络教程 (桥应该可以)

将容器附加到网络--网络

很好地为每个代理容器设置它们的-知识产权

通过挂载错误日志/配置文件/ -数量,使每个代理容器能够读取配置和写入错误日志(如果发生这种情况,您可以读取它们断开连接的原因)

所有代理容器都应该运行

您可以以两种方式连接到在容器中运行的代理。如果您希望在这些容器之外有卷曲,那么您需要使用-p公开这些代理从容器到外部世界的端口(在您的例子中是curl )。

您可以使用另一个具有linux + curl的容器映像。例如,阿尔卑斯linux + curl并以与代理相同的方式连接它。如果这样做,您不需要发布(公开)代理端口,也不需要考虑应该为这个特定代理公开多少个代理端口。

在每一步,您都可以发出一个命令

代码语言:javascript
复制
docker ps -a

查看所有容器及其状态。

停止并删除所有容器(不是来自它们的映像,而是正在运行的容器),以防容器退出时出现错误。

代码语言:javascript
复制
docker stop $(docker ps -aq) && docker rm $(docker ps -aq)

或者停止并从列表中删除特定的容器。

代码语言:javascript
复制
docker stop <container-id>
docker rm <container-id>

查看连接到桥接网络的所有容器(默认)

代码语言:javascript
复制
docker network inspect bridge

如果您确认与本地机器上的代理连接确实有问题,那么这就是curl的维护者可以复制的东西。

只需将上述所有命令放在一个文件中,以创建所有代理,将它们连接到网络等,例如,以replicate.sh脚本开头

代码语言:javascript
复制
#!/bin/sh

and your comands here

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

代码语言:javascript
复制
chmod +x ./replicate.sh

让它可执行。

您可以运行它,以反复检查是否一切正常运行。

代码语言:javascript
复制
./replicate.sh

并让curl的维护者复制您曾经遇到过问题的环境。

如果您不喜欢为代理运行许多命令,比如doker运行,那么您可以使用码头组成来在一个文件中定义整个测试环境。

如果您运行了很多容器,您可以限制资源(例如,每个容器所消耗的内存 ),在出现如此多的代理时,可能会对您有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54827396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档