为什么 node.js 在服务器重启后不加载网站?
Why node.js does not load website after a server restart?
我使用 Windows Server Standard 2019 来托管 Angular 11 Universal with ASP.net Core 3.1.1 网站。在服务器重新启动之前,该网站运行良好。我做了很多测试以确保 angular 应用程序没有内存泄漏或错误,一切都绝对完美。然后我不得不重新启动服务器以安装一些 windows 更新,然后网站就不再工作了。它会无限加载。
问题是如果我在后台进程which运行服务器重启后立即刷新网站,Node会启动一个新进程,网站会正常运行,直到下一次服务器重启。我做了很多其他测试来找到特定的案例场景。
所以,我不确定如何解决这个问题。自然地,我希望网站在服务器重启后立即运行,而无需我这边的任何干预。以下是我认为应该有助于解决问题的文件和配置,如果您需要其他信息,请告诉我:
网站文件夹结构:
- dist(文件夹)
- iisnode(文件夹)
- main.js
- node_start.cmd
- Web.config
我先安装了 nodejs 14.16.0 LTS,然后是 15.11.0 Current 以及 Url 重写 2.1 和 iisnode-full-v0.2.21-x64
IIS 是版本 10。我尝试将应用程序池设置为:
- 立即启动应用程序池
- 启动模式:AlwaysRunning
- 空闲超时操作:挂起
- 最大工作进程数:0
- 启用预加载:真
当我在后台关闭 Node.js JavasScript Runtime 时,我重复网站按预期工作,服务器重新启动后 运行 然后点击刷新访问网站。最后,该网站使用有效的 SSL 证书。
这里是node_start.cmd
的内容
cd "C:\inetpub\wwwroot\championstogether" "C:\Program
Files\nodejs\node.exe" "C:\inetpub\wwwroot\championstogether\main.js"
然后Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="StaticFilesCss" path="*.css" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFilesPng" path="*.png" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="iisnode" path="main.js" verb="*" modules="iisnode" responseBufferLimit="0" />
</handlers>
<iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe --no-deprecation --no-warnings"
flushResponse="false"
promoteServerVars="HTTP_UID,HTTP_PUBCOOKIE_USER,LOGON_USER,HTTP_SHIBSESSIONID"
node_env="production"
nodeProcessCountPerApplication="0"
debugHeaderEnabled="false"
devErrorsEnabled="false"
gracefulShutdownTimeout="60000"
maxConcurrentRequestsPerProcess="1024"
maxNamedPipeConnectionRetry="100"
namedPipeConnectionRetryDelay="250"
maxNamedPipeConnectionPoolSize="512"
maxNamedPipePooledConnectionAge="30000"
asyncCompletionThreadCount="0"
initialRequestBufferSize="4096"
maxRequestBufferSize="65536"
uncFileChangesPollingInterval="5000"
loggingEnabled="true"
logDirectory="iisnode"
debuggingEnabled="true"
debuggerPortRange="5058-6058"
debuggerPathSegment="debug"
maxLogFileSizeInKB="128"
maxTotalLogFileSizeInKB="1024"
maxLogFiles="20"
enableXFF="false"
configOverrides="iisnode.yml"
watchedFiles="web.config;*.js;routes\*.js;views\*.pug"/>
<rewrite>
<rules>
<rule name="DynamicContent">
<match url="/*" />
<action type="Rewrite" url="main.js" />
</rule>
<rule name="StaticContent" stopProcessing="true">
<match url="([\S]+[.](jpg|jpeg|gif|css|png|js|ts|cscc|less|ico|html|map|svg))" />
<action type="None" />
</rule>
<rule name="SocketIO" patternSyntax="ECMAScript">
<match url="socket.io.+"/>
<action type="Rewrite" url="main.js"/>
</rule>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^main.js\/debug[\/]?"/>
</rule>
</rules>
</rewrite>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<modules runAllManagedModulesForAllRequests="false" />
<staticContent>
<clientCache cacheControlMode="UseMaxAge" />
<remove fileExtension=".svg" />
<remove fileExtension=".eot" />
<remove fileExtension=".ttf" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<remove fileExtension=".otf" />
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".woff" mimeType="application/x-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/x-woff" />
<mimeMap fileExtension=".otf" mimeType="application/otf" />
</staticContent>
</system.webServer>
</location>
</configuration>
感谢您的帮助,
萨曼莎
萨曼莎 -
根据您的 web.config
文件,我发现您正在使用 iisnode
模块。 iisnode
模块实际上有一个错误,需要在服务器重新启动后手动重新启动 Node.js 进程,据我所知,从未最终开发出修复程序。
尽管 Microsoft 现在拥有代码,但他们并未创建代码,也没有积极维护代码。坦率地说,我很惊讶他们还没有发布关于弃用的官方通知。
IIS 上 运行 node.js
应用程序的替代选项是使用 ARR(反向代理)模块或 HttpPlatformHandler
模块。 ARR 非常通用;它不支持 Node.js 特定变量,甚至不支持在 web.config
.
中使用 Node 的规范
我的建议是使用 HttpPlatformHandler
模块,它可以管理任何进程,包括 Node,以及进出父进程的任何代理请求。虽然基本上仍然是反向代理,但可以为 node.js
进程配置此模块。 web.config
应该看起来像这样。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="main.js" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath="C:\Program Files\nodejs\node.exe"
arguments=""
startupTimeLimit=20
startupRetryCount=10
rapidFailsPerMinute=10
requestTimeout="00:02:00"
stdoutLogEnabled=true
stdoutLogFile="httpplatform-stdout"
processesPerApplication=0
forwardWindowsAuthToken=false>
<environmentVariables>
<environmentVariable name="PORT" value="%HTTP_PLATFORM_PORT%" />
<environmentVariable name="NODE_ENV" value="Production" />
</environmentVariables>
</httpPlatform>
// add the config details for the rest of your module here
</system.webServer>
</configuration>
ADDITIONAL REFERENCES --
Official
社区
根据@killshot13 的回答,我让 nodejs 与 HttpPlatformHandler 一起工作。服务器重启后第一次加载网站可能需要 3 分钟。我对无法使用 nodeProcessCountPerApplication="0" 或 flushResponse="false" 配置 nodejs 感到有点失望,但也许其他人知道怎么做。
答案在这里:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" requireAccess="Script" />
</handlers>
<httpPlatform
arguments=".\main.js"
stdoutLogEnabled="true"
stdoutLogFile=".\node.log"
startupTimeLimit="20"
startupRetryCount="10"
rapidFailsPerMinute="10"
requestTimeout="00:02:00"
processesPerApplication="2"
processPath="C:\Program Files\nodejs\node.exe --no-deprecation --no-warnings">
<environmentVariables>
<environmentVariable name="PORT" value="%HTTP_PLATFORM_PORT%" />
<environmentVariable name="NODE_ENV" value="production" />
</environmentVariables>
</httpPlatform>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<modules runAllManagedModulesForAllRequests="false" />
<staticContent>
<clientCache cacheControlMode="UseMaxAge" />
<remove fileExtension=".svg" />
<remove fileExtension=".eot" />
<remove fileExtension=".ttf" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<remove fileExtension=".otf" />
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".woff" mimeType="application/x-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/x-woff" />
<mimeMap fileExtension=".otf" mimeType="application/otf" />
</staticContent>
</system.webServer>
</location>
<system.webServer>
<defaultDocument>
<files>
<clear />
<add value="index.html" />
<add value="index.htm" />
<add value="iisstart.htm" />
<add value="default.aspx" />
</files>
</defaultDocument>
</system.webServer>
</configuration>
我使用 Windows Server Standard 2019 来托管 Angular 11 Universal with ASP.net Core 3.1.1 网站。在服务器重新启动之前,该网站运行良好。我做了很多测试以确保 angular 应用程序没有内存泄漏或错误,一切都绝对完美。然后我不得不重新启动服务器以安装一些 windows 更新,然后网站就不再工作了。它会无限加载。
问题是如果我在后台进程which运行服务器重启后立即刷新网站,Node会启动一个新进程,网站会正常运行,直到下一次服务器重启。我做了很多其他测试来找到特定的案例场景。
所以,我不确定如何解决这个问题。自然地,我希望网站在服务器重启后立即运行,而无需我这边的任何干预。以下是我认为应该有助于解决问题的文件和配置,如果您需要其他信息,请告诉我:
网站文件夹结构:
- dist(文件夹)
- iisnode(文件夹)
- main.js
- node_start.cmd
- Web.config
我先安装了 nodejs 14.16.0 LTS,然后是 15.11.0 Current 以及 Url 重写 2.1 和 iisnode-full-v0.2.21-x64
IIS 是版本 10。我尝试将应用程序池设置为:
- 立即启动应用程序池
- 启动模式:AlwaysRunning
- 空闲超时操作:挂起
- 最大工作进程数:0
- 启用预加载:真
当我在后台关闭 Node.js JavasScript Runtime 时,我重复网站按预期工作,服务器重新启动后 运行 然后点击刷新访问网站。最后,该网站使用有效的 SSL 证书。
这里是node_start.cmd
的内容cd "C:\inetpub\wwwroot\championstogether" "C:\Program Files\nodejs\node.exe" "C:\inetpub\wwwroot\championstogether\main.js"
然后Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="StaticFilesCss" path="*.css" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFilesPng" path="*.png" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="iisnode" path="main.js" verb="*" modules="iisnode" responseBufferLimit="0" />
</handlers>
<iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe --no-deprecation --no-warnings"
flushResponse="false"
promoteServerVars="HTTP_UID,HTTP_PUBCOOKIE_USER,LOGON_USER,HTTP_SHIBSESSIONID"
node_env="production"
nodeProcessCountPerApplication="0"
debugHeaderEnabled="false"
devErrorsEnabled="false"
gracefulShutdownTimeout="60000"
maxConcurrentRequestsPerProcess="1024"
maxNamedPipeConnectionRetry="100"
namedPipeConnectionRetryDelay="250"
maxNamedPipeConnectionPoolSize="512"
maxNamedPipePooledConnectionAge="30000"
asyncCompletionThreadCount="0"
initialRequestBufferSize="4096"
maxRequestBufferSize="65536"
uncFileChangesPollingInterval="5000"
loggingEnabled="true"
logDirectory="iisnode"
debuggingEnabled="true"
debuggerPortRange="5058-6058"
debuggerPathSegment="debug"
maxLogFileSizeInKB="128"
maxTotalLogFileSizeInKB="1024"
maxLogFiles="20"
enableXFF="false"
configOverrides="iisnode.yml"
watchedFiles="web.config;*.js;routes\*.js;views\*.pug"/>
<rewrite>
<rules>
<rule name="DynamicContent">
<match url="/*" />
<action type="Rewrite" url="main.js" />
</rule>
<rule name="StaticContent" stopProcessing="true">
<match url="([\S]+[.](jpg|jpeg|gif|css|png|js|ts|cscc|less|ico|html|map|svg))" />
<action type="None" />
</rule>
<rule name="SocketIO" patternSyntax="ECMAScript">
<match url="socket.io.+"/>
<action type="Rewrite" url="main.js"/>
</rule>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^main.js\/debug[\/]?"/>
</rule>
</rules>
</rewrite>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<modules runAllManagedModulesForAllRequests="false" />
<staticContent>
<clientCache cacheControlMode="UseMaxAge" />
<remove fileExtension=".svg" />
<remove fileExtension=".eot" />
<remove fileExtension=".ttf" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<remove fileExtension=".otf" />
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".woff" mimeType="application/x-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/x-woff" />
<mimeMap fileExtension=".otf" mimeType="application/otf" />
</staticContent>
</system.webServer>
</location>
</configuration>
感谢您的帮助,
萨曼莎
萨曼莎 -
根据您的 web.config
文件,我发现您正在使用 iisnode
模块。 iisnode
模块实际上有一个错误,需要在服务器重新启动后手动重新启动 Node.js 进程,据我所知,从未最终开发出修复程序。
尽管 Microsoft 现在拥有代码,但他们并未创建代码,也没有积极维护代码。坦率地说,我很惊讶他们还没有发布关于弃用的官方通知。
IIS 上 运行 node.js
应用程序的替代选项是使用 ARR(反向代理)模块或 HttpPlatformHandler
模块。 ARR 非常通用;它不支持 Node.js 特定变量,甚至不支持在 web.config
.
我的建议是使用 HttpPlatformHandler
模块,它可以管理任何进程,包括 Node,以及进出父进程的任何代理请求。虽然基本上仍然是反向代理,但可以为 node.js
进程配置此模块。 web.config
应该看起来像这样。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="main.js" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath="C:\Program Files\nodejs\node.exe"
arguments=""
startupTimeLimit=20
startupRetryCount=10
rapidFailsPerMinute=10
requestTimeout="00:02:00"
stdoutLogEnabled=true
stdoutLogFile="httpplatform-stdout"
processesPerApplication=0
forwardWindowsAuthToken=false>
<environmentVariables>
<environmentVariable name="PORT" value="%HTTP_PLATFORM_PORT%" />
<environmentVariable name="NODE_ENV" value="Production" />
</environmentVariables>
</httpPlatform>
// add the config details for the rest of your module here
</system.webServer>
</configuration>
ADDITIONAL REFERENCES --
Official
社区
根据@killshot13 的回答,我让 nodejs 与 HttpPlatformHandler 一起工作。服务器重启后第一次加载网站可能需要 3 分钟。我对无法使用 nodeProcessCountPerApplication="0" 或 flushResponse="false" 配置 nodejs 感到有点失望,但也许其他人知道怎么做。
答案在这里:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" requireAccess="Script" />
</handlers>
<httpPlatform
arguments=".\main.js"
stdoutLogEnabled="true"
stdoutLogFile=".\node.log"
startupTimeLimit="20"
startupRetryCount="10"
rapidFailsPerMinute="10"
requestTimeout="00:02:00"
processesPerApplication="2"
processPath="C:\Program Files\nodejs\node.exe --no-deprecation --no-warnings">
<environmentVariables>
<environmentVariable name="PORT" value="%HTTP_PLATFORM_PORT%" />
<environmentVariable name="NODE_ENV" value="production" />
</environmentVariables>
</httpPlatform>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<modules runAllManagedModulesForAllRequests="false" />
<staticContent>
<clientCache cacheControlMode="UseMaxAge" />
<remove fileExtension=".svg" />
<remove fileExtension=".eot" />
<remove fileExtension=".ttf" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<remove fileExtension=".otf" />
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".woff" mimeType="application/x-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/x-woff" />
<mimeMap fileExtension=".otf" mimeType="application/otf" />
</staticContent>
</system.webServer>
</location>
<system.webServer>
<defaultDocument>
<files>
<clear />
<add value="index.html" />
<add value="index.htm" />
<add value="iisstart.htm" />
<add value="default.aspx" />
</files>
</defaultDocument>
</system.webServer>
</configuration>