AspNetCore 启动地址配置详解
背景
程序在發(fā)布部署時候,設置環(huán)境ASPNETCORE_URLS不生效,也沒在代碼里使用UseUrls("xxxx"),啟動一直是http://localhost:5000.最后測試發(fā)現(xiàn)只有在appsettings.json中配置urls才生效,網(wǎng)上找了半天資料也沒看到有什么問題。
最終翻看源代碼,發(fā)現(xiàn)是在StartUp中的Configure替換了全局IConfiguration導致。
平時開發(fā)大體知道程序啟動時候端口啟用順序是
UseUrls("xxx")>?環(huán)境變量?> 默認,具體是怎么確定使用哪個配置的,沒找到資料,所有才有了本文。
啟動地址配置的幾種方式介紹
環(huán)境變量ASPNETCORE_URLS
UseUrls("http://localhost:6000")
appsettings.json新增urls或者server.urls配置
使用系統(tǒng)默認
說明
程序啟動過程中,一個配置key會重復使用,先放這里
//WebHostDefaults.ServerUrlsKey如下 public static readonly string ServerUrlsKey = "urls";Web項目啟動地址配置說明
今天是介紹啟動方式,所以web啟動流程不是重點。直接進入正題。
Web啟動最終是調用WebHost.StartAsync,源代碼在這WebHost。其中有個方法EnsureServer來獲取啟動地址
private static readonly string DeprecatedServerUrlsKey = "server.urls";//省略 var urls = _config[WebHostDefaults.ServerUrlsKey] ?? _config[DeprecatedServerUrlsKey];是從全局IConfigration實例中獲取啟動地址。所以我的遇到問題這里就解決了。但環(huán)境變量和UseUrls是如何解析并記載進來的呢?下面就開今天講解。
環(huán)境變量配置詳解
一般Web程序啟動代碼如下:
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();}).Build().Run();其中ConfigureWebHostDefaults的會用調用擴展方法ConfigureWebHost
public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Action<IWebHostBuilder> configure){return builder.ConfigureWebHost(webHostBuilder =>{WebHost.ConfigureWebDefaults(webHostBuilder);configure(webHostBuilder);});}以上代碼都是定義在Microsoft.Extensions.Hosting中。
繼續(xù)看ConfigureWebHost代碼,這個方法就定義在Microsoft.AspNetCore.Hosting程序集中了。
public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action<IWebHostBuilder> configure) {//這里會加載環(huán)境變量var webhostBuilder = new GenericWebHostBuilder(builder);//這里會調用UseUrls等擴展方法configure(webhostBuilder);builder.ConfigureServices((context, services) => services.AddHostedService<GenericWebHostService>());return builder; }在GenericWebHostBuilder?構造函數(shù)里有如下代碼,用來初始化配置,最終添加到全局
IConfiguration實例中,也就是Host中IConfiguration實例。
builder.ConfigureServices((context, services) => services.AddHostedService());這個是web啟動重點,有興趣的可以看下
//加入環(huán)境變量配置 _config = new ConfigurationBuilder().AddEnvironmentVariables(prefix: "ASPNETCORE_").Build(); //把配置加載到Host _builder.ConfigureHostConfiguration(config => {config.AddConfiguration(_config);// We do this super early but still late enough that we can process the configuration// wired up by calls to UseSettingExecuteHostingStartups(); })AddEnvironmentVariables環(huán)境變量解析最終會使用EnvironmentVariablesConfigurationProvider,有興趣的可以看下AddEnvironmentVariables源代碼,EnvironmentVariablesConfigurationProvider解析環(huán)境的方法如下。
public override void Load() {Load(Environment.GetEnvironmentVariables()); }internal void Load(IDictionary envVariables) {var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);//這里是篩選ASPNETCORE_開頭的環(huán)境變量var filteredEnvVariables = envVariables.Cast<DictionaryEntry>().SelectMany(AzureEnvToAppEnv).Where(entry => ((string)entry.Key).StartsWith(_prefix, StringComparison.OrdinalIgnoreCase));foreach (var envVariable in filteredEnvVariables){//這里會把前綴去掉加到配置里var key = ((string)envVariable.Key).Substring(_prefix.Length);data[key] = (string)envVariable.Value;}Data = data; }IConfiguration中的key是不區(qū)分大小寫的,所有最終的效是在全局IConfiguration中新增一條key為urls的記錄。
而如果使用默認Host.CreateDefaultBuilder(),appsettings.json中的配置會先加載。
如果在appsettings.json中配置urls的話,環(huán)境變量也定義了,就會被環(huán)境變量的覆蓋掉。
UseUrls解析
UseUrls解析最終會調用GenericWebHostBuilder中的UseSetting
//UseUrls代碼如下 public static IWebHostBuilder UseUrls(this IWebHostBuilder hostBuilder, params string[] urls) {if (urls == null){throw new ArgumentNullException(nameof(urls));}return hostBuilder.UseSetting(WebHostDefaults.ServerUrlsKey, string.Join(ServerUrlsSeparator, urls)); }//GenericWebHostBuilder中的UseSetting public IWebHostBuilder UseSetting(string key, string value) {_config[key] = value;return this; }由于這個方法是在?new GenericWebHostBuilder(builder);
之后調用,就是?configure(webhostBuilder);,上面代碼也有說明。所以IConfiguration中urls如果有值,又會被覆蓋掉。所以優(yōu)先級最高的是UseUrls()。
默認地址
假如以上3種配置都沒有,就是地址為空,會使用默認策略。這里是源代碼,下面是默認策略使用的地址
/// <summary>/// The endpoint Kestrel will bind to if nothing else is specified./// </summary>public static readonly string DefaultServerAddress = "http://localhost:5000";/// <summary>/// The endpoint Kestrel will bind to if nothing else is specified and a default certificate is available./// </summary>public static readonly string DefaultServerHttpsAddress = "https://localhost:5001";結論
啟動端口設置優(yōu)先級如下:
UseUrls("xxxx")?> 環(huán)境變量 >?appsetting.json配置urls>默認地址
不要隨意替換全局的IConfiguration,如果不手動加入環(huán)境變量解析的話,會丟失一部分配置數(shù)據(jù)。
作者:cgyqu
出處:https://www.cnblogs.com/cgyqu/p/12169014.html
總結
以上是生活随笔為你收集整理的AspNetCore 启动地址配置详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel模板导出之导出教材订购表
- 下一篇: BeetleX网关非法Url请求拦截插件