From 4b807991e57d70bfffa3f1b070dd865e09f2ea99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Fri, 19 Nov 2021 11:53:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FastGithub.DomainResolve/DnsClient.cs | 6 +- FastGithub.DomainResolve/DomainPersistence.cs | 116 ++++++++++++++++++ FastGithub.DomainResolve/DomainResolver.cs | 97 ++------------- .../ServiceCollectionExtensions.cs | 3 +- 4 files changed, 128 insertions(+), 94 deletions(-) create mode 100644 FastGithub.DomainResolve/DomainPersistence.cs diff --git a/FastGithub.DomainResolve/DnsClient.cs b/FastGithub.DomainResolve/DnsClient.cs index 12da242..282e67f 100644 --- a/FastGithub.DomainResolve/DnsClient.cs +++ b/FastGithub.DomainResolve/DnsClient.cs @@ -128,13 +128,13 @@ namespace FastGithub.DomainResolve } catch (OperationCanceledException) { - this.logger.LogWarning($"dns://{dns}无法解析{endPoint.Host}:请求超时"); + this.logger.LogWarning($"{endPoint.Host}@{dns}:请求超时。"); return Array.Empty(); } catch (Exception ex) { - this.logger.LogWarning($"dns://{dns}无法解析{endPoint.Host}:{ex.Message}"); - return this.dnsCache.Set(key, Array.Empty(), this.maxTimeToLive); + this.logger.LogWarning($"{endPoint.Host}@{dns}:{ex.Message}"); + return Array.Empty(); } finally { diff --git a/FastGithub.DomainResolve/DomainPersistence.cs b/FastGithub.DomainResolve/DomainPersistence.cs new file mode 100644 index 0000000..1b58b57 --- /dev/null +++ b/FastGithub.DomainResolve/DomainPersistence.cs @@ -0,0 +1,116 @@ +using FastGithub.Configuration; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +namespace FastGithub.DomainResolve +{ + /// + /// 域名持久化 + /// + sealed class DomainPersistence + { + private static readonly string dataFile = "dnsendpoints.json"; + private static readonly SemaphoreSlim dataLocker = new(1, 1); + private static readonly JsonSerializerOptions jsonOptions = new() + { + WriteIndented = true, + PropertyNameCaseInsensitive = true, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + private readonly FastGithubConfig fastGithubConfig; + private readonly ILogger logger; + private record EndPointItem(string Host, int Port); + + + /// + /// 域名持久化 + /// + /// + /// + public DomainPersistence( + FastGithubConfig fastGithubConfig, + ILogger logger) + { + this.fastGithubConfig = fastGithubConfig; + this.logger = logger; + } + + + /// + /// 读取保存的节点 + /// + /// + public IList ReadDnsEndPoints() + { + if (File.Exists(dataFile) == false) + { + return Array.Empty(); + } + + try + { + dataLocker.Wait(); + + var utf8Json = File.ReadAllBytes(dataFile); + var endPointItems = JsonSerializer.Deserialize(utf8Json, jsonOptions); + if (endPointItems == null) + { + return Array.Empty(); + } + + var dnsEndPoints = new List(); + foreach (var item in endPointItems) + { + if (this.fastGithubConfig.IsMatch(item.Host) == true) + { + dnsEndPoints.Add(new DnsEndPoint(item.Host, item.Port)); + } + } + return dnsEndPoints; + } + catch (Exception ex) + { + this.logger.LogWarning(ex.Message, "读取dns记录异常"); + return Array.Empty(); + } + finally + { + dataLocker.Release(); + } + } + + /// + /// 保存节点到文件 + /// + /// + /// + /// + public async Task WriteDnsEndPointsAsync(IEnumerable dnsEndPoints, CancellationToken cancellationToken) + { + try + { + await dataLocker.WaitAsync(CancellationToken.None); + + var endPointItems = dnsEndPoints.Select(item => new EndPointItem(item.Host, item.Port)).ToArray(); + var utf8Json = JsonSerializer.SerializeToUtf8Bytes(endPointItems, jsonOptions); + await File.WriteAllBytesAsync(dataFile, utf8Json, cancellationToken); + } + catch (Exception ex) + { + this.logger.LogWarning(ex.Message, "保存dns记录异常"); + } + finally + { + dataLocker.Release(); + } + } + } +} diff --git a/FastGithub.DomainResolve/DomainResolver.cs b/FastGithub.DomainResolve/DomainResolver.cs index 89e3e03..20f9836 100644 --- a/FastGithub.DomainResolve/DomainResolver.cs +++ b/FastGithub.DomainResolve/DomainResolver.cs @@ -3,11 +3,9 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Net; using System.Runtime.CompilerServices; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -19,112 +17,32 @@ namespace FastGithub.DomainResolve sealed class DomainResolver : IDomainResolver { private readonly DnsClient dnsClient; - private readonly FastGithubConfig fastGithubConfig; + private readonly DomainPersistence persistence; private readonly ILogger logger; - private record EndPointItem(string Host, int Port); private readonly ConcurrentDictionary dnsEndPointAddressElapseds = new(); - private static readonly string dnsEndpointFile = "dnsendpoints.json"; - private static readonly SemaphoreSlim dnsEndpointLocker = new(1, 1); - private static readonly JsonSerializerOptions jsonOptions = new() - { - WriteIndented = true, - PropertyNameCaseInsensitive = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - }; - /// /// 域名解析器 /// /// - /// + /// /// public DomainResolver( DnsClient dnsClient, - FastGithubConfig fastGithubConfig, + DomainPersistence persistence, ILogger logger) { this.dnsClient = dnsClient; - this.fastGithubConfig = fastGithubConfig; + this.persistence = persistence; this.logger = logger; - foreach (var endPoint in this.ReadDnsEndPoints()) + foreach (var endPoint in persistence.ReadDnsEndPoints()) { this.dnsEndPointAddressElapseds.TryAdd(endPoint, IPAddressElapsedCollection.Empty); } } - /// - /// 读取保存的节点 - /// - /// - private IList ReadDnsEndPoints() - { - if (File.Exists(dnsEndpointFile) == false) - { - return Array.Empty(); - } - - try - { - dnsEndpointLocker.Wait(); - - var utf8Json = File.ReadAllBytes(dnsEndpointFile); - var endPointItems = JsonSerializer.Deserialize(utf8Json, jsonOptions); - if (endPointItems == null) - { - return Array.Empty(); - } - - var dnsEndPoints = new List(); - foreach (var item in endPointItems) - { - if (this.fastGithubConfig.IsMatch(item.Host) == true) - { - dnsEndPoints.Add(new DnsEndPoint(item.Host, item.Port)); - } - } - return dnsEndPoints; - } - catch (Exception ex) - { - this.logger.LogWarning(ex.Message, "读取dns记录异常"); - return Array.Empty(); - } - finally - { - dnsEndpointLocker.Release(); - } - } - - /// - /// 保存节点到文件 - /// - /// - /// - /// - private async Task WriteDnsEndPointsAsync(IEnumerable dnsEndPoints, CancellationToken cancellationToken) - { - try - { - await dnsEndpointLocker.WaitAsync(CancellationToken.None); - - var endPointItems = dnsEndPoints.Select(item => new EndPointItem(item.Host, item.Port)).ToArray(); - var utf8Json = JsonSerializer.SerializeToUtf8Bytes(endPointItems, jsonOptions); - await File.WriteAllBytesAsync(dnsEndpointFile, utf8Json, cancellationToken); - } - catch (Exception ex) - { - this.logger.LogWarning(ex.Message, "保存dns记录异常"); - } - finally - { - dnsEndpointLocker.Release(); - } - } - - /// /// 解析ip /// @@ -150,7 +68,6 @@ namespace FastGithub.DomainResolve { if (this.dnsEndPointAddressElapseds.TryGetValue(endPoint, out var addressElapseds) && addressElapseds.IsEmpty == false) { - this.logger.LogInformation($"{endPoint.Host}->{addressElapseds}"); foreach (var addressElapsed in addressElapseds) { yield return addressElapsed.Adddress; @@ -160,12 +77,11 @@ namespace FastGithub.DomainResolve { if (this.dnsEndPointAddressElapseds.TryAdd(endPoint, IPAddressElapsedCollection.Empty)) { - await this.WriteDnsEndPointsAsync(this.dnsEndPointAddressElapseds.Keys, cancellationToken); + await this.persistence.WriteDnsEndPointsAsync(this.dnsEndPointAddressElapseds.Keys, cancellationToken); } await foreach (var adddress in this.dnsClient.ResolveAsync(endPoint, fastSort: true, cancellationToken)) { - this.logger.LogInformation($"{endPoint.Host}->{adddress}"); yield return adddress; } } @@ -201,6 +117,7 @@ namespace FastGithub.DomainResolve addressElapseds = new IPAddressElapsedCollection(await Task.WhenAll(tasks)); } this.dnsEndPointAddressElapseds[dnsEndPoint] = addressElapseds; + this.logger.LogInformation($"{dnsEndPoint.Host}->{addressElapseds}"); } } } diff --git a/FastGithub.DomainResolve/ServiceCollectionExtensions.cs b/FastGithub.DomainResolve/ServiceCollectionExtensions.cs index e43006d..49341c6 100644 --- a/FastGithub.DomainResolve/ServiceCollectionExtensions.cs +++ b/FastGithub.DomainResolve/ServiceCollectionExtensions.cs @@ -17,7 +17,8 @@ namespace FastGithub public static IServiceCollection AddDomainResolve(this IServiceCollection services) { services.TryAddSingleton(); - services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); services.TryAddSingleton(); services.AddHostedService(); return services;