根据统计信息返回最优ip
This commit is contained in:
parent
f89952dd18
commit
88d3e08ed3
@ -18,12 +18,12 @@ namespace FastGithub.Scanner
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置是否可用
|
/// 获取或设置是否可用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Available { get; set; } = false;
|
public bool Available { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置扫描总耗时
|
/// 获取统计信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TimeSpan Elapsed { get; set; } = TimeSpan.MaxValue;
|
public GithubContextStatistics Statistics { get; } = new();
|
||||||
|
|
||||||
|
|
||||||
public GithubContext(string domain, IPAddress address)
|
public GithubContext(string domain, IPAddress address)
|
||||||
@ -32,11 +32,6 @@ namespace FastGithub.Scanner
|
|||||||
this.Address = address;
|
this.Address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{Address}\t{Domain}\t# {Elapsed}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
return obj is GithubContext other && this.Equals(other);
|
return obj is GithubContext other && this.Equals(other);
|
||||||
|
|||||||
@ -8,21 +8,12 @@ namespace FastGithub.Scanner
|
|||||||
{
|
{
|
||||||
private readonly object syncRoot = new();
|
private readonly object syncRoot = new();
|
||||||
private readonly HashSet<GithubContext> contextHashSet = 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)
|
lock (this.syncRoot)
|
||||||
{
|
{
|
||||||
if (this.contextHashSet.TryGetValue(context, out var value))
|
return this.contextHashSet.Add(context);
|
||||||
{
|
|
||||||
value.Elapsed = context.Elapsed;
|
|
||||||
value.Available = context.Available;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.contextHashSet.Add(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,35 +30,16 @@ namespace FastGithub.Scanner
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="domain"></param>
|
/// <param name="domain"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IPAddress? FindFastAddress(string domain)
|
public IPAddress? FindBestAddress(string domain)
|
||||||
{
|
{
|
||||||
lock (this.syncRoot)
|
lock (this.syncRoot)
|
||||||
{
|
{
|
||||||
// 如果上一次的ip可以使用,就返回上一次的ip
|
return this.contextHashSet
|
||||||
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
|
|
||||||
.Where(item => item.Available && item.Domain == domain)
|
.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)
|
.Select(item => item.Address)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
if (fastAddress != null)
|
|
||||||
{
|
|
||||||
this.domainAdressCache[domain] = fastAddress;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.domainAdressCache.Remove(domain);
|
|
||||||
}
|
|
||||||
return fastAddress;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
57
FastGithub.Scanner/GithubContextStatistics.cs
Normal file
57
FastGithub.Scanner/GithubContextStatistics.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,18 +30,18 @@ namespace FastGithub.Scanner
|
|||||||
this.fullScanDelegate = pipelineBuilder
|
this.fullScanDelegate = pipelineBuilder
|
||||||
.New()
|
.New()
|
||||||
.Use<ConcurrentMiddleware>()
|
.Use<ConcurrentMiddleware>()
|
||||||
.Use<ScanElapsedMiddleware>()
|
.Use<ScanOkLogMiddleware>()
|
||||||
|
.Use<StatisticsMiddleware>()
|
||||||
.Use<PortScanMiddleware>()
|
.Use<PortScanMiddleware>()
|
||||||
.Use<HttpsScanMiddleware>()
|
.Use<HttpsScanMiddleware>()
|
||||||
.Use<ScanOkLogMiddleware>()
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.resultScanDelegate = pipelineBuilder
|
this.resultScanDelegate = pipelineBuilder
|
||||||
.New()
|
.New()
|
||||||
.Use<ScanElapsedMiddleware>()
|
.Use<ScanOkLogMiddleware>()
|
||||||
|
.Use<StatisticsMiddleware>()
|
||||||
.Use<PortScanMiddleware>()
|
.Use<PortScanMiddleware>()
|
||||||
.Use<HttpsScanMiddleware>()
|
.Use<HttpsScanMiddleware>()
|
||||||
.Use<ScanOkLogMiddleware>()
|
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ namespace FastGithub.Scanner
|
|||||||
await this.fullScanDelegate(context);
|
await this.fullScanDelegate(context);
|
||||||
if (context.Available == true)
|
if (context.Available == true)
|
||||||
{
|
{
|
||||||
this.results.AddOrUpdate(context);
|
this.results.Add(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ namespace FastGithub.Scanner
|
|||||||
public IPAddress? FindFastAddress(string domain)
|
public IPAddress? FindFastAddress(string domain)
|
||||||
{
|
{
|
||||||
return domain.Contains("github", StringComparison.OrdinalIgnoreCase)
|
return domain.Contains("github", StringComparison.OrdinalIgnoreCase)
|
||||||
? this.results.FindFastAddress(domain)
|
? this.results.FindBestAddress(domain)
|
||||||
: default;
|
: default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FastGithub.Scanner.Middlewares
|
namespace FastGithub.Scanner.Middlewares
|
||||||
@ -10,19 +11,29 @@ namespace FastGithub.Scanner.Middlewares
|
|||||||
{
|
{
|
||||||
private readonly ILogger<ScanOkLogMiddleware> logger;
|
private readonly ILogger<ScanOkLogMiddleware> logger;
|
||||||
|
|
||||||
|
private record ScanOk(string Domain, IPAddress Address, int TotalScanCount, double SuccessRate, TimeSpan AvgElapsed);
|
||||||
|
|
||||||
public ScanOkLogMiddleware(ILogger<ScanOkLogMiddleware> logger)
|
public ScanOkLogMiddleware(ILogger<ScanOkLogMiddleware> logger)
|
||||||
{
|
{
|
||||||
this.logger = 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)
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||||||
namespace FastGithub.Scanner.Middlewares
|
namespace FastGithub.Scanner.Middlewares
|
||||||
{
|
{
|
||||||
[Service(ServiceLifetime.Singleton)]
|
[Service(ServiceLifetime.Singleton)]
|
||||||
sealed class ScanElapsedMiddleware : IMiddleware<GithubContext>
|
sealed class StatisticsMiddleware : IMiddleware<GithubContext>
|
||||||
{
|
{
|
||||||
public async Task InvokeAsync(GithubContext context, Func<Task> next)
|
public async Task InvokeAsync(GithubContext context, Func<Task> next)
|
||||||
{
|
{
|
||||||
@ -14,12 +14,16 @@ namespace FastGithub.Scanner.Middlewares
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
|
context.Statistics.SetScan();
|
||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
context.Elapsed = stopwatch.Elapsed;
|
if (context.Available == true)
|
||||||
|
{
|
||||||
|
context.Statistics.SetScanSuccess(stopwatch.Elapsed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user