繁体   English   中英

IIS 发布 ASP.NET 核心应用程序而不关闭 IIS 网站

[英]IIS Publish ASP.NET Core App Without Bringing Down IIS Website

当前设置


我们目前将 ASP.NET 核心产品部署到:

  • Windows 服务器 2016
  • 托管在 IIS 版本 10.0.14393.0

我们有一个“站点”,下面有多个应用程序。 每个应用程序都使用自己的应用程序池并映射到不同的物理文件夹路径位置。

每个应用程序都由其自己的源代码 ASP.NET Core Server 项目表示

IIS结构

站点中子应用程序的 IIS 结构

问题


我们的 CI/CD 使用 Jenkins,这是无法更改的。 我们有 Powershell 脚本与 IIS 交互

没有 IIS 命令来停止应用程序,只有站点,但理想情况下,我们不希望在发布单个应用程序的新版本时关闭站点。 我们只想关闭那个特定的应用程序。

我们通过停止与应用程序关联的 WebAppPool 来尝试此操作,然后等待(2 分钟......然后 5 分钟)。 但即使在那之后,应用程序文件仍然被锁定。

我们最终关闭了 WebAppPool 和站点以释放文件,以便可以替换它们。

我知道必须有更好的方法来做到这一点。 我们如何关闭单个应用程序并阻止新请求到达它,以便我们可以替换文件然后重新启动它? 一直以来,“SITE”及其下未更新的任何其他应用程序仍在运行。 我不介意更新应用程序的停机时间。

2022 年 6 月 8 日更新

找到这个: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/app-offline?view=aspnetcore-6.0

去看看这是否能解决我的问题。

在应用程序的根文件夹中添加名为 app_offline.htm 的文件应该会强制 ASP.NET Core 模块关闭应用程序并停止处理传入请求。 然后,您应该能够在不影响其他应用程序的情况下部署新文件。

我强烈建议使用带有 IIS 的Web 部署 设置起来有点麻烦,但是一旦配置好,它就真的很好用。

如果您以这种方式发布,它将自动执行以下操作:

  • 继续接受传入的请求,但暂停它们
  • 优雅地停止旧版本的应用程序
  • 回收应用程序池
  • 启动新版本的应用程序
  • 暂停的请求将恢复到新版本的应用程序

此解决方案使您能够部署新版本,而不会对您的服务造成明显的中断,而其他解决方案可能会在发布期间使您的服务无法访问。

我只使用了 Visual Studio 的发布菜单,但应该可以通过调用 msbuild.exe 的 CI/CD 脚本使其工作,如此处所述 (链接描述了 TeamCity 的灵魂,但应该可以适应 Jenkins)

我以前成功地将 IIS 中的站点指向符号链接。 然后,符号链接又指向一个包含网页内容的文件夹。

每当我必须更新网页时,我都会创建一个新文件夹,将其命名为webpage_date,然后更新符号链接并将其指向新文件夹。 最后我回收了负责网页的 AppPool。

所以它会去:

符号链接 -> 网页_1

将带有更新网页的文件夹放在旁边,称为webpage_2。 指向它的符号链接:

符号链接 -> 网页_2

然后回收 AppPool。

这使得停机时间非常短。

重启 WebAppPool 的 Powershell 命令:

Restart-WebAppPool -Name "YourAppPool"

重启-WebAppPool 文档

可以使用创建符号链接

New-Item -ItemType SymbolicLink -Path .\link -Target .\Notice.txt

Powershell 新项目符号链接文档

这是我使用蓝/绿策略的方法:

首先,我在服务器上创建了这个文件夹结构:

 D:\inetpub\wwwroot\MyAppPath\ Staging Green Blue

接下来,在 IIS 中,我将应用程序的物理路径指向 D:\inetpub\wwwroot\MyAppPath\Green

然后我创建了 D:\inetpub\wwwroot\MyAppPath\SetAppPath.ps1

($curPath = Get-WebFilePath -PSPath "IIS:\Sites\www.example.com\MyApp")
if ($curPath -like "*Blue*") {
    Copy-Item -Path "D:\inetpub\wwwroot\MyAppPath\Staging\*" -Destination "D:\inetpub\wwwroot\MyAppPath\Green" -Recurse -Force
    Set-ItemProperty IIS:\Sites\www.example.com\MyApp -name physicalPath -value "D:\inetpub\wwwroot\MyAppPath\Green"
} else {
    Copy-Item -Path "D:\inetpub\wwwroot\MyAppPath\Staging\*" -Destination "D:\inetpub\wwwroot\MyAppPath\Blue" -Recurse -Force
    Set-ItemProperty IIS:\Sites\www.example.com\MyApp -name physicalPath -value "D:\inetpub\wwwroot\MyAppPath\Blue"
}

然后,我创建了一个没有运行 SetAppPath.ps1 的触发器的任务 (SetMyAppPath)

在我的开发工作站上,我在项目根目录中创建了 deploy.ps1:

param ($buildType)
net use r: /delete
dotnet publish --configuration $buildType
net use R: "\\111.222.333.444\d`$" /user:"MyAdminUser" "MyAdminPassword"
Copy-Item -Path "C:\Users\MyUser\Dir1\Dir2\Dir3\MyProject\bin\$buildType\netcoreapp3.1\publish\*"  -Exclude web.config,appsettings.json,appsettings.Development.json -Destination "R:\inetpub\wwwroot\MyAppPath\Staging" -Recurse -Force
schtasks /RUN /S \\111.222.333.444 /U MyAdminUser /P MyAdminPassword /tn SetMyAppPath
net use r: /delete

然后,为了部署,我运行。\Deploy Debug 或.\Deploy Release

因此,当我准备好部署新版本时,会将文件复制到服务器上的暂存文件夹中。 然后,服务器上的任务被触发,该任务将暂存文件复制到绿色或蓝色文件夹,该文件夹不是当前文件夹。

最后,应用程序路径将更新为绿色或蓝色文件夹,这不是当前文件夹。

奇迹般有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM