根据统计信息返回最优ip

This commit is contained in:
陈国伟 2021-06-16 16:57:12 +08:00
parent f89952dd18
commit 88d3e08ed3
6 changed files with 96 additions and 57 deletions

View File

@ -18,24 +18,19 @@ namespace FastGithub.Scanner
/// <summary>
/// 获取或设置是否可用
/// </summary>
public bool Available { get; set; } = false;
public bool Available { get; set; }
/// <summary>
/// 获取或设置扫描总耗时
/// 获取统计信息
/// </summary>
public TimeSpan Elapsed { get; set; } = TimeSpan.MaxValue;
public GithubContextStatistics Statistics { get; } = new();
public GithubContext(string domain, IPAddress address)
{
this.Domain = domain;
this.Address = address;
}
public override string ToString()
{
return $"{Address}\t{Domain}\t# {Elapsed}";
}
}
public override bool Equals(object? obj)
{

View File

@ -8,21 +8,12 @@ namespace FastGithub.Scanner
{
private readonly object syncRoot = new();
private readonly HashSet<GithubContext> contextHashSet = new();
private readonly Dictionary<string, IPAddress> domainAdressCache = new();
public void AddOrUpdate(GithubContext context)
public bool Add(GithubContext context)
{
lock (this.syncRoot)
{
if (this.contextHashSet.TryGetValue(context, out var value))
{
value.Elapsed = context.Elapsed;
value.Available = context.Available;
}
else
{
this.contextHashSet.Add(context);
}
return this.contextHashSet.Add(context);
}
}
@ -39,35 +30,16 @@ namespace FastGithub.Scanner
/// </summary>
/// <param name="domain"></param>
/// <returns></returns>
public IPAddress? FindFastAddress(string domain)
public IPAddress? FindBestAddress(string domain)
{
lock (this.syncRoot)
{
// 如果上一次的ip可以使用就返回上一次的ip
if (this.domainAdressCache.TryGetValue(domain, out var address))
{
var key = new GithubContext(domain, address);
if (this.contextHashSet.TryGetValue(key, out var context) && context.Available)
{
return address;
}
}
var fastAddress = this.contextHashSet
return this.contextHashSet
.Where(item => item.Available && item.Domain == domain)
.OrderBy(item => item.Elapsed)
.OrderByDescending(item => item.Statistics.GetSuccessRate())
.ThenBy(item => item.Statistics.GetAvgElapsed())
.Select(item => item.Address)
.FirstOrDefault();
if (fastAddress != null)
{
this.domainAdressCache[domain] = fastAddress;
}
else
{
this.domainAdressCache.Remove(domain);
}
return fastAddress;
}
}
}

View File

@ -0,0 +1,57 @@
using System;
namespace FastGithub.Scanner
{
sealed class GithubContextStatistics
{
/// <summary>
/// 扫描总次数
/// </summary>
public int TotalScanCount { get; private set; }
/// <summary>
/// 扫描总成功次数
/// </summary>
public int TotalSuccessCount { get; private set; }
/// <summary>
/// 扫描总耗时
/// </summary>
public TimeSpan TotalSuccessElapsed { get; private set; }
public void SetScan()
{
this.TotalScanCount += 1;
}
public void SetScanSuccess(TimeSpan elapsed)
{
this.TotalSuccessCount += 1;
this.TotalSuccessElapsed = this.TotalSuccessElapsed.Add(elapsed);
}
/// <summary>
/// 获取成功率
/// </summary>
/// <returns></returns>
public double GetSuccessRate()
{
return this.TotalScanCount > 0 ?
(double)this.TotalSuccessCount / this.TotalScanCount
: 0d;
}
/// <summary>
/// 获取平均耗时
/// </summary>
/// <returns></returns>
public TimeSpan GetAvgElapsed()
{
return this.TotalScanCount > 0
? this.TotalSuccessElapsed / this.TotalScanCount
: TimeSpan.MaxValue;
}
}
}

View File

@ -30,18 +30,18 @@ namespace FastGithub.Scanner
this.fullScanDelegate = pipelineBuilder
.New()
.Use<ConcurrentMiddleware>()
.Use<ScanElapsedMiddleware>()
.Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>()
.Use<ScanOkLogMiddleware>()
.Use<StatisticsMiddleware>()
.Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>()
.Build();
this.resultScanDelegate = pipelineBuilder
.New()
.Use<ScanElapsedMiddleware>()
.Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>()
.Use<ScanOkLogMiddleware>()
.Use<StatisticsMiddleware>()
.Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>()
.Build();
}
@ -62,7 +62,7 @@ namespace FastGithub.Scanner
await this.fullScanDelegate(context);
if (context.Available == true)
{
this.results.AddOrUpdate(context);
this.results.Add(context);
}
}
}
@ -83,7 +83,7 @@ namespace FastGithub.Scanner
public IPAddress? FindFastAddress(string domain)
{
return domain.Contains("github", StringComparison.OrdinalIgnoreCase)
? this.results.FindFastAddress(domain)
? this.results.FindBestAddress(domain)
: default;
}
}

View File

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Net;
using System.Threading.Tasks;
namespace FastGithub.Scanner.Middlewares
@ -10,19 +11,29 @@ namespace FastGithub.Scanner.Middlewares
{
private readonly ILogger<ScanOkLogMiddleware> logger;
private record ScanOk(string Domain, IPAddress Address, int TotalScanCount, double SuccessRate, TimeSpan AvgElapsed);
public ScanOkLogMiddleware(ILogger<ScanOkLogMiddleware> logger)
{
this.logger = logger;
}
public Task InvokeAsync(GithubContext context, Func<Task> next)
public async Task InvokeAsync(GithubContext context, Func<Task> next)
{
await next();
if (context.Available)
{
this.logger.LogInformation(context.ToString());
}
var mesage = new ScanOk(
context.Domain,
context.Address,
context.Statistics.TotalScanCount,
context.Statistics.GetSuccessRate(),
context.Statistics.GetAvgElapsed()
);
return next();
this.logger.LogInformation(mesage.ToString());
}
}
}
}

View File

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace FastGithub.Scanner.Middlewares
{
[Service(ServiceLifetime.Singleton)]
sealed class ScanElapsedMiddleware : IMiddleware<GithubContext>
sealed class StatisticsMiddleware : IMiddleware<GithubContext>
{
public async Task InvokeAsync(GithubContext context, Func<Task> next)
{
@ -14,12 +14,16 @@ namespace FastGithub.Scanner.Middlewares
try
{
stopwatch.Start();
context.Statistics.SetScan();
await next();
}
finally
{
stopwatch.Stop();
context.Elapsed = stopwatch.Elapsed;
if (context.Available == true)
{
context.Statistics.SetScanSuccess(stopwatch.Elapsed);
}
}
}
}