Net core学习系列(四)——Net Core项目执行流程
"跨平台"后的ASP.Net Core是如何接收并处理请求的呢? 它的运行和处理机制和之前有什么不同?本章从"宏观"到"微观"地看一下它的结构以及不同时期都干了些什么.
一、ASP.NET Core 的运行机制

图1
ASP.NET Core 的运行机制如上图所示, 现在做一下详细说明.
①Web Server: ASP.NET Core提供两种服务器可用, 分别是Kestrel和HTTP.sys(Core 1.x 中被命名为 WebListener),
A. Kestrel是一个跨平台的Web服务器;
B. HTTP.sys只能用在Windows系统中.
②Internet: 当需要部署在Internal Network 中并需要 Kestrel 中没有的功能(如 Windows 身份验证)时,可以选择HTTP.sys。
③IIS、Apache、Nginx: Kestrel 可以单独使用 ,也可以将其与反向代理服务器(如 IIS、Nginx 或 Apache)结合使用。 请求经这些服务器进行初步处理后转发给Kestrel(即图中虚线的可选流程).
大概的运行机制就是这样, 那么具体到ASP.NET Core Application是如何运行的呢? 我们将图1中ASP.NET Core Application这个红框框放大一下,看下一节.
二、ASP.NET Core 的启动
看一下将图1的ASP.NET Core Application放大后的样子:

图2
④Main方法, 程序的起点.
⑤创建并配置WebHostBuilder: 首先调用CreateDefaultBuilder( 如图所示, 它是一系列配置的大综合,下文做详细介绍), 进行一系列配置之后, 调用 UseStartup<T>(),
指定⑩Startup为启动配置文件. 在Startup中, 将进行两个比较重要的工作, ⑧服务的依赖注入和⑨配置管道, 后文将对这一部分详细的介绍.
⑥生成WebHostBuilder并进行了一系列配置之后, 通过这个WebHostBuilder来Build出一个IWebHost.
⑦调用IWebHost的Run方法使之开始运行.
ASP.NET Core 应用程序本质上是控制台应用程序,所以它也是以一个我们熟悉的Main方法作为程序的起点.
打开Program.cs文件, 默认是如下代码

public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
} public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}

定义了一个BuildWebHost方法, 在Main中调用它返回一个IWebHost, 并使这个IWebHost"Run起来". 再看BuildWebHost方法内部, 通过调用CreateDefaultBuilder
创建了一个IWebHostBuilder, 然后用这个Builder来Build出一个IWebHost.
简单来说就是 创建IWebHostBuilder=>Builder=>Build()=>IWebHost=>Run().
三、WebHostBuilder的一系列配置
系统离不开各种各样的配置, 比如常见的读取配置文件, 指定日志处理程序等, 我们详细的看一下.
(一)CreateDefaultBuilder
CreateDefaultBuilder, 顾名思义, 它是一个默认配置 . 如图2所示, 它主要是调用了各种ConfigureXXX和UseXXX, 首先看一下它的源码

1 public static IWebHostBuilder CreateDefaultBuilder(string[] args)
2 {
3 var builder = new WebHostBuilder()
4 .UseKestrel()
5 .UseContentRoot(Directory.GetCurrentDirectory())
6 .ConfigureAppConfiguration((hostingContext, config) =>
7 {
8 var env = hostingContext.HostingEnvironment;
9
10 config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
11 .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
12
13 if (env.IsDevelopment())
14 {
15 var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
16 if (appAssembly != null)
17 {
18 config.AddUserSecrets(appAssembly, optional: true);
19 }
20 }
21
22 config.AddEnvironmentVariables();
23
24 if (args != null)
25 {
26 config.AddCommandLine(args);
27 }
28 })
29 .ConfigureLogging((hostingContext, logging) =>
30 {
31 logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
32 logging.AddConsole();
33 logging.AddDebug();
34 })
35 .UseIISIntegration()
36 .UseDefaultServiceProvider((context, options) =>
37 {
38 options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
39 });
40
41 return builder;
42 }

上面的源码中我们看到它这些ConfigureXXX和UseXXX的过程, 而在Core 1.0版本中是没有CreateDefaultBuilder这个方法的,
系统默认是逐个调用这些ConfigureXXX和UseXXX的,在Core 2.0中, 为了代码简洁和使用方便, 将这些常规情况下需要调用的方法放到了这个名为CreateDefaultBuilder的方法中.
一般情况下,调用CreateDefaultBuilder 执行其中的这些的默认配置足够用了。但既然这是默认配置, 我们就可以根据自身情况自定义.
因为这些配置都是对 WebHostBuilder进行修改, 而修改后再次返回修改后的 WebHostBuilder, 所以在CreateDefaultBuilder不符合现实需求的情况下可以通过如下的方法进行自定义.
1)不调用CreateDefaultBuilder, 将上面讲到的这些配置选择性的执行, 甚至可以添加、替换里面的某些配置, 如将UseKestrel改为UseHttpSys.
2)小幅改动, 即调用CreateDefaultBuilder之后再对其返回的WebHostBuilder调用自定义的其他配置方法. 例如可以再次调用 ConfigureAppConfiguration,从而添加更多的配置源.
下面来介绍一下这些ConfigureXXX和UseXXX.
A. UseKestrel
用于指定服务器使用 Kestrel, 若使用HttpSys, 需使用UseHttpSys。
Kestrel 是跨平台 ASP.NET Core Web 服务器,它基于 libuv(一个跨平台异步 I/O 库)。 Kestrel 是 Web 服务器,默认包括在 ASP.NET Core 项目模板中。
Kestrel 支持以下功能:
- HTTPS
- 用于启用 WebSocket 的不透明升级
- 用于获得 Nginx 高性能的 Unix 套接字.
默认情况下,ASP.NET Core 项目模板使用的是 Kestrel。
我们可以再次调用UseKestrel来修改Kestrel的配置, 例如限制请求正文的最大值

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(options =>
{
options.Limits.MaxRequestBodySize = 10 * 1024;
})
.Build();

B. UseContentRoot
为应用程序指定根目录。需注意这和 StaticFiles的根是不同的, 虽然默认情况下StaticFiles的根是以ContentRoot为依据 ([ContentRoot]/wwwroot)。
C. ConfigureAppConfiguration
读取配置。如上代码会读取 appsettings.json 和 appsettings.{env.EnvironmentName}.json , env.EnvironmentName指的是环境, 例如Development. 当在Development环境的时候, 还会读取用户密钥。
这部分在学习系统配置的时候详细介绍.
D. ConfigureLogging
配置日志处理程序,控制台和调试日志提供程序, 学习日志的时候再详讲.
E. UseIISIntegration
将应用程序配置为在 IIS 中运行。上面已经讲过, 这里仍需要使用 UseKestrel, 而IIS 起到反向代理的作用,而 Kestrel 仍用作主机。
如果应用程序没有使用 IIS 作为反向代理,那么 UseIISIntegration 不会有任何效果。因此,即使应用程序在非 IIS 方案中运行,也可以安全调用这种方法。
F.UseDefaultServiceProvider
设置默认的依赖注入容器, 这部分在后面学习依赖注入的时候再详讲.
四、ASP.NET Core 的环境
在 ASP.NET Core 中,有个非常重要而且常用的东西叫环境变量, 它由 ASPNETCORE_ENVIRONMENT 环境变量指定。
我们可以根据需要将此变量设置为任意值,但通常使用的是值 Development、Staging 和 Production。它定义了当前应用程序的运行环境, 我们经常会根据这个变量来让应用采用不同的处理方式.
在上面的例子中, 就有这样的用法

if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}

_Layout View 中
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
因此,如果在run 之前将 ASPNETCORE_ENVIRONMENT 变量设置为 Development(或在 launchSettings.json 文件中设置此环境变量),
应用程序会在 Development 模式下运行,而不是 Production 模式(这是不设置任何变量时的默认模式)。
注意:在 Windows 和 macOS 上,环境变量和值不区分大小写。Linux 环境变量和值区分大小写。
Net core学习系列(四)——Net Core项目执行流程的更多相关文章
- 【.Net Core 学习系列】-- EF Core 实践(Code First)
一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二解决方案: 新建项目: File --> New --> Project --> ...
- 【.Net Core 学习系列】-- EF Core实践(DB First)
一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二.准备数据: CREATE DATABASE [Blogging]; GO USE [Blogging ...
- Vue (学习第四部 前端项目搭建流程 )
目录 客户端项目搭建 创建项目目录 初始化项目 安装路由 Vue-router 下载安装路由组件 配置路由 初始化路由对象 注册路由信息 在视图函数中显示路由对应的内容 路由对象提供的操作 页面跳转 ...
- CobaltStrike逆向学习系列(13):RDI 任务执行流程分析
这是[信安成长计划]的第 13 篇文章 0x00 目录 0x01 任务号 0x02 功能执行 0x03 结果接收 在上一篇文章中已经讲明了 RDI 类型的任务在发布时候的流程,接下来就是执行了,文中不 ...
- EntityFramework Core 学习系列(一)Creating Model
EntityFramework Core 学习系列(一)Creating Model Getting Started 使用Command Line 来添加 Package dotnet add pa ...
- scrapy爬虫学习系列四:portia的学习入门
系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备: http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...
- DocX开源WORD操作组件的学习系列四
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- .net reactor 学习系列(四)---.net reactor应用场景
原文:.net reactor 学习系列(四)---.net reactor应用场景 前面已经学习了.net reactor一些基础知识,现在准备学习下实际的应用场景,只是简单的保护和 ...
- Ansible Tower系列 四(使用tower执行一个命令)【转】
在主机清单页面中,选择一个主机清单,进入后,选择hosts里的主机 Paste_Image.png 点击 RUN COMMANDS MODULE 选择 commandARGUMENTS 填写 ifco ...
- ServletContext--HttpServletResponse--web项目执行流程
一.ServletContext 接口(javax.servlet) 定义:public interface ServletContext 原理: Tomcat启动的时候,需要识别webapp ...
随机推荐
- css,对包含有子元素的元素进行flex后,会影响原有的布局。如何后续处理
对包含有子元素的元素进行flex后,会影响原有的布局. 例如设置两个div,第一个div包含一个img(图片),第二个div包含多个p元素(对前面的img的说明).如下图 1:当对着两个两个div进行 ...
- Windows上安装ElasticSearch7
安装JDK1.8(包括)以上版本 安装ElasticSearch ElasticSearch下载地址: https://www.elastic.co/downloads/elasticsearch 双 ...
- PHP使用Redis的Pub/Sub(发布订阅)命令
1.概念 名称 含义 channel 频道:生产者和消费者直接操作的对象 publish 生产者:向channel发送消息 subscribe 消费者:订阅一个或多个channel psubscrib ...
- 我的oracle 健康检查报告
最近一直想用sql来生成oracle的健康检查报告,这样看起来一目了然,经过网上搜资料加自己整理终于算是成型了,部分结果如下图所示, 具体参考附件,恳请广大网友看看是否还有需要添加的地方. DB_he ...
- PHP Lumen Laravel 解决validate方法自定义message无效的问题
/** * 由于 \Laravel\Lumen\Routing\ProvidesConvenienceMethods::validate 在验证不通过时, * 抛出 \Illuminate\Valid ...
- 安装lamp服务器
1.安装http: $ yum install httpd 2.启动http: $ systemctl start httpd 3.访问:http://192.168.1.100 4.Installi ...
- mysql考生号后三位对出密号
select mihao,substring(t1.kaohao, -3) from t_zhaosheng_zhiyuan as t1 where substring(t1.kaohao, -3) ...
- 泛微 e-cology OA 远程代码执行漏洞复现
0x00 前言 Poc已在github公开,由于环境搭建较为复杂,所以我在空间搜索引擎中找了国外的网站进行复现 如果有想自行搭建环境复现的可以在公众号内回复“泛微环境”即可获取源码及搭建方式 0x01 ...
- spring cloud (三) 路由 zuul
1 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
- heapq 对有序的数组列表进行整体排序
""" 功能:实现对有序的多个数组整体排序,获取top k个最小元素 """ from heapq import * def heap_so ...