IIS - w3wp.exe 프로세스의 ASP.NET 런타임을 항상 Warmup 모드로 유지하는 preload Enabled 설정
IIS 7.5부터,
IIS 7.5부터 지원되는 웹 사이트 자동 시작 모드
; https://www.sysnet.pe.kr/2/0/1367
iisreset이나 작업자 프로세스의 recycle 등이 발생했을 때 w3wp.exe를 자동으로 로드하고 닷넷 런타임까지 초기화하는 것이 가능했습니다. 이에 대해 다음과 같이 간략하게 정리할 수 있는데요,
- AppPool의 "Start Mode" == AlwaysRunning 옵션 제공
- Auto Start Provider: IProcessHostPreloadClient를 구현한 모듈을 serviceAutoStartProviders 노드에 등록
AppPool의 Start mode는 w3wp.exe의 네이티브 상태만 초기화시키는 것이고, "Auto Start Provider"는 ASP.NET 런타임 및 내부 코드의 역할에 따른 추가 초기화가 가능합니다.
하지만, "Auto Start Provider"는 은근히 사전 단계를 필요로 하기 때문에 불편한 것이 사실입니다. 바로 그런 번거로움을 IIS 8을 사용하면 해결됩니다.
이런 문제가 (
Windows Server 2012부터 적용된) IIS 8.0의 "Application Initialization"에서 해결이 됩니다.
IIS 8.0 Application Initialization
; https://learn.microsoft.com/en-us/iis/get-started/whats-new-in-iis-8/iis-80-application-initialization
Auto Application Inialization (Preload) on IIS
; https://abhimantiwari.github.io/blog/Application-Initialization/
Application Initialization은, IIS 8.0부터 MMC 화면에서 다음과 같이 "웹 사이트" 레벨로 설정하는 것을 지원합니다.
위의 설정을 추가하면 "%WINDIR%\system32\inetsrv\config\applicationHost.config" 파일에는 해당 사이트에 대해 preloadEnabled 설정이 추가됩니다.
<site name="app1" id="2">
<application path="/" applicationPool="app1" preloadEnabled="true">
<virtualDirectory path="/" physicalPath="D:\webapps\app1" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:18000:" />
</bindings>
</site>
이로 인해, 이후 w3wp.exe가 (AppPool의 "Start Mode" == AlwaysRunning 옵션의 영향으로) 로드되면 IIS는 자동으로 "/" 경로에 대해 요청을 하나 전달합니다. 따라서, IIS 8.0부터는 다음의 2가지 설정만으로,
- AppPool의 "Start Mode" == AlwaysRunning
- Web Site의 preload Enabled == "True"
w3wp.exe를 항상 실행 상태로 두면서 ASP.NET 런타임의 초기화까지 마친 상태를 유지할 수 있습니다. 한 마디로, Cold start 타임을 획기적으로 줄일 수 있는 것입니다.
참고로, 원한다면 추가 요청을 발생하는 것도 쉽게 설정이 가능합니다. 이런 설정은 Web Application의 "web.config" 파일에,
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- 생략 -->
<system.webServer>
<!-- 생략 -->
<applicationInitialization>
<add initializationPage="/api/Values" />
</applicationInitialization>
</system.webServer>
<!-- 생략 -->
</configuration>
applicationInitialization 노드를 추가해 add/@initializationPage로 발생시키고자 하는 경로를 명시하면 됩니다. 위와 같이 설정한 경우에는, "/" 요청과 함께 "/api/Values"가 함께 발생하는 것입니다.
이 정도면, 최초 요청에 대한 응답 시간문제를 해결하기 위해 굳이 AOT 빌드까지 해야 할 것인가에 대한 고민의 무게를 많이 덜어 줄 것입니다. ^^
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]