之前我们已经基于ARSoft.Tools.Net简单实现了DNS解析模块的功能,但是当性能要求升高时,每一次爬取都要进行DNS请求,甚至很有可能一段时间内每次请求的都是相同的地址,频繁的DNS请求就会成为性能瓶颈,所以我们要通过缓存机制将DNS解析结果缓存下来,降低DNS解析操作,提升系统性能。 如此,我们基于之前封装的MemoryCacheHelper类对DnsResolver类进行改造:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 using System; using System.Collections.Generic;using System.Diagnostics;using System.Net;using ARSoft.Tools.Net;using ARSoft.Tools.Net.Dns;using Mem = Crawler.Common.MemoryCacheHelper;namespace Crawler.Protocol { public class DnsResolver { public TimeSpan TimeSpan { get ; set ; } public string Url { get ; set ; } public ARecord Record { get ; set ; } public string DnsServer { get ; set ; } public int TimeOut { get ; set ; } public ReturnCode ReturnCode { get ; set ; } public bool IsSuccess { get ; private set ; } public TimeSpan TimeToLive { get ; set ; } public DnsResolver (string url, string dnsServer = "223.5.5.5" , int timeOut = 10000 ) { Url = url; DnsServer = dnsServer; TimeOut = timeOut; IsSuccess = false ; if (Mem.Contains(url)) Fill(Mem.Get<DnsResolver>(url)); else Dig(); } private void Fill (DnsResolver resolver ) { TimeSpan = resolver.TimeSpan; Url = resolver.Url; Record = resolver.Record; DnsServer = resolver.DnsServer; TimeOut = resolver.TimeOut; ReturnCode = resolver.ReturnCode; IsSuccess = resolver.IsSuccess; } public void Dig () { var dnsClient = new DnsClient(IPAddress.Parse(DnsServer), TimeOut); var s = new Stopwatch(); s.Start(); var dnsMessage = dnsClient.Resolve(DomainName.Parse(Url)); s.Stop(); TimeSpan = s.Elapsed; if (dnsMessage == null || (dnsMessage.ReturnCode != ReturnCode.NoError && dnsMessage.ReturnCode != ReturnCode.NxDomain)) IsSuccess = false ; if (dnsMessage != null ) { if (dnsMessage.AnswerRecords.Count > 0 ) { Record = dnsMessage.AnswerRecords[0 ] as ARecord; if (Record != null ) { IsSuccess = true ; TimeToLive=new TimeSpan(0 ,0 ,Record.TimeToLive); Mem.Add(Url, this , TimeToLive); } } } if (dnsMessage != null ) ReturnCode = dnsMessage.ReturnCode; } } }
这样,每次做完DNS解析后,会根据域名的TTL将解析结果缓存下来,下次查询时可以直接调用缓存,提高系统性能。