【AspNet Core】Nuget代理網站


因為訪問Nuget太慢,在Dotnet Core RC2發布前,我就基於Asp.Net做了一個Nuget代理網站

這是網站地址:http://nuget.lzzy.net/

Nuget源:http://nuget.lzzy.net/api/v2

廣西電信百兆帶寬。

這個網站將會緩存所有訪問過的API頁面與包。

API頁面緩存的原理,第一次訪問會等待服務器從Nuget上下載頁面信息

下載后會替換里面的網址並保存到數據庫。

第二次訪問會從數據庫里取出頁面兵判斷過期時間

如果已過期,先返回頁面信息,后台新建線程下載新頁面。

這樣國內訪問的時候就會覺得非常快。

 

升級至AspNet Core

等到RC2發布后,我覺得,是時候研究Dotnet Core平台了

那么就從這個小小的Nuget代理網站開始吧。

在.Net FX下,開發的代理程序是通過IHttpHandler進行代理的

那么到了AspNet Core,就變成了通過中間件進行代理。

路由在AspNetCore下也變得不同了,使用起來比老版的更方便更簡單。

 

路由的使用

注:路由的使用需要用到包Microsoft.AspNetCore.Routing

首先創建一個靜態類,添加一個UseXXXMiddleware擴展方法,這是AspNetCore使用中間件的約定,當然你也可以起其它名字。

在方法里,我們需要new一個RouteBuilder實例。

在實例里調用各種映射方法。

然后調用RouteBuilder的Build方法,這將生成一個路由。

最后再使用路由中間件的擴展方法UseRouter,把剛剛Build出來的路由作為參數傳遞進去即可。

        public static IApplicationBuilder UseNugetProxyMiddleware(this IApplicationBuilder builder, IConfigurationRoot config)
        {
            if (!Directory.Exists("Packages"))
                Directory.CreateDirectory("Packages");
            
            var cacheSection = config.GetSection("Cache");
            _CacheMetadata = int.Parse(cacheSection.GetSection("Metadata").Value);
            _CacheList = int.Parse(cacheSection.GetSection("List").Value);
            _CacheDetail = int.Parse(cacheSection.GetSection("Detail").Value);
            _CacheDefault = int.Parse(cacheSection.GetSection("Default").Value);
            var proxySection = config.GetSection("Proxy");
            _Source = proxySection.GetSection("Source").Value;
            _Replace = proxySection.GetSection("Replace").Value;
            _Path = proxySection.GetSection("Path").Value;

            var routeBuilder = new RouteBuilder(builder);
            routeBuilder.MapGet(_Path + "/{action}", PageHandler);
            routeBuilder.MapGet(_Path, PageHandler);
            routeBuilder.MapGet(_Path + "/package/{id}/{version}", PackageHandler);

            _Path = "/" + _Path;

            var router = routeBuilder.Build();
            return builder.UseRouter(router);
        }

        private static async Task PageHandler(HttpContext httpContext)
        {

        }

 

路由下的中間件使用

使用RouteBuilder的映射方法時,需要傳遞處理HttpContext的委托

這里其實與AspNet Core本身的中間件方法其實是一樣的。

只不過,我們需要在方法里獲取各種數據,而不是像AspNet Core中間件一樣可以在構造函數里獲取到一些服務。

AspNet Core路由提供了HttpContext獲取路由參數的擴展方法GetRouteValue。

        private static async Task PackageHandler(HttpContext httpContext)
        {

            string id = httpContext.GetRouteValue("id") as string;
            string version = httpContext.GetRouteValue("version") as string;
        }

也有GetRouteData擴展方法,這里我們並不需要用到。

 

EntityFramework Core

RC2下,EntityFramework Core的使用出現了一些變化

在Startup.cs里,配置EF Core

        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddDbContext<DataContext>(builder =>
            {
                builder.UseSqlServer(Configuration.GetConnectionString("DataContext"));
            });
        }

在這里修改DbContext的配置。

要注意的是,繼承DbContext的類,要使用帶參數的構造函數並調用基類構造函數。

    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options) { }

        public DbSet<Page> Page { get; set; }
    }

 

互斥鎖

多人訪問同一個新頁面,只能有一個人去下載新頁面的數據,其他人則等待。新包同理。

多人訪問同一個過期頁面,只會創建一個新線程去下載新頁面的數據。

項目里封裝了一個SynchronizationHelp類,在中間件里通過路徑進行互斥處理。

 

剩下的也沒什么特別值得要說的了,一些盡在源碼里。 

 

Github

這里是這個代理網站的Github:

https://github.com/Kation/NugetProxy

 

啊,對了,還有一點。

代理網站的配置。

配置文件:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "ConnectionStrings": {
    "DataContext": "server=(local);database=nuget;uid=sa;pwd=123@abc"
  },
  "Cache": {
    "Metadata": "10080",
    "List": "60",
    "Detail": "1440",
    "Default": "30"
  },
  "Proxy": {
    "Source": "https://www.nuget.org/api/v2",
    "Replace": "https://www.nuget.org/api/v2",
    "Path": "api/v2"
  }
}

可以設定緩存時間,超出時間后才去下載新頁面,單位是分鍾。

Proxy的Source是Nuget源

Replace是要替換的字符串,將會替換為當前網站地址+Path

PS:我在美國架了一台20M的VPS反向代理Nuget

http://nuget.lzzy.net/api/v2使用的是我的VPS方向代理的源

效果比直接訪問Nuget快……


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM