ASP.NET Core跨平台技术内幕

ASP.NET Core设计初衷是开源跨平台、高性能Web服务器,其中跨平台特性较早期ASP.NET是一个显著的飞跃,.NET现可以理直气壮与JAVA同台竞技,而ASP.NET Core的高性能特性更是成为致胜法宝 。
ASP.NET Core 2.1+为IIS托管新增In-Process模型并作为默认选项(使用IISHttpServer替代了Kestrel,dotnet程序由IIS网站进程w3wp.exe内部托管) 。
为展示ASP.NET Core跨平台特性,本文重点着墨经典的Out-Process托管模型 。
宏观设计
为解耦平台web服务器差异,程序内置Http服务组件Kestrel,由web服务器转发请求到Kestrel 。

ASP.NET Core跨平台技术内幕

文章插图
  • 老牌web服务器定位成反向代理服务器,转发请求到ASP.NET Core程序(分别由IIS ASP.NET Core Module和Nginx负责)
常规代理服务器,只用于代理内部主机对外网的连接需求,一般不支持外部对内部网络的访问请求; 当一个代理服务器能够代理外部网络的主机,访问内部网络,这种代理服务器被称为反向代理服务器。
  • 平台web代理服务器、ASP.NET Core程序(dotnet.exe) 均为独立进程,平台自行决定互动细节,只需确保平台web服务器与Kestrel形成Http通信 。
Kestrel
与老牌web服务器解耦,实现跨平台部署 。
  • Kestrel使ASP.NET Core具备了基本web服务器的能力,在内网部署和开发环境完全可使用dotnet.exe自宿模式运行 。
  • Kestrel定位是Http服务组件,实力还比不上老牌web服务器,在timeout机制、web缓存、响应压缩等不占优势,在安全性等方面还有缺陷 。
因此在生产环境中必须使用老牌web服务器反向代理请求 。
跨平台管控程序,转发请求
要实现企业级稳定部署:
ASP.NET Core跨平台技术内幕

文章插图
*nix平台
将ASP.NET Core程序以dotnet.exe自宿模式运行,并配置为系统守护进程(管控应用),再由Nginx转发请求 。
以下使用systemd创建进程服务文件 /etc/systemd/system/kestrel-eqidproxyserver.service
[Unit]Description=EqidProxyServer deploy on centos[Service]WorkingDirectory=/var/www/eqidproxyserver/eqidproxyServerExecStart=/usr/bin/dotnet /var/www/eqidproxyserver/eqidproxyServer/EqidProxyServer.dllRestart=always# Restart service after 10 seconds if the dotnet service crashes:RestartSec=10TimeoutStopSec=90KillSignal=SIGINTSyslogIdentifier=dotnet-exampleUser=rootEnvironment=ASPNETCORE_ENVIRONMENT=ProductionEnvironment=DOTNET_PRINT_TELEMETRY_MESSAGE=false[Install]WantedBy=multi-user.target// 启用服务,在localhost:5000端口侦听请求sudo systemctl enable kestrel-eqidproxyserver.service 安装Nginx,并配置Nginx转发请求到localhost:5000:
server { listen 80; server_name default_website; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; 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; } }windows平台
[ 管控应用、转发请求] 由ASP.NET Core Module(插入在IIS Pipeline中的原生组件,下面简称ACM)一手操办,w3wp.exe、dotnet.exe的互动关系是通过父子进程维系 。
下图脚本力证dotnet.exe进程是w3wp.exe创建出来的子进程:
ASP.NET Core跨平台技术内幕

文章插图
得益此关系,ACM在创建dotnet.exe子进程时能指定环境变量,约定donet.exe接收(IIS转发的请求)的侦听端口 。
实际源码看ACM为子进程设定三个重要的环境变量:
  • ASPNETCORE_PORT 约定 Kestrel将会在此端口上监听
  • ASPNETCORE_AppL_PATH
  • ASPNETCORE_TOKEN 约定 携带该Token的请求为合法的转发请求
与ACM夫唱妇随的是UseIISIntegration扩展方法,完成如下工作:
① 启动Kestrel服务在http://localhost:{ASPNETCORE_PORT}上监听
② 根据 {ASPNETCORE_TOKEN} 检查请求是否来自ACM转发


推荐阅读