背景

程序在发布部署时候,设置环境ASPNETCORE_URLS不生效,也没在代码里使用UseUrls("xxxx"),启动一直是http://localhost:5000.最后测试发现只有在appsettings.json中配置urls才生效,网上找了半天资料也没看到有什么问题。

最终翻看源代码,发现是在StartUp中的Configure替换了全局IConfiguration导致。

平时开发大体知道程序启动时候端口启用顺序是
UseUrls("xxx")环境变量 > 默认,具体是怎么确定使用哪个配置的,没找到资料,所有才有了本文。

启动地址配置的几种方式介绍
  1. 环境变量ASPNETCORE_URLS

#windows
set ASPNETCORE_URLS=http://localhost:6000
#linux
export ASPNETCORE_URLS=http://localhost:6000
  1. UseUrls("http://localhost:6000")

  2. appsettings.json新增urls或者server.urls配置

{"urls":"http://localhost:6000;http://localhost:6001","server.urls":"http://localhost:6000;http://localhost:6001"
}
  1. 使用系统默认

说明

程序启动过程中,一个配置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实例中获取启动地址。所以我的遇到问题这里就解决了。但环境变量UseUrls是如何解析并记载进来的呢?下面就开今天讲解。

环境变量配置详解

一般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中。

继续看ConfigureWebHost代码,这个方法就定义在Microsoft.AspNetCore.Hosting程序集中了。

public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action<IWebHostBuilder> configure)
{//这里会加载环境变量var webhostBuilder = new GenericWebHostBuilder(builder);//这里会调用UseUrls等扩展方法configure(webhostBuilder);builder.ConfigureServices((context, services) => services.AddHostedService<GenericWebHostService>());return builder;
}

GenericWebHostBuilder 构造函数里有如下代码,用来初始化配置,最终添加到全局
IConfiguration实例中,也就是HostIConfiguration实例。

builder.ConfigureServices((context, services) => services.AddHostedService());这个是web启动重点,有兴趣的可以看下

//加入环境变量配置
_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环境变量解析最终会使用EnvironmentVariablesConfigurationProvider,有兴趣的可以看下AddEnvironmentVariables源代码,EnvironmentVariablesConfigurationProvider解析环境的方法如下。

public override void Load()
{Load(Environment.GetEnvironmentVariables());
}internal void Load(IDictionary envVariables)
{var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);//这里是筛选ASPNETCORE_开头的环境变量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是不区分大小写的,所有最终的效是在全局IConfiguration中新增一条key为urls的记录。
而如果使用默认Host.CreateDefaultBuilder()appsettings.json中的配置会先加载。
如果在appsettings.json中配置urls的话,环境变量也定义了,就会被环境变量的覆盖掉。

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);,上面代码也有说明。所以IConfigurationurls如果有值,又会被覆盖掉。所以优先级最高的是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";
结论
  1. 启动端口设置优先级如下:
    UseUrls("xxxx") > 环境变量 > appsetting.json配置urls>默认地址

  2. 不要随意替换全局的IConfiguration,如果不手动加入环境变量解析的话,会丢失一部分配置数据。

作者:cgyqu
出处:https://www.cnblogs.com/cgyqu/p/12169014.html

AspNetCore 启动地址配置详解相关推荐

  1. JVM启动参数配置详解

    JVM启动参数配置详解 1. JDK8的JVM启动参数默认配置 2. JDK8的JVM启动参数说明 2.1 基本参数 2.2 G1相关参数 2.3 辅助信息 1. JDK8的JVM启动参数默认配置 - ...

  2. 分区启动Grub2配置详解

    本文是一篇关于分区启动的帖子 一. grub.cfg 详解 ( 色红为说明 ) grub.cfg 默以为读只,要修改前先设为可写 sudo chmod +w /boot/grub/grub.cfg s ...

  3. php-fpm 的参数,php-fpm启动参数配置详解

    pid = run/php-fpm.pid #pid设置,默认在安装目录中的var/run/php-fpm.pid,建议开启 error_log = log/php-fpm.log #错误日志,默认在 ...

  4. php-fpm 启动参数及重要配置详解

    2019独角兽企业重金招聘Python工程师标准>>> php-fpm 启动参数及重要配置详解 约定几个目录 /usr/local/php/sbin/php-fpm /usr/loc ...

  5. phonegap安装 环境搭建与配置详解(3.4 完整版 提供下载地址)

    phonegap安装 环境搭建与配置详解(3.4 完整版 提供下载地址) 原文连接:http://blog.csdn.net/aaawqqq/article/details/19755179 phon ...

  6. Dropbear 安装配置与启动ssh服务详解

    Dropbear 安装配置与启动ssh服务详解  扎啤 关注 2017.09.12 22:57* 字数 441 阅读 4160评论 0喜欢 0 一.介绍 dropbear作为一款基于ssh协议的轻量级 ...

  7. 内核启动流程分析(二)配置详解

    总体概述 配置详解 配置的最终目的,是生成了.config文件,查看下这个文件, # # Automatically generated make config: don't edit # Linux ...

  8. vue中使用ECharts实现中国地图配置详解(配官方配置地址)

    前言: 1.实现自定义左下角的视觉映射组件(包括自定义颜色.文字.图元大小) 2.实现自定义悬浮提示框 如下图所示: 实现步骤: 一.在vue中安装echarts 1.npm install echa ...

  9. elasticsearch-.yml(中文配置详解)

    此elasticsearch-.yml配置文件,是在$ES_HOME/config/下 elasticsearch-.yml(中文配置详解) # ======================== El ...

最新文章

  1. 【笔记】震惊!世上最接地气的字符串浅谈(HASH+KMP)
  2. 使Docker搭建Java Web运行环境
  3. 20180525小测
  4. 【数据竞赛】从0梳理1场CV缺陷检测赛事!
  5. 美素数(HDU 4548)(打表,简化时间复杂度)
  6. android studio 解决gradle加载依赖慢的问题
  7. docker log 文件 清理
  8. 吃透理财三句话人人都能成百万富翁
  9. 怎样进入pe重建硬盘
  10. Ddos攻击攻击与防御
  11. 【Spark亚太研究院系列丛书】Spark实战高手之-构建Spark集群-安装Ubuntu系统(3)
  12. springmvc07 Json处理
  13. TIMESTAMP与DATETIME的区别
  14. 百年GE濒临破产,传奇霸业何以衰亡?
  15. 中科院分词系统大致流程
  16. tfidf算法 python_Python TFIDF计算文本相似度
  17. 怎样查找MP3音乐链接地址 用于QQ空间背景
  18. 【分析】RBD Mirroring - 原理、概念、命令
  19. OLED显示字符的大小与PCtoLCD2002生成字模
  20. Dell B1260dn Printer驱动的安装

热门文章

  1. C#正则表达式编程(四)转致周公
  2. PHP如何防采集方法代码
  3. 多年经验的程序员迷失了自己,该怎么办?
  4. 德国巴伐利亚山谷积雪遍地 汽车被大雪掩埋
  5. “数据门”事件频发 如何避免人为因素导致数据泄露?
  6. 微软 改变 开源【几个站点】
  7. Java读取word文件,字体,颜色
  8. [改善Java代码]性能考虑,数组是首选
  9. Angularjs调用公共方法与共享数据
  10. 使用OClint进行iOS项目的静态代码扫描