前言
我們有一個系統是使用 NodeJS ,同事 Stan 使用 PuppeteerSharp 同時起多個 Chrome 來測試它。
結果一下子 IIS Node 就沒反應了,一整個 Hang 住。
研究
想說怎麼跑個沒幾次就掛了呢? 結果發現我們有一段程式,在呼叫 API 時,會等 API 回來,再回給 Client 。例如,
1 | const express = require('express'); |
雖然在 ASP.NET API 中,常常寫 await 之後,再將結果回給 Client 。
但透過 iisnode 來執行,壓個幾次,就會導致 iisnode hang 住。
因為這部份的程式,我們並不需要等待 api 的結果,所以就先將內容回給 Client 後,再執行 Call API 的 Task。
調整後,再來測試, iisnode 就不會 hang 住了。
但啟用 webscoket 後,再壓個幾次,又發生 iisnode hang 住的問題。
試了後久,後來查到 IIS stops serving content with iisnode and socket.io #268 有提到 Windows 8 有 Http Request 10 個的限制,當啟用了 WebScoket 之後是一直連接著,所以會導致後面的 Request 被 Block 住。 將環境改到 Windows Server 來測試, WebScoket 也沒問題了。
如果有 timeout 問題也可以試著調整 maxNamedPipeConnectionRetry 與 namedPipeConnectionRetryDelay 的設定值。
備用方案就是使用 Reverse Proxy 的方式,可以參考 Hosting a Node.js application on Windows with IIS as reverse proxy。
使用 iisnode 下,可以儘快 Response 就儘快 Respose。測試 WebScoket 時,請記得使用 Windows Server 來壓測哦!
參考資料
IIS stops serving content with iisnode and socket.io #268
Does IISnode timeout the Http Request #555
Hosting a Node.js application on Windows with IIS as reverse proxy
Unable to increase the node server timeout beyond 2 minute mark when using IISNode #558