大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。

本章是《定制ASP NET 6.0框架系列文章》的第六篇。在本章中,我们将讨论如何在ASP NET 6.0中自定义托管宿主。比如,托管选项和不同类型的托管,并了解一下IIS上的托管。限于篇幅,本章只是一个抛砖迎玉。

本章涵盖主题包括:

  • 配置WebHostBuilder
  • 配置Kestrel
  • 配置HTTP.sys
  • IIS上的托管
  • 在Linux上使用Nginx或Apache

本章涉及的服务端体系结构主题包括:

1 准备

代码准备

我们先创建一个空运用:

dotnet new web -n ExploreHosting -o ExploreHosting

然后使用VS Code打开该项目:

cd ExploreHosting code .

名词解释:

Hosting 有些地方叫宿主,有些地方叫托管,还有的地方叫承载,为了行文方便,我这里统一叫托管,我们知道他们是同一个意思就行。

2 配置WebHostBuilder

与上一章一样,这个小节我们将重点放在Program.cs上。WebHostBuilder是托管的重要类,它是我们配置和创建Web托管的地方。

以下代码是每个新创建的ASP.NET Core Web项目默认的代码:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();

正如我们前面所了解的,默认框架已经帮我们配置了基本的内容,我们可以在在Azure或本地IIS上直接运行。显然以上的配置是最基础的,你完全可以覆写这些默认配置,包括托管的配置。

下面我们一起来看下Kestrel如何配置。

3 配置Kestrel

创建好WebHostBuilder后,我们可以使用各种方法来配置builder。这里,我们只举例一种,即使用Startup类。

在第4章:使用Kestrel配置和自定义HTTPS中我提到,Kestrel是托管应用程序的一种选项,它内置于.NET的Web服务器,基于.NET套接字实现。以前,它是在libuv之上构建的,libuv与Node.js使用相同的web服务器。Microsoft删除了对libuv的依赖,并基于.NET套接字创建了自己的Web服务器Kestrel。

在上一章中,我们使用UseKestrel方法来配置Kestrel选项:

.UseKestrel((host, options) => { // ... })

如上代码所示,第一个参数是WebHostBuilderContext,用于访问已配置的主机设置或配置本身。第二个参数是配置Kestrel的对象。

下面的代码片段显示的是我们在上一章中所做的托管配置需要监听的访问地址:

builder.WebHost.UseKestrel((host, options) => {
var filename = host.Configuration.GetValue("AppSettings:certfilename", "");
var password = host.Configuration.GetValue("AppSettings:certpassword", ""); options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions => {
listenOptions.UseHttps(filename, password);
});
});

注意:在中添加一个using一个System.Net名称空间。

以上代码演示的是覆盖默认配置,您可以在其中传入URL,例如,使用launchSettings.json文件的applicationUrl属性或环境变量。

接下来,我们看看如何设置HTTP.sys。

4 配置HTTP.sys

这里介绍另一个托管选项HTTP.sys,一个不同的Web服务器的实现。它是一个非常成熟的库,默认嵌入到Windows中,可以用来托管ASP.NET Core应用程序:

.UseHttpSys(options => { // ... })

HTTP.sys不同于Kestrel,它不能在IIS中使用,因为对于IIS来说,它与ASP.NET Core模块无法兼容。

使用HTTP.sys而不是Kestrel的主要原因是:Windows身份验证不能在Kestrel中使用。另外,如果你想将自己的应用暴露到公网当中,当时你又不想使用IIS,也可以使用HTTP.sys。

多年来,IIS一直在HTTP.sys之上运行,这意味着使用UseHttpSys()相当于IIS内部使用相同的Web服务器实现。了解有关HTTP.sys的更多信息,可以访问该地址

接下来,让我们看看使用IIS托管。

5 IIS上的托管

ASP.NET Core应用程序不应直接暴露于internet,即使它支持Kestrel或HTTP.sys。最好在两者之间有一个反向代理,或者至少有一个监视托管过程的服务。对于ASP.NET Core来说,IIS不仅仅是一个反向代理。它还负责托管进程,以防由于错误而中断。如果发生错误,IIS将重新启动进程。Nginx和IIS类似,主要是用在Linux上的反向代理,也负责托管过程。

假设你已经创建了一个新项目(删除Kestrel相关配置,对IIS不起作用)。

在IIS或Azure上托管ASP.NET Core Web之前,我们需要先编译并发布应用。

dotnet publish -o ..\published -r win-x64

编译后生成的文件可以部署在IIS上,另外它还生成了一个web.config,用于配置IIS或Azure的设置。

如果发布一个自包含的应用程序,它还包含运行时本身,即.NET Core运行时,但是交付时的大小增加了很多。而在IIS上只需创建一个新网站并将其映射到发布输出的文件夹即可。如果你需要考虑更改安全相关内容,或者带一些数据库连接等等,它会变得更加复杂,这不是一篇文章能搞定的。

6 在Linux上使用Nginx或Apache

在Linux上的发布ASP.NET Core应用和IIS上非常相似,因为没有了IIS这个反向代理,所以我们需要为反向代理做准备额外的步骤。一般我们会选择一个网络服务器,如Nginx或Apache作为反向代理,将流量转发给Kestrel和ASP.NET Core应用程序。

首先,我们需要应用接受两个特定的转发头,打开Startup.cs并在UseAuthentication中间件之前的Configure方法中添加以下行:

app.UseForwardedHeaders(new ForwardedHeadersOptions {
ForwardedHeaders = ForwardedHeaders.XForwardedFor|ForwardedHeaders.XForwardedProto
});

另外,还需要添加来自反向代理的传入流量信任,为此需要向ConfigureServices方法添加以下行:

Builder.Services.Configure<ForwardedHeadersOptions>(options => {
options.KnownProxies.Add(IPAddress.Parse("10.0.0.108"));
});

这里别忘了引入Microsoft.AspNetCore.HttpOverrides名称空间。

这里演示的是添加代理的IP地址,然后我们发布应用程序:

dotnet publish --configuration Release

将生成的文件复制到名为/var/www/yourapplication的文件夹中。你可以通过以下命令在Linux上进行快速测试:

dotnet <yourapplication.dll>

这里的yourapplication.dll是已编译的应用程序,包括路径。如果一切正常,我们就能够在http://localhost:5000/访问我们的站点。

如果访问一切正常,应用程序应该作为服务运行,我们需要在/etc/systemd/system/上创建一个服务文件,可以将文件命名为kestrel-yourapplication.service,在其中配置以下内容:

[Unit] Description=Example .NET Web API App running on Ubuntu
[Service] WorkingDirectory=/var/www/yourapplication ExecStart=/usr/bin/dotnet/var/www/yourapplication/yourapplication.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10 KillSignal=SIGINT SyslogIdentifier=dotnet-example User=www-data Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target

1.确保配置里的路径指向编译生成的文件夹。

2.此文件配置了应用程序应在默认端口上作为服务运行。

3.监视应用程序并在其崩溃时重新启动。

4.定义了来自环境变量的配置(请参阅第1章“自定义日志记录”,了解如何使用环境变量配置应用程序)。

接下来,我们看下如何配置Nginx。

6.1配置Nginx

接下来,我们可以在Nginx上进行配置了:

server {
listen 80;
server_name example.com *.example.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

以上代码告诉Nginx将端口80上的调用转发给example.com及其子域http://localhost:5000,这是应用程序的默认地址。

6.2配置Apache

Apache配置看起来非常类似于Nginx方法,几乎做了相同的事情:

<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto expr=%{REQUEST_SCHEME}
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ServerName www.example.com
ServerAlias *.example.com
ErrorLog ${APACHE_LOG_DIR}yourapplication-error.log
CustomLog ${APACHE_LOG_DIR}yourapplication-access.log
common
</VirtualHost>

以上就是Nginx和Apache的配置内容,更多细节需要你撸起袖子细细体验了。

回顾

ASP.NET Core和.NET CLI已经包含了在各种平台上运行的所有工具,并默认进行了设置,以便为Azure和IIS以及Nginx做好准备。

在.NET 6.0我们用的是WebHostBuilder,它创建了应用程序的托管环境。但是在之前的3.0版本中,我们用的是HostBuilder,它能够创建完全独立于任何Web上下文托管环境。

ASP.NET Core 6.0具有在程序后台运行驻守任务的能力,具体介绍,请期待我们的下一章《使用IHostedService和BackgroundService》。

在.NET 6.0中使用不同的托管模型的更多相关文章

  1. Hadoop 2.0 中的资源管理框架 - YARN(Yet Another Resource Negotiator)

    1. Hadoop 2.0 中的资源管理 http://dongxicheng.org/mapreduce-nextgen/hadoop-1-and-2-resource-manage/ Hadoop ...

  2. [译] C# 5.0 中的 Async 和 Await (整理中...)

    C# 5.0 中的 Async 和 Await [博主]反骨仔 [本文]http://www.cnblogs.com/liqingwen/p/6069062.html 伴随着 .NET 4.5 和 V ...

  3. Spring.Net在Mvc4.0中应用的说明

    案例Demo:http://yunpan.cn/cJ5aZrm7Uybi3 访问密码 414b Spring.Net在Mvc4.0中应用的说明 1.引用dll 2.修改Global文件 (Spring ...

  4. WCF学习之旅—WCF4.0中的简化配置功能(十五)

    六 WCF4.0中的简化配置功能 WCF4.0为了简化服务配置,提供了默认的终结点.绑定和服务行为.也就是说,在开发WCF服务程序的时候,即使我们不提供显示的 服务终结点,WCF框架也能为我们的服务提 ...

  5. 看看C# 6.0中那些语法糖都干了些什么(终结篇)

    终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...

  6. 看看C# 6.0中那些语法糖都干了些什么(中篇)

    接着上篇继续扯,其实语法糖也不是什么坏事,第一个就是吃不吃随你,第二个就是最好要知道这些糖在底层都做了些什么,不过有一点 叫眼见为实,这样才能安心的使用,一口气上五楼,不费劲. 一:字符串嵌入值 我想 ...

  7. FineUI(开源版)v6.0中FState服务器端验证的实现原理

    前言 1. FineUI(开源版)是完整开源,最早发起于 2008-04,下载全部源代码:http://fineui.codeplex.com/ 2. 你可以通过捐赠作者来支持FineUI(开源版)的 ...

  8. AppBox v6.0中实现子页面和父页面的复杂交互

    前言 1. AppBox是捐赠开源(获取源代码至少需要捐赠作者 1 元钱),基于的 FineUI(开源版)则是完整开源,网址:http://fineui.codeplex.com/ 2. 你可以通过捐 ...

  9. VB6.0中,DTPicker日期、时间控件不允许为空时,采用文本框与日期、时间控件相互替换赋值(解决方案)

    VB6.0中,日期.时间控件不允许为空时,采用文本框与日期.时间控件相互替换赋值,或许是一个不错的选择. 实现效果如下图: 文本框txtStopTime1 时间框DTStopTime1(DTPicke ...

随机推荐

  1. 《Unix 网络编程》05:TCP C/S 程序示例

    TCP客户/服务器程序示例 系列文章导航:<Unix 网络编程>笔记 目标 ECHO-Application 结构如下: graph LR; A[标准输入/输出] --fgets--> ...

  2. Eoapi — 一个可拓展的开源 API 工具

    ​ 在社区中时常会出现"抱怨某商业产品越来越臃肿"的声音,API 工具也是如此.从最早期只做 API 调试的工具,到经过多年的演进后集成全面功能的"庞然大物", ...

  3. cuda在ubuntu的安装使用分享

    前言 之前给大家分享过opencv在jetson nano 2gb和ubuntu设备中使用并且展示了一些人脸识别等的小demo.但是对于图像处理,使用gpu加速是很常见 .(以下概念介绍内容来自百科和 ...

  4. 2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP详细版

    2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP 题目描述 蓝桥学院由21栋教学楼组成,教学楼编号1到21.对于两栋教学楼a和b,当a和b互质时,a和b之间有一条走廊直接相连,两个方向皆可通 ...

  5. Linux shell 2>&1的意思

    在脚本里经常看到 ./xxx.sh > /dev/null 2>&1 ./xxx.sh > log.file 2>&1 在shell中输入输出都有对应的文件描述 ...

  6. SAP APO - Architecture

    SAP APO体系结构由多个组件组成-数据库,BI环境包含InfoCube和实时缓存. InfoCube是BI数据集市的一部分,实时缓存是您保留与计划和调度有关的所有数据的主要区域. 您可以在实时缓存 ...

  7. Java模拟西宝高速公路

    @ 目录 写在前面 一.仿真模拟的具体要求 二.类的设计 2.1 抽象父类PubVehicles 2.2 Expressway类 2.3 Passenger类 2.4 Timer类 2.5 Displ ...

  8. java运算符(超详细!!!)

    java运算符 一.算数运算符 符号 含义 + 加法 - 减法 * 乘法 / 除法 % 余数 ++ 自增 -- 自减 这些是常用的算数运算符,在java基础阶段,掌握这些就可 加减乘除运算符 代码实例 ...

  9. 抓到 Netty 一个隐藏很深的内存泄露 Bug | 详解 Recycler 对象池的精妙设计与实现

    欢迎关注公众号:bin的技术小屋,如果大家在看文章的时候发现图片加载不了,可以到公众号查看原文 本系列Netty源码解析文章基于 4.1.56.Final版本 最近在 Review Netty 代码的 ...

  10. 一键部署bash脚本怎么写

    因为我开源的一键部署应用到linux服务器的AntDeploy, 在linux部署是需要安装一个agent服务(systemctl服务) 如果是手动第一次安装的话 需要敲 下载 wget 解压 tar ...