背景

程序在发布部署时候,设置环境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实例中,也就是Host中IConfiguration实例。

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 UseSetting
ExecuteHostingStartups();
})

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);,上面代码也有说明。所以IConfiguration中urls如果有值,又会被覆盖掉。所以优先级最高的是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,如果不手动加入环境变量解析的话,会丢失一部分配置数据。
  3. 将自己的配置注入的全局,可以使用以下方式,这样就会把配置追加到全局的IConfiguration中
 Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(builder =>
{
builder.UseStartup<Startup>();
}).ConfigureAppConfiguration(config =>
{
config.AddJsonFile("config.json", true, true);
}).Build().Run();

作者:cgyqu

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

本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位置注明作者及出处。

NetCore 启动地址配置详解的更多相关文章

  1. Java从入门到精通——数据库篇Mongo DB 安装启动及配置详解

    一.概述     Mongo DB 下载下来以后我们应该如何去安装启动和配置才能使用Mongo DB,本篇博客就给大家讲述一下Mongo DB的安装启动及配置详解. 二.安装 1.下载Mongo DB ...

  2. GRUB2配置详解:默认启动项,超时时间,隐藏引导菜单,配置文件详解,图形化配置

    配置文件详解: /etc/default/grub # 设定默认启动项,推荐使用数字 GRUB_DEFAULT=0 # 注释掉下面这行将会显示引导菜单 #GRUB_HIDDEN_TIMEOUT=0 # ...

  3. Spring Boot 启动(二) 配置详解

    Spring Boot 启动(二) 配置详解 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Boot 配置 ...

  4. apache 虚拟主机详细配置:http.conf配置详解

    apache 虚拟主机详细配置:http.conf配置详解 Apache的配置文件http.conf参数含义详解 Apache的配置由httpd.conf文件配置,因此下面的配置指令都是在httpd. ...

  5. tomcat的配置详解:[1]tomcat绑定域名

    转自:http://jingyan.baidu.com/article/7e440953dc096e2fc0e2ef1a.html tomcat的配置详解:[1]tomcat绑定域名分步阅读 在jav ...

  6. WebsitePanel(wsp)配置详解(安装指南)

    WebsitePanel(wsp)配置详解(安装指南) 铁卫士原创 估计很多同学都还不知道WebsitePanel是什么东东吧,WebsitePanel简称wsp是微软旗下,开源免费的虚拟主机系统,我 ...

  7. maven常用插件配置详解

    常用插件配置详解Java代码    <!-- 全局属性配置 --> <properties> <project.build.name>tools</proje ...

  8. Apache2.2+Tomcat7.0整合配置详解

    一.简单介绍 Apache.Tomcat Apache HTTP Server(简称 Apache),是 Apache 软件基金协会的一个开放源码的网页服务器,可以在 Windows.Unix.Lin ...

  9. Nginx+Tomcat的服务器端环境配置详解

    这篇文章主要介绍了Nginx+Tomcat的服务器端环境配置详解,包括Nginx与Tomcat的监控开启方法,需要的朋友可以参考下 Nginx+tomcat是目前主流的Javaweb架构,如何让ngi ...

随机推荐

  1. Libev源码分析09:select突破处理描述符个数的限制

    众所周知,Linux下的多路复用函数select采用描述符集表示处理的描述符.描述符集的大小就是它所能处理的最大描述符限制.通常情况下该值为1024,等同于每个进程所能打开的描述符个数. 增大描述符集 ...

  2. pytorch更新

    Pytorch如何更新版本与卸载,使用pip,conda更新卸载Pytorch 2018年05月22日 07:33:52 醉雨轩Y 阅读数 19047   今天我们主要汇总如何使用使用ubuntu,C ...

  3. angularJS $q

    1.$q $q是Angular的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常). 2.defer defer的字面意思是延迟, $q.defer()   ...

  4. PHP 面试题三

    1.nginx使用哪种网络协议? nginx是应用层 我觉得从下往上的话 传输层用的是tcp/ip 应用层用的是http fastcgi负责调度进程 2. <? echo 'hello tush ...

  5. vector容器、

    一.  vector  向量容器1. 创建   vector  对象(1)不指定容器大小vector<int> V;(2)指定容器大小vector<int> V(10);(3) ...

  6. 【codeforces 789A】Anastasia and pebbles

    [题目链接]:http://codeforces.com/contest/789/problem/A [题意] 有n种物品,每种物品有wi个; 你有两个口袋,每个口袋最多装k个物品; 且口袋里面只能装 ...

  7. PHP会员找回密码功能的简单实现

    文章来自:博客 http://www.jb51.net/article/91944.htm 设置思路 1.用户注册时需要提供一个E-MAIL邮箱,目的就是用该邮箱找回密码. 2.当用户忘记密码或用户名 ...

  8. P1087 N个数的最大公约数

    题目描述 今天灵灵学习了使用欧几里得算法(即:辗转相除法)求解两个数的最大公约数.于是他决定用这个方法求解 \(N\) 个数的最大公约数. 输入格式 输入的第一行包含一个整数 \(N(1 \le N ...

  9. 2018-2-13-win10-uwp-InkCanvas控件数据绑定

    title author date CreateTime categories win10 uwp InkCanvas控件数据绑定 lindexi 2018-2-13 17:23:3 +0800 20 ...

  10. Jmeter压力测试教程(入门篇)

    2.4 添加HTTP镜像服务器 在运行测试之前,如何验证我们发送的信息是否有误?如何可以理直气壮的告诉别人自己发送的测试请求没有问题?这里推荐添加HTTP镜像服务器进行校验测试. HTTP镜像服务器并 ...