资讯动态

Node.js 部署到 IIS 完整指南:iisnode 配置、web.config 与排障实战

发布时间:2026/10/2 9:42:50 来源:尧图企业网站定制
你们是不是也遇到过这种情况Node.js 项目在本地npm start跑得好好的一到 Windows 服务器上就不知道怎么“正规化”地跑起来。双击node app.js确实能起服务但终端一关整个服务就没了服务器重启一次又得手动拉起来运维的人要是稍微马虎一点线上就静悄悄挂了。把 Node.js 部署到 IIS 上恰恰是很多 .NET 团队、传统运维在 Windows 环境里最顺手也最刚需的方案。IIS 本身有进程托管、自动重启、日志、权限隔离、域名绑定这些现成能力还能跟 Windows 认证、AD 域控配合比裸跑一个node进程可控得多。但这个东西网上教程鱼龙混杂要么太旧要么只说一半照着抄完还是 502、404、empty reply、PowerShell 执行策略报错……我前前后后在 Windows Server 2016/2019/2022 上都折腾过这篇就把每个环节拆到最细从装 Node.js 到建站点到 web.config 逐行解释再到部署后必踩的坑和排查链路一次性讲清楚。1. 为什么要用 IIS 托管 Node.js而不是直接跑命令行1.1 裸跑 Node 进程的四个痛点很多人觉得 “IIS 是跑 ASP.NET 的Node.js 自己就能监听端口何必绕一圈”。这话在开发环境没问题但到了生产环境裸跑 Node 进程的缺点就非常明显。首先是进程守护缺失。Node.js 进程一旦因为未捕获异常崩溃没有人帮你把它拉起来。你要么写一个 Windows 计划任务定时检查端口要么装 pm2 这种进程管理器但这又多了一个要维护的组件。IIS 自带的应用程序池本身就具备进程回收、自动重启机制进程死了它会按配置重新拉起 Worker Process。其次是日志和监控分裂。Node 应用自己打的日志、IIS 的请求日志、Windows 事件日志三套东西各管各的。排障时要来回切换上下文效率很低。托管到 IIS 之后所有的 HTTP 请求日志统一走 IIS应用的 stdout/stderr 可以统一重定向到 iisnode 的日志目录排查链路就顺了。第三是端口管理和防火墙策略。裸跑 Node 通常监听 3000/8080 这种端口和 IIS 的 80/443 是两套体系。运维要额外开防火墙端口还容易和别人部署的服务端口冲突。用 iisnode 托管后Node 应用不需要自己监听公网端口IIS 直接通过命名管道把请求转发给 Node 进程外部访问依然走 80/443防火墙规则完全不用变。第四是身份认证和 HTTS 证书体系的整合。如果你的内网环境有域控用 Windows 集成认证来给内部系统做登录控制裸跑 Node 就很难无缝对接。IIS 上可以做反向代理和 Windows 认证的组合Node 应用本身不用实现认证逻辑IIS 帮你全部挡在前面。1.2 IIS 托管方案的三种主流技术路线在 Windows 上把 Node.js 和 IIS 打通主要有三种路线部署前一定要先搞清区别选错了后面全是坑。路线一iisnode 模块。这是最经典也是网上教程最多的一种。iisnode 是一个 IIS 原生模块通过 web.config 里的handlers配置把.js文件的请求直接交给 Node.js 进程处理。它最大的特点是 Node 进程由 IIS 直接管控进程回收、并发控制都在这一个模块里完成。适合“一个 IIS 站点对应一个 Node 应用”的简单场景。路线二HttpPlatformHandler v2。这是微软官方接替 iisnode 的新方案官方 GitHub 仓库现在还维护着。它不像 iisnode 那样直接映射.js文件而是启动一个独立的 HTTP 进程监听本地回环地址的随机端口IIS 再把请求转发到这个端口。好处是它支持的运行时更广不光是 Node.jsJava、Python 这种监听端口的进程都能托管。路线三ARR 反向代理。安装 IIS 的 URL Rewrite 和 Application Request Routing (ARR) 模块把 https://你的域名/ 的所有请求反向代理到http://127.0.0.1:3000。这个方案对 Node 应用最“无感”应用代码完全不需要感知 IIS 的存在还是app.listen(3000)的方式。适合多个 Node 应用共用一个 IIS、各自监听不同端口的场景。我个人的建议是追求稳定文档多用 iisnode愿意折腾新版用 HttpPlatformHandler多站点各自为政用 ARR。这篇的主体部分以 iisnode 为主线讲最后再单开一节对比三个方案的选型细节。2. 部署前的环境准备从零装好 Node.js 与 IIS2.1 Node.js 安装与 PATH 配置不要为了图新鲜装最新的 Node.js。在 Windows Server 上跑生产环境我建议用LTS 版本而且版本不要过于激进实测 Node.js 18.x 和 20.x LTS 对 iisnode 的兼容性最稳。有些 npm 依赖包在 Node 22 上会有原生模块编译问题到时候排查起来很痛苦。安装包直接去 Node.js 官网下 Windows Installer (.msi) 版本安装过程中注意两点第一安装路径建议保持默认的C:\Program Files\nodejs\。虽然自定义路径可以但 iisnode 在解析 node.exe 路径时对带空格的路径处理偶尔会出幺蛾子后面 web.config 里写nodeProcessCommandLine也会更麻烦。保持默认最省心。第二安装完成后检查 PATH 环境变量。新版 Node.js 安装器会自动把C:\Program Files\nodejs\加到系统 PATH但有些情况下比如用绿色版、免安装版解压的不会自动配置。安装完成后打开一个新的 PowerShell 窗口执行node -v npm -v如果提示“无法识别 node 命令”就是 PATH 没配上。手动去“系统属性 - 环境变量 - Path”里添加C:\Program Files\nodejs\然后重启 PowerShell。2.2 启用 IIS 与必备模块Windows Server 和 Windows 10/11 专业版都能装 IIS但开启方式略有区别。Windows Server 上打开“服务器管理器 - 添加角色和功能”勾选Web 服务器 (IIS)。注意在“角色服务”列表里除了默认勾选的项我强烈建议勾上这些常见 HTTP 功能 - 默认文档、静态内容运行状况和诊断 - HTTP 日志记录、请求监视安全性 - URL 授权、Windows 身份验证内网环境用得着管理工具 - IIS 管理控制台其中“静态内容”这一项很多人都忽略。部署的 Node 项目里如果有静态资源目录比如public、uploadsIIS 默认不处理.js、.css、.png这些文件的静态请求就会出现“样式全丢、接口正常”的诡异问题。Windows 10/11 专业版则在“启用或关闭 Windows 功能”里勾选Internet Information Services子项里的“万维网服务”记得全展开把静态内容、默认文档这些也勾上。IIS 装好后还要装两个关键组件URL Rewrite和iisnode。URL Rewrite 是 iisnode 方案里做请求转发必需的——当用户访问https://你的域名/时IIS 得知道把这个请求重写到哪个.js文件上。没有它IIS 只会按默认规则找静态文件找不到就直接 404。URL Rewrite 的安装包可以从微软官网的 IIS 扩展页面下载。iisnode 呢去 GitHub 上搜iisnode仓库的 Releases 页面下载iisnode-full-v0.2.26-x64.msi这种安装包。虽然这个版本号停在 0.2.26 很久了但实测在 Windows Server 2016/2019/2022 上配合 Node.js 18/20 都能正常工作。注意安装 iisnode 的时候先装 URL Rewrite 再装 iisnode这个顺序别搞反。iisnode 的安装程序会在 IIS 的全局配置里注册 handler如果 URL Rewrite 还没装后面手写 web.config 时又得回头补装多绕一道弯路。2.3 验证 iisnode 是否安装成功装完之后打开 IIS 管理器左侧选中服务器节点双击“模块”图标往下翻能找到iisnode这个模块。如果能看见说明模块注册成功。更直接的验证方式是在 IIS 默认站点C:\inetpub\wwwroot下新建一个测试文本文件命名为test.js在里面写var http require(http); http.createServer(function (req, res) { res.writeHead(200, { Content-Type: text/plain }); res.end(Hello from Node.js on IIS); }).listen(process.env.PORT);然后在这个目录下新建一个 web.configconfiguration system.webServer handlers add nameiisnode pathtest.js verb* modulesiisnode / /handlers rewrite rules rule nametest match urltest.js / action typeRewrite urltest.js / /rule /rules /rewrite /system.webServer /configuration浏览器访问http://localhost/test.js如果页面显示Hello from Node.js on IIS说明 iisnode 已经能正常工作了环境搭建这一步就算踩实了。这里有一点要特别提醒代码里的process.env.PORT是关键。iisnode 托管时不会让你的 Node 应用自己决定监听哪个端口而是由 IIS 分配一个命名管道或者动态端口通过环境变量PORT传给应用。如果你的应用里硬编码app.listen(3000)iisnode 在这一步就会出问题后面我详细讲。3. iisnode 方案的核心web.config 按这个抄3.1 一个可以直接套用的 web.config 完整示例iisnode 方案里最核心的就是 web.config它决定了 IIS 怎么把请求转给你写的 Node.js 代码。我直接把用了很多次的完整配置贴出来然后逐段解释你才能知道每行是干嘛的出了问题也好排查。?xml version1.0 encodingUTF-8? configuration system.webServer !-- 告诉 IIS*.js 文件由 iisnode 模块处理而不是当成静态文件 -- handlers add nameiisnode pathapp.js verb* modulesiisnode / /handlers !-- 告诉 IIS把无法映射到静态资源的请求重写到 Node.js 入口文件 -- rewrite rules rule nameNodeApp stopProcessingtrue match url(.*) / conditions add input{REQUEST_FILENAME} matchTypeIsFile negatetrue / add input{REQUEST_FILENAME} matchTypeIsDirectory negatetrue / /conditions action typeRewrite urlapp.js / /rule /rules /rewrite !-- iisnode 模块专项配置 -- iisnode nodeProcessCommandLinequot;C:\Program Files\nodejs\node.exequot; maxConcurrentRequestsPerProcess1024 maxProcessCount1 node_envproduction loggingEnabledtrue logDirectoryiisnode debugHeaderEnabledfalse / /system.webServer /configuration如果你的项目入口文件不叫app.js比如是server.js或者index.js把上面的app.js全部替换成实际文件名就行。3.2 handlers 和 URL Rewrite 规则的逻辑拆解很多人照抄 web.config 之后发现一个问题直接访问http://你的站点/app.js能出结果但访问http://你的站点/就是 404 或者空白。这就是没有理解 handlers 和 URL Rewrite 是两层东西。handlers 这一层管的是“谁来处理这个请求”。pathapp.js的意思是只有请求路径精确匹配app.js时iisnode 这个模块才会介入。但用户访问的 URL 千奇百怪/、/api/user、/login……这些路径都不叫app.jsIIS 默认会把它们当作请求某个静态文件或目录去看找不到就 404。URL Rewrite 这一层管的是“请求进来之后往哪儿转”。我在配置里写的是一个通配规则只要是既不是真实文件、也不是真实目录的请求negatetrue就是“排除”的意思一律重写到app.js。这样/、/api/user被 rewrite 成app.js之后正好命中 handlers 里的规则iisnode 模块接管把请求交给 Node 进程处理。这种“重写 处理器”的组合本质上是在 IIS 和 Node.js 之间搭了一座桥。静态资源图片、CSS、JS 文件因为存在真实文件IsFile条件判断为真不会重写到 app.jsIIS 直接返回文件性能更好动态请求全部交给 Node逻辑清晰。3.3 iisnode 属性详解与 iisnode.ymlweb.config 里iisnode标签的各个属性建议不要全用默认值尤其是这几个nodeProcessCommandLine指定 node.exe 的绝对路径。注意 XML 转义要写成quot;。如果你的 Node.js 装在默认路径按上面写就没问题如果自定义路径这里一定要改对否则 iisnode 启动不了 Node 进程。maxConcurrentRequestsPerProcess单个 Node 进程能同时处理的最大并发请求数。默认值不是很高实测高并发下可以把等待队列拖死调到1024比较稳妥。maxProcessCountIIS 最多能启动几个 Node 进程。设成1表示单进程模式避免多个进程共享内存状态比如 socket.io 的广播时出乱子。node_env设成production会让 Express 等框架直接进入生产模式从性能、报错信息两方面都更符合线上部署要求。loggingEnabled和logDirectory打开 iisnode 自己的日志。排障的时候这些日志能救命的后面我会专门讲怎么看。如果你需要更细粒度的控制比如修改日志文件最大大小、设置 devErrors 是否向前端暴露错误详情可以在 web.config 的同级目录放一个iisnode.ymlloggingEnabled: true logDirectory: iisnode debugHeaderEnabled: false devErrorsEnabled: true maxConcurrentRequestsPerProcess: 1024 maxProcessCount: 1iisnode.yml的优先级比 web.config 里的iisnode属性更高。也就是说俩都写了yml 里的值会覆盖 XML 属性。这个机制有时候会让新手困惑明明 web.config 里关闭了日志日志目录里却还在产生文件八成就是项目里残留了一个 iisnode.yml 在生效。4. 创建 IIS 网站到跑通第一版的完整步骤4.1 新建应用程序池并调优环境准备好了web.config 也放进项目目录了接下来就是在 IIS 管理器里把站点正式建起来。打开 IIS 管理器左侧“应用程序池”右键 - “添加应用程序池”。名称按项目名写比如NodeAppPool.NET CLR 版本选择“无托管代码”——很多人在这里习惯性选 v4.0实际上 iisnode 跑的是 Node.js不经过 .NET CLR选“无托管代码”可以避免不必要的托管环境加载开销。托管管道模式选“集成”。右键这个新建的应用程序池进入“高级设置”有两个参数建议改掉“回收 - 特定时间”默认的应用程序池回收时间是凌晨 03:17这个时间点是 IIS 随机生成的一旦回收正在处理的请求会被强杀。如果线上有正在跑的长任务建议把特定时间清空改为按需回收。“进程模型 - 闲置超时分钟”默认 20 分钟也就是 20 分钟没有请求进来这个 Node 进程就会被回收掉。很多 Node 应用第一次访问时特别慢就是因为进程被回收后冷启动。如果对内存不敏感把这个值设成0不回收或者调大到 1440。注意这里的“回收”指的是应用程序池的工作进程w3wp.exe回收iisnode 管理的 node.exe 子进程也会跟着受影响。如果发现 Node 应用“用着用着突然变慢、过一会又好了”大概率就是定期回收导致的冷启动先去检查这个设置。4.2 网站绑定端口与主机名的细节左侧“网站”右键 - “添加网站”站点名称随意应用程序池选刚才建的NodeAppPool物理路径指向你的项目发布目录。绑定类型选http还是https看你的证书情况。端口这里有个常见的坑如果你这台服务器上已经存在“默认网站”Default Web Site占用着 80 端口你新建站点还绑定 80启动站点时会直接报“另一个站点正在使用同一端口”。解决办法有三种把默认网站停掉让新站点独占 80。给每个站点绑定不同的主机名比如node1.example.com和node2.example.comIIS 按 Host 头区分请求。让新站点用别的端口比如 8080访问时带端口。我建议内网测试环境直接用端口区分生产环境一定用主机头 HTTPS 证书这样最正规也不会误伤同一台服务器上的其他站点。绑定完之后记得去 Windows 防火墙里确认入站规则是否放行了对应端口。如果是从外网访问还要检查云服务器安全组规则——这个最容易漏本地浏览器一访问直接超时排查半天发现是云控制台的安全组没放行。4.3 目录权限从“应用程序池权限设置失败”说起建完站点直接把项目文件拷到物理路径然后浏览器访问——这一步大概率会踩权限坑。常见报错是500.19 错误无法读取配置文件应用程序池权限设置失败请手动为其设置 localsystem 权限 未知错误(0x80005000)这个错误我在多个 Server 版本上都见过本质原因就一个应用程序池的工作进程身份没有权限读取你项目目录下的 web.config或者是 IIS 管理器里 GUI 设置权限的功能在某些环境上存在缺陷报了个让人摸不着头脑的错误码。解决办法是右键点击项目目录 - 属性 - 安全 - 编辑给IIS_IUSRS用户组添加“读取和执行”、“列出文件夹内容”、“读取”权限。如果排障时急用先给Everyone读取权限确认一下就是权限问题然后再收紧成IIS_IUSRS。如果项目里有写入需求比如上传文件、生成日志还要单独给对应的子目录uploads/、logs/加“修改”和“写入”权限。这里千万别图省事直接给整个项目目录 Everyone 完全控制Node 的node_modules目录里第三方包数量巨大一旦目录可写被入侵后可能被直接篡改依赖安全风险很高。特别提醒修改 web.config 后IIS 会自动触发应用程序池回收这会导致 Node 进程重启。如果你改了文件系统权限、环境变量、端口绑定这类不涉及 web.config 的配置记得手动重启一下应用程序池否则改动不生效还容易误判成“改了没用”。4.4 发布 Express 应用的注意点把 Node 项目从开发机传到服务器上我见的两种做法一种是把整个项目文件夹含 node_modules直接拷贝过去另一种是只拷贝源码到服务器上重新npm install --production。个人更推荐第二种。第一种虽然省事但要是开发机和服务器系统版本不同比如开发是 Windows服务器是老 Windows里面某些原生模块bcrypt、sharp、canvas这类可能是在开发机的 CPU 架构下编译的拷过去直接报Invalid ELF header或者 “was compiled against a different Node.js version”。正确做法是# 在服务器项目目录下执行 npm install --production --registryhttps://registry.npmmirror.com用国内镜像源下载会快很多。装完依赖后先别急着走 IIS在项目目录里直接跑npm start或者node app.js确认应用依赖没问题。这一步的意义是把“应用本身的错误”和“IIS 托管导致的错误”切开——应用本地跑不起来的没必要让 IIS 背锅。确认本地能跑之后再把入口代码里写死的端口改掉。iisnode 模式下应用必须监听process.env.PORT。Express 应用的经典写法const express require(express); const app express(); // 你的中间件、路由... const port process.env.PORT || 3000; app.listen(port, () { console.log(App listening on port ${port}); });这段代码在本地开发时process.env.PORT不存在就会落在 3000但 iisnode 托管时环境变量里有 IIS 分配的动态端口Node 进程监听这个端口IIS 才能把请求正确地转发过去。5. 部署后必踩的坑从 502 到 empty reply 的排查链路5.1 “npm 无法加载文件” —— PowerShell 执行策略这是一个非常经典的 Windows 环境问题虽然不完全发生在 IIS 部署环节但只要是新服务器十有八九会遇到。在 PowerShell 里执行npm install提示npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1因为在此系统上禁止运行脚本。这是因为 PowerShell 的默认执行策略是Restricted不允许运行任何 .ps1 脚本而 npm 的命令行入口是 npm.ps1。注意node -v能通过是因为 node.exe 是原生程序但 npm 是 PowerShell 脚本所以被拦住了。解决方法是在 PowerShell管理员身份里执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser选 “Y” 确认。RemoteSigned的意思是本地创建的脚本可以运行从互联网下载的脚本需要数字签名——既满足了运行 npm 的需求又不至于完全放开执行策略。另外如果是在cmd命令行里跑npm则不会触发这个限制因为 cmd 会直接调用npm.cmd。所以应急的时候切到 CMD 窗口也能绕过去但根治还是要改执行策略毕竟 PowerShell 才是 Windows 运维的主要工具。5.2 访问根路径报 502.3 / empty reply但访问具体路由却正常这是我见过最多的一个坑。配置全部按教程做了访问http://localhost/api/user正常返回 JSON但访问http://localhost/时浏览器直接报502.3 Bad Gateway或者empty reply from server。问题几乎都出在 URL Rewrite 规则的匹配顺序和边界处理上。当用户访问/时URL Rewrite 把它重写到app.js但{REQUEST_FILENAME}这个条件在某些情况下判断/这个路径对应的物理目录是存在的比如你的项目物理路径就是C:\inetpub\nodeapp请求/时 IIS 认为请求的目标就是物理路径本身于是IsDirectory条件成立negatetrue取反后不满足重写条件请求就停留在“请求一个目录”的状态IIS 去找默认文档找不到就 502.3 或者空响应。解决办法有几个按稳妥程度排序方案一URL Rewrite 规则加上默认文档兜底。在重写规则之前先加一条规则当请求的目标是目录且存在默认文档时直接重写到默认文档对应的应用入口。最省事的做法其实是让你的默认文档指向一个静态占位页然后把所有非静态资源的请求全部重写rule nameNodeApp stopProcessingtrue match url(.*) / conditions add input{REQUEST_FILENAME} matchTypeIsFile negatetrue / add input{REQUEST_FILENAME} matchTypeIsDirectory negatetrue / add input{URL} pattern^/$ negatefalse / /conditions action typeRewrite urlapp.js / /rule其实就是把根路径/也纳入重写范围不要让它命中 IsDirectory。方案二站点级别设置默认文档为app.js。在 IIS 管理器的“默认文档”里添加app.js。这样当访问/时IIS 先尝试找默认文档找到app.js后这个请求就变成静态文件请求app.js再由 handlers 交给 iisnode。注意这里要理解 IIS 请求处理的顺序是 “先找默认文档 - 再走 URL Rewrite - 最后匹配 handlers”。方案二的思路是让默认文档把请求“升级”成对 app.js 的精确访问从而绕过 IsDirectory 判断。实测这个方案对根路径 502 特别有效而且不需要改动重写规则。5.3 应用已经被 iisnode 启动但请求还是 404如果访问根目录报的是404 Not Found而不是 502那说明 iisnode 模块没有接管请求或者接管了但 Node 进程没跑起来。这时候按顺序检查三件事第一handlers 里的 path 是不是和入口文件名完全一致。大小写、多一个空格、拼写错误都会导致匹配不上。IIS 的 handler 匹配是精确匹配不像 Windows 文件系统不区分大小写那么宽松。第二URL Rewrite 模块是否真的装上了。在 IIS 管理器的站点“功能视图”里看有没有“URL 重写”这个图标。没装 URL Rewrite 的话web.config 里rewrite节点就是一个未知配置节IIS 直接报 500.19 配置错误根本到不了 404 这一步。第三Node 应用实际监听端口是否正常。在服务器上执行Get-Process node | Select-Object Id, ProcessName, Path看看有没有 node.exe 进程在跑。如果在跑再确认它的监听端口iisnode 模式是命名管道可以用 Process Explorer 查看。如果没有进程打开日志目录看iisnode日志里的崩溃信息。5.4 高并发下 Node 进程频繁崩溃重启iisnode 方案在并发上来之后Node 进程偶尔会崩这是相对常见的问题。表现是请求变慢、随机出现 503过几秒自己恢复反反复复。排查思路分三步第一步打开 iisnode 的崩溃日志看节点进程是不是因为内存超限被回收。Node.js 的默认堆内存上限在 64 位系统上是 2GB 左右如果你的应用频繁处理大对象很容易触顶。可以在启动命令里加参数提高上限iisnode nodeProcessCommandLinequot;C:\Program Files\nodejs\node.exequot; --max-old-space-size4096 /第二步检查是否有未捕获的 Promise 异常。Node 进程最怕的就是unhandledRejection一旦全局未捕获异常出现进程直接崩。在入口文件顶部加个兜底process.on(uncaughtException, (err) { console.error(Uncaught Exception:, err); }); process.on(unhandledRejection, (reason) { console.error(Unhandled Rejection:, reason); });这一对全局处理器不能替你解决业务逻辑问题但至少能让进程扛住偶发的异常而不是直接退出。日志打出来后再针对具体错误修代码。第三步确认maxConcurrentRequestsPerProcess参数没卡住。iisnode 的并发模型是每个 Node 进程同时处理多个请求如果单个请求阻塞时间太长会让 Node 的事件循环失去响应。用kudu或者process.memoryUsage()打点监控看是 CPU 密集导致的事件循环延迟还是 I/O 等待过长。5.5 日志不会说谎iisnode 排障的正确打开方式前面反复提到日志目录这里把排障链路完整走一遍。iisnode 默认会在项目的 web.config 同级目录下生成iisnode文件夹里面有这样几类文件文件类型内容排障用途iisnode-xxxx-*.logiisnode 模块自身的运行日志模块加载、进程启动失败的原因node-xxxx-*.logNode 进程的 stdout/stderr 输出console.log、console.error打的内容全在这里*.sock命名管道文件存在即说明进程在监听可忽略遇到 502 或者 503我的排查顺序永远固定先看iisnode-*日志里面会明确写“Failed to launch node executable”或“The node process did not start listening on the port”。这一条能直接定位是 node.exe 路径问题还是应用启动失败。然后看node-*日志里面是应用自身打出来的错误堆栈比如导入模块失败、端口被占用、数据库连接超时。如果这两层都没有线索再看 IIS 的“失败请求跟踪”日志Failed Request Tracing它能记录整个请求在 IIS 管线里经过了哪些模块、在哪一步出的错。开启方式是在站点功能视图里选择“失败请求跟踪”添加规则状态代码填500-599再设置跟踪文件的保存目录。实测下来90% 的部署问题通过前两步就能搞定真正需要走到失败请求跟踪这层的情况并不多但掌握它能让排查效率高一个量级。6. 多站点场景的进阶方案HttpPlatformHandler 与 ARR 选型6.1 三种方案的核心差异对比如果你的环境不止一个 Node 应用要放在 IIS 上或者你的技术栈里还有 Java、Python 服务那 iisnode 就不一定是最优解了。下面用表格对比三个方案方便你按场景选型对比维度iisnodeHttpPlatformHandler v2ARR 反向代理原理模块内启动 node 进程命名管道通信启动 HTTP 进程动态端口通信反向代理到应用固定端口应用代码改动需改用process.env.PORT需改用process.env.PORTv2 传HTTP_PLATFORM_PORT无需改动继续监听固定端口多实例并发单站点单进程为主支持按进程数扩展自行管理进程数静态资源处理由 IIS 统一处理由 IIS 统一处理可代理可自行处理配置复杂度中web.config 配置项多中低但需要额外维护端口进程官方维护状态基本停止更新持续维护持续维护适合场景老项目、单 Node 应用、已有大量教程参考新项目、多运行时统一托管多 Node 应用、不想改应用代码6.2 我建议的选型思路先说结论新项目首选 HttpPlatformHandler v2老项目稳定优先就用 iisnode应用本身已经是微服务形态、多服务同时跑的话走 ARR。HttpPlatformHandler v2 的配置思路是在 web.config 的 handlers 里注册一个httpplatform:nodejs处理器然后在httpPlatform节点里指定processPath和arguments让它启动node app.js。这个模块会自己把环境变量HTTP_PLATFORM_PORT传给应用应用监听这个端口即可。它比 iisnode 更接近“进程管理器”的形态配置项也更语义化。ARR 的方案最简单粗暴装好 ARR 和 URL Rewrite 之后web.config 里写一条反向代理规则rewrite rules rule nameReverseProxyToNode stopProcessingtrue match url(.*) / action typeRewrite urlhttp://127.0.0.1:3000/{R:1} / /rule /rules /rewriteNode 应用还像开发环境一样监听 3000 端口配合 pm2 这类进程守护工具管理生命周期。这个方案的最大优势是应用代码零感知迁移成本最低你甚至可以同时代理多个端口对应多个应用IIS 在这里纯粹当一个流量入口。缺点也显而易见Node 进程和 IIS 各管各的生命周期监控、日志都割裂需要自己额外做一层进程守护pm2 或 NSSM如果并发很高本机回环代理也会损耗一些性能。我个人在实际部署中一般是这么决策的如果这台服务器的运维由 .NET 团队顺手管着不希望引入太多额外组件而且就是单个 Node 服务就用 iisnode它和 IIS 结合得最紧密IIS 的回收、日志、权限体系直接接管 Node 进程。如果团队里有人对 pm2 很熟或者同一个站点要同时代理好几个后端服务ARR 更省事。最后再分享一个小技巧无论用哪种方案先在本地把应用跑通再上 IIS 托管最后才配置域名和 HTTPS这个顺序能帮你把“代码问题”和“托管问题”隔离开。真出问题了先看应用自己的日志再看 iisnode 或 HttpPlatformHandler 的日志最后才翻 IIS 的配置——按这个链路走没有排查不出来的问题。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑