2014-06-22 30 views
3

鉴于在并行请求100个URL同时为10000个网址,我会收到以下错误他们50-5000应用程序(有时):无法解析DNS

远程名不能解决'www.url.com'

据我所知,该错误意味着DNS服务器无法解析的网址。但是,对于每次运行,无法解析的网址数量都会发生变化(从50到5000)。

我是否提出太多要求太快?我可以这样做吗? - 在功能更强大的服务器上运行相同的测试,表明只有10个网址无法解析 - 这听起来更实际。

,做并行请求代码:

var semp = new SemaphoreSlim(100); 
var uris = File.ReadAllLines(@"C:\urls.txt").Select(x => new Uri(x)); 

foreach(var uri in uris) 
{ 
    Task.Run(async() => 
    { 
     await semp.WaitAsync(); 
     var result = await Web.TryGetPage(uri); // Using HttpWebRequest 
     semp.Release(); 
    }); 
} 
+0

你能展示这个并行工作的最基本的代码吗? – Haney

+0

@DavidHaney,完成:-) – ebb

+0

似乎你可能只是用并发请求重载DNS服务器,或者类似地,你的Web实例/类是静态的(或者有静态成员),并且所有任务都共享连接会有奇怪的结果。 – Haney

回答

4

我敢打赌,你不知道的HttpWebRequest的DNS查找(这是所有.NET HTTP API的基石)发生同步, 甚至当做异步请求(烦人,对吧?)。这意味着立即触发许多请求会导致严重的ThreadPool压力和大量延迟。这可能会导致意外超时。如果你真的想要一步到位,不要使用.net dns实现。您可以使用third party library解析主机并使用ip而不是主机名创建webrequest,然后在发出请求之前手动设置主机头。你可以通过这种方式实现更高的吞吐量,这样可以达到很多

+0

从电话回答,所以一个代码示例是关闭卡atm。让我知道这是否没有意义,当我在真正的电脑前时,我会添加代码。 – spender

+0

完全有道理。这也可以解释为什么我必须“发明”一种机制,每隔10秒调整一次Web请求的超时时间,以便它们不超时。 'Dns.GetHostEntryAsync'不足以解决主机,或者这是否也是同步的? :-) – ebb

+1

同步。这很糟糕,这是我第一次注意到它后几年仍然存在的问题。 – spender

3

听起来好像你在淹没你的本地DNS服务器(用术语,你的本地递归DNS解析器)。

当您的程序发出DNS解析请求时,它会将端口53数据报发送到本地解析器。解析器通过回复缓存或递归地将请求重新发送给某个已被识别为可能具有您正在查找的记录的其他解析器来响应。

所以,你的多线程程序导致大量的数据报四处飞扬。 Internet协议主机和路由器通过丢弃数据报包来处理拥塞和过载。这就像在桥上铲车一样处理桥上的交通堵塞。在过载情况下,一些数据包会消失。

因此,如果端点软件使用数据报协议丢失数据包,则可以再次尝试。这就是TCP的目的,即便它只能与数据报进行通信,也可以提供无差错数据流的错觉。

因此,当您的某些DNS请求解析失败时,您的程序需要重试。你是一个数据报端点,所以你有责任重试。我怀疑当你的一些请求超时,因为你的数据报被删除,.net库会让你失败。

现在,这是重要的事情。与您一样,数据报端点程序也有责任实施拥塞控制。 TCP使用其滑动窗口系统自动执行此操作,并使用称为慢启动/指数回退的算法。如果TCP不这样做,所有的互联网路由器都会一直拥塞。 Van Jacobson曾经梦想过这个算法,你应该阅读它。

与此同时,您应该在您的批量DNS查找程序中实施一种简单的形式。以下是你如何做到这一点。

  1. 以批量大小,比如5查找开始。
  2. 每次成功完成整批回收时,请将您的批处理大小增加一个用于下一批处理。这是慢启动。只要你没有拥挤,就会增加网络负载。
  3. 每次遇到解析名称失败时,都会将下一批量的大小减半。因此,例如,如果批量大小为30,并且出现故障,则您的下一个批次大小将为15.这是指数回退。您可以通过大幅减少网络负载来应对拥塞。
  4. 实施类似100的最大批量大小只是为了避免过多的猪,并且看起来像是对DNS系统的粗暴拒绝服务攻击。

前段时间我有一个类似的项目,这个策略对我很好。

+0

Thansk为你的答案:-) - 有什么办法,我可以确保它实际上是导致问题的本地DNS服务器? – ebb

+0

另外,为什么具有更多CPU和内存容量的服务器能够一次执行更多查找,从而防止出现过载情况? – ebb