[2core]web服务器配置
创始人
2024-09-26 15:49:27
0

迁移问题

相对来说本文的内容有点多,主要包含基于IISExpress调试配置、Kestrel配置、IIS配置、IISIntegation配置、HTTPS配置、基于控制器API。ASP.NET 4.x及以前版本的框架是基于IIS部署的,而ASP.NET Core则是独立部署运行,并不依赖IIS,所以需要把依赖IIS的功能剥离出来独自管理,因此出现了不少知识点需要记录。

IISExpress调试配置

当你使用Visual Studio2019+版本创建一个ASP.NET Core项目后,可能要做的第一件事儿就是运行起来看看效果,此时VS编译好项目后,创建一个承载项目运行的进程,然后打开浏览器,访问默认的服务地址得到输出结果。作为一名程序员,你可能首先关注的是浏览器地址栏里的地址构成,然后再去程序代码中查找配置。

使用VS调试ASP.NET Core项目,默认使用的是IISExpress服务器,项目的启动设置位于“启动项目 》Properties 》 launchSettings.json”文件里,我们可以通过更改launchSettings.json文中里的选项控制VS+IISExpress+ASP.NET Core项目的调试运行过程,比如更换默认分配的端口号,添加https链接方式等。

{   "$schema": "https://json.schemastore.org/launchsettings.json",   "iisSettings": {     "windowsAuthentication": false,     "anonymousAuthentication": true,     "iisExpress": {       "applicationUrl": "http://localhost:12488",       "sslPort": 0     }   },   "profiles": {     "jks.core.test.webserver": {       "commandName": "Project",       "dotnetRunMessages": true,       "launchBrowser": true,       "launchUrl": "index",       "applicationUrl": "http://localhost:9000;https://localhost:9001",       "environmentVariables": {         "ASPNETCORE_ENVIRONMENT": "Development"       }     },     "IIS Express": {       "commandName": "IISExpress",       "launchBrowser": true,       "launchUrl": "index",       "environmentVariables": {         "ASPNETCORE_ENVIRONMENT": "Development"       }     }   } }

Kestrel配置

Kestrel服务器是ASP.NET Core实现跨平台的关键因素,没有它的出现无从谈起跨平台(Windows/Linux/Unix/MacOS)。 对于Kestrel的配置可以通过编码方式写在程序中,但是作为一名优秀的程序员一定会将其配置写入配置文件,然后通过控制配置文件实现对Kestrel服务器的动态设置(配置信息位于appsettings.json文件里)。由于ASP.NET Core毕竟是巨硬家的东西,IIS又那么强大,不可能弃IIS不用,所以ASP.NET Core项目的部署方式分为以下多种:
1)Kestrel部署:独立部署运行,可运行任何.NET支持的操作系统上,即实现跨平台。
2)HttpSys部署:由于支持使用操作系统内核功能,效率最高,依赖Windows平台。
3)IIS部署(InProcess):与ASP.NET 4.x时期的项目相同,效率比较高,依赖Windows和IIS。
4)IISIntegation部署(OutOfProcess):IIS更像代理服务器,将接收的请求转发给Kestrel处理。
5)其他服务器:Nginx、Caddy、BFE和Apache等,实现过程也类似于IISIntegation模式的代理方式。

1.为了方便使用和管理配置被划分为两部分:Kestrel配置与KestrelSettings配置

{   //Web服务器配置   "WebServer": {     //服务器类型(IISExpress,Kestrel,IIS,IISIntegation),IIS注意与web.config配合     "WSType": "IISExpress",     "Kestrel": {       "Endpoints": {         "HttpEndPoint": {           "Url": "http://*:9000",           "Protocols": "Http1AndHttp2AndHttp3"         },         "HttpsEndPoint": {           "Url": "https://*:9001",           "ClientCertificateMode": "AllowCertificate",           "Certificate": {             "AllowInvalid": false,             "Path": "Keys\\test.p12",             "Password": "1234567890"           }         }       }     },     "KestrelSettings": {       "AddServerHeader": true,       "AllowResponseHeaderCompression": true,       "AllowSynchronousIO": false,       "AllowAlternateSchemes": false,       "DisableStringReuse": false,       "KestrelLimits": {         "KeepAliveTimeout": 130,         "RequestHeadersTimeout": 30,         "MaxConcurrentConnections": null,         "MaxConcurrentUpgradedConnections": null,         "MaxRequestBufferSize": 1048576,         "MaxRequestHeaderCount": 100,         "MaxRequestHeadersTotalSize": 32768,         "MaxRequestLineSize": 8192,         "MaxRequestBodySize": 30000000,         "MaxResponseBufferSize": 65536       },       "KestrelLimits2": {         "MaxStreamsPerConnection": 100,         "HeaderTableSize": 4096,         "MaxFrameSize": 16384,         "MaxRequestHeaderFieldSize": 16384,         "InitialConnectionWindowSize": 131072,         "InitialStreamWindowSize": 98304       },       "KestrelLimits3": {         "MaxRequestHeaderFieldSize": 16384       }     }   } }

2.定义KestrelSettings配置对应的Options类

public class KestrelSettingOptions     {         public bool AddServerHeader { get; set; } = true;         public bool AllowResponseHeaderCompression { get; set; } = true;         public bool AllowAlternateSchemes { get; set; } = false;         public bool DisableStringReuse { get; set; } = false;          public KestrelLimitOptions KestrelLimits { get; set; } = new KestrelLimitOptions();         public KestrelLimit2Options KestrelLimits2 { get; set; } = new KestrelLimit2Options();         public KestrelLimit3Options KestrelLimits3 { get; set; } = new KestrelLimit3Options();     }      public class KestrelLimitOptions     {         public long? MaxConcurrentConnections { get; set; } = null;         public long? MaxConcurrentUpgradedConnections { get; set; } = null;         public int KeepAliveTimeout { get; set; } = 130;         public long? MaxRequestBufferSize { get; set; } = 1048576;         public int MaxRequestHeaderCount { get; set; } = 100;         public int MaxRequestHeadersTotalSize { get; set; } = 32768;         public int MaxRequestLineSize { get; set; } = 8192;         public long? MaxRequestBodySize { get; set; } = 30000000;         public int RequestHeadersTimeout { get; set; } = 30;         public long? MaxResponseBufferSize { get; set; } = 65536;     }     public class KestrelLimit2Options     {         public int MaxStreamsPerConnection { get; set; } = 100;         public int HeaderTableSize { get; set; } = 4096;         public int MaxFrameSize { get; set; } = 16384;         public int MaxRequestHeaderFieldSize { get; set; } = 16384;         public int InitialConnectionWindowSize { get; set; } = 131072;         public int InitialStreamWindowSize { get; set; } = 98304;     }     public class KestrelLimit3Options     {         public int MaxRequestHeaderFieldSize { get; set; } = 16384;     }

3.实现Kestrel服务器的功能

public static void Config(ConfigureWebHostBuilder webhost)         {             switch (AppSetting.Instance.WebServerType)             {                 case "iisexpress":                     break;                 case "kestrel":                     ConfigKestrel(webhost);                     break;                 case "iisintegation":                     ConfigIISIntegation(webhost);                     break;                 default:                     ConfigIIS(webhost);                     break;             }         }          private static void ConfigKestrel(ConfigureWebHostBuilder webhost)         {             webhost.UseKestrel((builderContext, options) =>             {                 options.Configure(builderContext.Configuration.GetSection(ConstFiles.AppSettings_WebServerKestrel), reloadOnChange: true);                 var kso = builderContext.Configuration.GetSection(ConstFiles.AppSettings_WebServerKestrelSettings).Get();                 KestrelSettings(options, kso);             });         }         private static void KestrelSettings(KestrelServerOptions opt, KestrelSettingOptions kso)         {             //settings             opt.AddServerHeader = kso.AddServerHeader;             opt.AllowAlternateSchemes = kso.AllowAlternateSchemes;             opt.AllowResponseHeaderCompression = kso.AllowResponseHeaderCompression;             opt.AllowSynchronousIO = kso.AllowSynchronousIO;             opt.DisableStringReuse = kso.DisableStringReuse;              //http1.x(Text)             opt.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(kso.KestrelLimits.KeepAliveTimeout);             opt.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(kso.KestrelLimits.RequestHeadersTimeout);             opt.Limits.MaxConcurrentConnections = kso.KestrelLimits.MaxConcurrentConnections;             opt.Limits.MaxConcurrentUpgradedConnections = kso.KestrelLimits.MaxConcurrentUpgradedConnections;             opt.Limits.MaxRequestBodySize = kso.KestrelLimits.MaxRequestBodySize;             opt.Limits.MaxRequestBufferSize = kso.KestrelLimits.MaxRequestBufferSize;             opt.Limits.MaxRequestHeaderCount = kso.KestrelLimits.MaxRequestHeaderCount;             opt.Limits.MaxRequestHeadersTotalSize = kso.KestrelLimits.MaxRequestHeadersTotalSize;             opt.Limits.MaxRequestLineSize = kso.KestrelLimits.MaxRequestLineSize;             opt.Limits.MaxResponseBufferSize = kso.KestrelLimits.MaxResponseBufferSize;             //http2.x(Frame|Binary)             opt.Limits.Http2.HeaderTableSize = kso.KestrelLimits2.HeaderTableSize;             opt.Limits.Http2.InitialConnectionWindowSize = kso.KestrelLimits2.InitialConnectionWindowSize;             opt.Limits.Http2.InitialStreamWindowSize = kso.KestrelLimits2.InitialStreamWindowSize;             opt.Limits.Http2.MaxFrameSize = kso.KestrelLimits2.MaxFrameSize;             opt.Limits.Http2.MaxRequestHeaderFieldSize = kso.KestrelLimits2.MaxRequestHeaderFieldSize;             opt.Limits.Http2.MaxStreamsPerConnection = kso.KestrelLimits2.MaxStreamsPerConnection;             //http3.x(QUIC|UDP)             opt.Limits.Http3.MaxRequestHeaderFieldSize = kso.KestrelLimits3.MaxRequestHeaderFieldSize;         }          private static void ConfigIIS(ConfigureWebHostBuilder webhost)         {             webhost.UseIIS();         }         private static void ConfigIISIntegation(ConfigureWebHostBuilder webhost)         {             webhost.UseIISIntegration();         }

IIS配置(InProcess)

从程序代码上说ASP.NET Core项目基于IIS部署运行的配置,就像上述代码中那么简单“webhost.UseIIS();”这么一行代码就可实现,然而实际上并非如此。通过对ASP.NET Core项目编译发布,你会看到生成的文件里有一个web.config文件,这个文件里节点是关键配置项,具体配置内容如下:

                                                                                                  

特别提示:
1)由于ASP.NET Core已经从根本上独立于IIS,此时若想让IIS托管运行,IIS需要安装一个插件ASP.NET Core 模块 (ANCM)

IISIntegation配置(OutOfProcess)

InProcess部署模式属于进程内托管,OutOfProcess部署模式属于进程外托管,通过上述代码可以知晓,其实代码使用和配置文件基本相同,只是个别调用方法和参数配置需要修改,因此不再赘述,请参考上述内容。
 

Https配置

https配置相较于基于IIS的配置变化不小,在ASP.NET 4.x时期https的配置不会在程序代码中操作,现在ASP.NET Core需要在代码中实现。对于一切可以通过配置实现的功能一定要通过配置实现,因为修改程序代码总是一件麻烦事,尤其是在部署运行之后,所以对于Https的配置,也是通过配置的形式实现。
1.在appsettings.json文件中,定义Https的相关配置项

{ "WebServer": {     //服务器类型(IISExpress,Kestrel,IIS,IISIntegation),IIS注意与web.config配合     "WSType": "IISExpress",     "Kestrel": {       "Endpoints": {         "HttpEndPoint": {           "Url": "http://*:9000",           "Protocols": "Http1AndHttp2AndHttp3"         },         "HttpsEndPoint": {           "Url": "https://*:9001",           "ClientCertificateMode": "AllowCertificate",           "Certificate": {             "AllowInvalid": false,             "Path": "Keys\\test.p12",             "Password": "1234567890"           }         }       }     }   },   "WebApplication": {     "HttpsRedirection": true,     "MapController": true   } }

2.依据配置信息决定是否将默认的http请求重定向到https请求

private static void ConfigHttps(WebApplication app)         {             if (AppSetting.Instance.WebApp.HttpsRedirection)             {                 app.UseHttpsRedirection();                 app.UseHsts();             }         }

控制器API

控制器API就是传统的XXXController+Action方式定义的API服务,由于巨硬在ASP.NET Core中推出Minimal API,故而作此说明,但是鉴于Minimal API模式尚未成熟,在生产环境还是建议使用控制器API。在使用依赖注入(DI)时,都是先把服务对象添加到IServiceCollection集合中,然后再使用,所以控制器API也是如此,先通过IServiceCollection.AddControllers方法把你定义的控制器添加到服务集合,然后再调用WebApplication.MapControllers方法将控制器API类中的Action转化成一个个路由终结点,此时外部程序就可以发起请求了。

1.依据配置文件中的定义,判断是否采用了控制器API

  "WebApplication": {     "HttpsRedirection": true,     "MapController": true   }

2.将控制器类添加到服务集合

private static void ConfigControllers(IServiceCollection services)         {             if (AppSetting.Instance.WebApp.MapController)             {                 services.AddControllers();             }         }

3.将控制器类中的Action转化成路由终结点服务

private static void ConfigControllers(WebApplication app)         {             if (AppSetting.Instance.WebApp.MapController)             {                 app.MapControllers();             }         }

总结

经过上述内容可知,web服务器配置变化是比较大的,而且未来还会继续变化,因此,需要重点关注这部分技术的发展和使用。

测试源码:https://gitee.com/kinbor/jks.core.test.webserver

相关内容

热门资讯

安卓手机好的系统,安卓手机操作... 你有没有发现,现在手机市场上的安卓手机真是琳琅满目,让人挑花了眼。不过,你知道吗?在这些安卓手机中,...
安卓系统mac电脑配置,打造安... 亲爱的电脑迷们,你是否曾想过,你的苹果笔记本里也能装上安卓系统?是的,你没听错!今天,就让我带你一起...
状元郎平板安卓系统,引领平板教... 你有没有想过,一款平板电脑,竟然能让你在学习之余,还能畅游安卓世界的海洋?没错,今天我要跟你聊聊的就...
安卓系统哪个传奇好玩,畅玩经典... 手机里的游戏可是咱们休闲娱乐的一大法宝,尤其是安卓系统,那丰富的游戏资源简直让人挑花眼。今天,就让我...
联众支持安卓系统吗,“联众PD... 斗地主爱好者们,是不是在为找不到一款好玩的斗地主游戏而烦恼呢?别急,今天我要给大家揭秘一个好消息——...
康佳电视安卓系统太卡,康佳电视... 亲爱的电视迷们,你们有没有遇到过这样的烦恼:家里的康佳电视用着用着就变得像蜗牛一样慢吞吞的,让人抓狂...
ios对比安卓系统流畅,流畅体... 你有没有发现,用手机的时候,有时候iOS系统就像个优雅的舞者,而安卓系统则像个活力四射的少年?没错,...
安卓系统占用内存小,深度解析优... 你有没有发现,手机用久了,就像人一样,会变得“臃肿”起来?尤其是安卓系统,有时候感觉就像一个超级大胃...
安卓系统怎么下载jdk,JDK... 你有没有想过,在安卓手机上也能编写Java程序呢?没错,就是那种在电脑上写代码的感觉,现在也能在手机...
安卓系统调手机亮度,轻松掌握手... 手机屏幕亮度总是让你眼花缭乱?别急,今天就来手把手教你如何轻松调节安卓系统的手机亮度,让你的手机屏幕...
学习机安卓系统双系统,安卓系统... 你有没有想过,学习机也能玩转安卓系统?没错,就是那个我们平时用来刷剧、玩游戏、看新闻的安卓系统!现在...
安卓系统有哪些兼职,盘点热门兼... 你有没有想过,在手机上也能轻松赚钱呢?没错,就是那个我们每天都离不开的安卓系统,它不仅能让你畅游网络...
别致影音下载安卓系统,轻松享受... 你有没有想过,在这个信息爆炸的时代,找到一款既别致又实用的影音下载APP,简直就像在茫茫人海中找到那...
安卓车机系统和手机系统,共筑智... 你有没有发现,现在汽车也越来越智能了?这不,车机系统都开始流行起来,而且很多车企都选择了安卓系统。那...
爱情银行ios系统与安卓系统,... 亲爱的读者们,今天咱们来聊聊一个让无数人心动的话题——爱情银行iOS系统与安卓系统!想象爱情银行就像...
车载wce系统和安卓系统区别,... 亲爱的车友们,你们有没有想过,为什么你的车载导航有时候会像老牛拉车一样慢吞吞,有时候又像兔子一样活泼...
安卓系统常见app取证,深度解... 你有没有想过,手机里的那些小玩意儿,其实可能藏着大大的秘密呢?没错,就是那些我们每天不离手的安卓系统...
苹果云照片安卓系统,苹果云照片... 你有没有想过,那些在苹果手机上美美哒的照片,怎么才能搬到安卓手机上呢?别急,今天就来给你揭秘这个神奇...
ios系统跟安卓系统都是美国,... iOS与安卓:美国科技的双雄争霸在当今这个数字化的世界里,智能手机已经成为了我们生活中不可或缺的一部...
深度系统可以装安卓,系统兼容安... 亲爱的读者们,你是否曾想过,在电脑上也能畅玩安卓游戏,享受安卓应用带来的便捷?现在,这个梦想成真啦!...