前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ASP.NET Core 2.2使用IIS部署要注意的路径问题

ASP.NET Core 2.2使用IIS部署要注意的路径问题

作者头像
Edi Wang
发布2019-07-15 11:49:47
2.9K0
发布2019-07-15 11:49:47
举报
文章被收录于专栏:汪宇杰博客

ASP.NET Core 2.2 推出已经有一段时间了,其中有个新功能,能够使用新的AspNetCoreModuleV2并且在IIS上使用InProcess模式部署,以大幅提高性能。这几天Azure App Service终于完成了这个新版模块的部署,我第一时间将我的博客配置到新模块上,结果爆了。我们来看看原因和解决方式。

如果不知道什么是InProcess模式的话,简单来说,就是原先ASP.NET Core确实可以跑在IIS上,但其实是由一个名为AspNetCoreModule的IIS模块调用dotnet.exe启动kestrel来跑的,所以进程名字实际上是dotnet.exe。

而ASP.NET Core 2.2里新增了InProcess模式,可以在IIS自己的w3wp进程中跑你的应用。这个InProcess的In也就是In在了w3wp里的意思。据官网的描述,这种运行方式可以有400%的性能提升。

有兴趣可以看看官网的详细介绍:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/index?view=aspnetcore-2.2&tabs=windows#in-process-hosting-model

生产环境大爆炸

根据原先对ASP.NET Core的了解,我开发时候一般不会使用IIS去测试,用kestrel在开发环境测完以后直接使用Azure DevOps部署到Azure App Service上跑,结果今天升级到InProcess模式以后,生产环境爆了,而开发机的kestrel怎么弄都是好的。

启动失败,我的整个博客网站无法访问,好牛逼啊!

故障分析

还好微软智慧云Azure提供的全球独一无二的kudu工具可以非常方便的看到日志,日志显示:

[2018-12-26 12:06:26.5616][RD00155DB8C92A][Fatal][Microsoft.AspNetCore.Hosting.Internal.WebHost] Application startup exception System.IO.FileNotFoundException: Could not find file 'D:\Windows\system32\urlrewrite.xml'.

File name: 'D:\Windows\system32\urlrewrite.xml'

怎么会这样?我的代码访问的明明是应用根目录下的文件,为何跑到系统目录去了?再一看启动日志:

[2018-12-26 12:06:23.7946][RD00155DB8C92A][Info][Moonglade.Web.Program] Moonglade is starting, hail Microsoft!

--------------------------------------------------------

Version: 10.0.6934.1000

Directory: D:\Windows\system32

x64Process: True

OSVersion: Microsoft Windows 10.0.14393

AppDomain: Moonglade.Web

UserName: moonglade

--------------------------------------------------------

故障代码是这段:

using (var sr = File.OpenText("urlrewrite.xml"))

{

...

}

最终发现,在Kestrel下运行的时候,Environment.CurrentDirectory指向的是应用根目录,而在IIS的InProcess模式下运行的时候,则指向系统目录,最终导致应用里只要间接或直接使用Environment.CurrentDirectory的代码,都会爆。

解决办法

我们可以利用IHostingEnvironment接口里提供的ContentRootPath属性来获取当前应用目录的绝对路径,这是在Kestrel和IIS中行为一致的。我的故障代码正好位于可以访问到IHostingEnvironment的地方,因此做如下修改:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

string baseDir = env.ContentRootPath;

using (var sr = File.OpenText(Path.Combine(baseDir, "urlrewrite.xml")))

{

...

}

}

对于没法直接访问IHostingEnvironment又懒得做依赖注入的地方,可以这么玩:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

string baseDir = env.ContentRootPath;

...

AppDomain.CurrentDomain.SetData(Constants.AppBaseDirectory, baseDir);

}

然后在要用的地方GetData()就好了:

var configSource = $@"{AppDomain.CurrentDomain.GetData(Constants.AppBaseDirectory)}\mailConfiguration.xml";

再次部署上线,问题成功解决!

其他注意事项

如果你在VS里使用IIS去debug,比如这样设置的话:

会产生一个debug配置的web.config文件,而这个文件在默认情况下会参与你CI/CD环境的编译和发布,最终导致你指定用release模式编译的网站,上线之后是debug标记的。一定记得要手工排除这个文件。

ASP.NET Core 2.2 以后,再也不能想当然地认为开发ASP.NET Core 用不用IIS都无所谓了,真的是有些东西在IIS和Kestrel下行为不一致,因此推荐大家如果生产环境在使用IIS的话,上线之前务必在本地的IIS上用同样配置测试一遍

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 汪宇杰博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
CODING DevOps
CODING DevOps 一站式研发管理平台,包括代码托管、项目管理、测试管理、持续集成、制品库等多款产品和服务,涵盖软件开发从构想到交付的一切所需,使研发团队在云端高效协同,实践敏捷开发与 DevOps,提升软件交付质量与速度。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档