眾所周知,當我們使用IIS的時候,在使用負載均衡的情況下,想停掉一個站點,通常會點擊Sites(網站)中的Stop(停止)來停止一個站點。但是這樣做,會帶來一個問題,當點擊Stop(停止)時,正在響應中的請求會立刻被切斷,使客戶端無法收到響應,后續(xù)也無法連接該站點,在某些業(yè)務場景中,比如涉及金額交易業(yè)務,在沒有使用冪等,鎖等手段的情況下,強行切斷的請求后,客戶端不知道該交易的交易情況,如果再次請求(因為本站點已停止,負載均衡會指向其他機器)會造成重復交易,如果不請求,客戶端也不能確切的知道該交易已經成功。類似微服務中,服務間請求超時的情況。
熟悉IIS的讀者通常不會直接停止站點,而會選擇點擊Application Pools(應用程序池)中的Stop(停止)來停止一個站點,應用程序池在被停止后,新的請求會被響應503,負載均衡識別到503后,會把該請求負載到其他機器上,以保證業(yè)務不會中斷。同樣的問題,當點擊Stop(停止)停止時,正在響應的請求,會發(fā)生什么情況呢。有經驗的開發(fā)/運維會回答,在Application Pools(應用程序池)里Advanced Settings(高級設置)中Process Model(進程模型)組包含一個Shutdown Time Limit(關閉時間限制)選項,默認值為90s。這就意味著當應用程序池停止、回收時,IIS會最多等待沒響應的請求90s,如果90s內,所有的請求響應完畢,應用程序池就會被停止、回收。那么如何判斷IIS在這90s內未響應請求是否全部被響應呢,如果部署的程序是ASP.NET Core,可以在Event Viewer(事件查看器)/Windows Logs(Windows 日志)/Application(應用程序)里查看事件日志,如果出現Failed to gracefully shutdown application 'MACHINE/WEBROOT/APPHOST/xxx'.這個警告,則表明存在請求沒有被響應,被IIS強行關閉的情況。
事與愿違,在實際生產實踐中,讀者會發(fā)現IIS并沒有"等待"90s,就會關掉連接,而客戶端還在傻傻等待90s后才會顯示無響應,造成正在請求的HTTP無法響應。通過閱讀[官方文檔](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-8.0#ihostapplicationlifetime ".NET Generic Host in ASP.NET Core")我們得知,等ASP.NET Core收到關閉信號時,對于正在處理的HTTP請求,會等待5s,5s之后會像IIS那樣關閉連接。所以我們需要設置HostOptions
var builder = WebApplication.CreateBuilder(args);
......
builder.Services.Configure<HostOptions>(options =>
{
//If the timeout period expires before all of the hosted services stop, any remaining active services are stopped when the app shuts down. The services stop even if they haven't finished processing. If services require more time to stop, increase the timeout.
//Default: 5 seconds
options.ShutdownTimeout = TimeSpan.FromSeconds(30);
});
......
按照文檔修改程序后,實際測試發(fā)現,設置.NET Generic Host的ShutdownTimeout"似乎"不生效, 在改動前由于IIS的Shutdown Time Limit默認是90s ,ASP.NET Core中ShutdownTimeout默認值是5s,所以在改動前IIS站點會最多等待正在請求的HTTP 5s 在改動后,筆者把.NET Generic Host的ShutdownTimeout調整至30s后,實測下來發(fā)現點擊停止應用程序池后,竟然只能等正在請求中的HTTP 10s ! 于是再次搜索資料,終于發(fā)現還有一個參數需要設置-> https://stackoverflow.com/questions/51634638/graceful-shutdown-of-ihostedservice 和官方文檔[地址](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-3.1#attributes-of-the-aspnetcore-element "ASP.NET Core Module (ANCM) for IIS") 在最近的文檔(.NET 8)里竟然把Attributes of the aspNetCore element這一節(jié)刪掉(移走)了,導致查閱最新文檔,根部搜索不到所需信息,接下來按照文檔操作就十分簡單了,加上shutdownTimeLimit屬性,修改web.config如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2"
resourceType="Unspecified" />
</handlers>
<aspNetCore shutdownTimeLimit="30" processPath="dotnet" arguments=".\WebApplicationTest.dll" stdoutLogEnabled="true"
stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
修改后,再次實測,即符合預期,在使用ASP.NET Core的情況下關于shutdownTime總結(省流)如下:
IIS應用程序池shutdownTime默認值為90s
AspNetCoreModuleV2shutdownTime默認值為10s
.NET Generic Host(應用程序)默認值為5s
如要修改shutdownTime則需同時關注以上三處設置。祝您使用愉快!
?文章來源:http://www.zghlxwxcb.cn/news/detail-747865.html
聲明
本文采用知識共享署名-非商業(yè)性使用-相同方式共享 2.5 中國大陸許可協議進行許可,發(fā)表在CSDN和博客園,歡迎讀者轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接!請讀者/爬蟲們尊重版權
文章來源地址http://www.zghlxwxcb.cn/news/detail-747865.html
到了這里,關于如何優(yōu)雅的關閉一個IIS站點的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!