开源FastGithub
0 前言
github網站訪問慢或訪問不了,相信很多人都會遇到過,解決方式大概有兩種:一種是使用代理訪問;另一種是使用ipaddress.com等域名解析網站查詢域名的ip,然后在host文件增加ip與域名的映射。
1 代理訪問
代理訪問是在一臺能上github的服務器開通代理服務,然后你所在機器在訪問github時,流量由代理服務器轉發,穩定的代理服務,一般都是收費用。
2 域名解析網站
例如使用ipaddress.com查詢域名的ip,但你的網絡可能還是無法正常的訪問這個ip,或者無法連接此ip的443端口。所以如果你在網上搜索"github慢",得到別人貼出的"最新github ip"數據,粘貼到你的host文件,你可能還是無法訪問github。
3 FastGithub
github定制版的dns服務,解析訪問github最快的ip
3.1 加速原理
使用github公開的ip范圍,掃描所有可用的ip;
間隔指定時間(5min)檢測與記錄掃描到的ip的訪問耗時;
攔截dns,訪問github時,返回最快的ip;
3.2 獲取github的ip
訪問https://api.github.com/meta,我們就可以拿到github公開其使用的ip,為了能夠在所有環境獲取到這個meta數據,我們需要把這個meta轉存到gitee或本機,因為這份數據更新不頻繁。FastGithub依賴這份數據,目前從gitee獲取到緩存副本。
3.3 443端口掃描
github使用了https,所以對應的tcp端口是443,嘗試連接到github各ip下的443端口,如果在指定時間內(默認1s)能連接成功,證明這個ip是有用的,反之就要丟棄這個ip了。在.net下,我們可以使用Socket來進行tcp連接:
[Service(ServiceLifetime.Singleton)] sealed class PortScanMiddleware : IMiddleware<GithubContext> {private const int PORT = 443;private readonly IOptionsMonitor<GithubOptions> options;private readonly ILogger<PortScanMiddleware> logger;public PortScanMiddleware(IOptionsMonitor<GithubOptions> options,ILogger<PortScanMiddleware> logger){this.options = options;this.logger = logger;}public async Task InvokeAsync(GithubContext context, Func<Task> next){try{using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);using var cancellationTokenSource = new CancellationTokenSource(this.options.CurrentValue.PortScanTimeout);await socket.ConnectAsync(context.Address, PORT, cancellationTokenSource.Token);await next();}catch (Exception){this.logger.LogTrace($"{context.Domain} {context.Address}的{PORT}端口未開放");}} }3.4 Https檢測
443端口開放,不意味這個ip就能正常的使用github,有可能在建立ssl時會失敗,或者在https請求時,服務返回的內容并不是github官網的內容,所以我們需要進一步的偵測是否有http響應,響應內容是不是github的內容。據我觀察,正常的github響應Server頭,都有GitHub.com值。
[Service(ServiceLifetime.Singleton)] sealed class HttpsScanMiddleware : IMiddleware<GithubContext> {private readonly IOptionsMonitor<GithubOptions> options;private readonly ILogger<HttpsScanMiddleware> logger;public HttpsScanMiddleware(IOptionsMonitor<GithubOptions> options,ILogger<HttpsScanMiddleware> logger){this.options = options;this.logger = logger;}public async Task InvokeAsync(GithubContext context, Func<Task> next){try{var request = new HttpRequestMessage{Method = HttpMethod.Get,RequestUri = new Uri($"https://{context.Address}"),};request.Headers.Host = context.Domain;using var httpClient = new HttpClient(new HttpClientHandler{Proxy = null,UseProxy = false,});var startTime = DateTime.Now;using var cancellationTokenSource = new CancellationTokenSource(this.options.CurrentValue.HttpsScanTimeout);var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationTokenSource.Token);var server = response.EnsureSuccessStatusCode().Headers.Server;if (server.Any(s => string.Equals("GitHub.com", s.Product?.Name, StringComparison.OrdinalIgnoreCase))){context.HttpElapsed = DateTime.Now.Subtract(startTime);await next();}}catch (TaskCanceledException){this.logger.LogTrace($"{context.Domain} {context.Address}連接超時");}catch (Exception ex){this.logger.LogTrace($"{context.Domain} {context.Address} {ex.Message}");}} }3.5 Dns服務
我們可以建設一個本機或局域網的dns服務,訪問github時,就返回檢測到的最快的一條ip,訪問其它域名時,轉發給8.8.8.8這樣穩定的上游dns服務來解析。這樣既不影響其它域名的解析速度與穩定性,同時又能正常的使用github所有服務。
4 源代碼和軟件
4.1 源代碼
github:https://github.com/xljiulang/fastgithub
4.2 軟件下載
gitee:https://gitee.com/jiulang/fast-github/releases/
總結
以上是生活随笔為你收集整理的开源FastGithub的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: C sharp实例:华盾武器门数据接收和
 - 下一篇: 用BenchmarkDotNet看Pro