Node/Express经IIS反向代理访问出现数分钟数据更新延迟
问题根因
这个数分钟延迟完全是IIS反向代理依赖的ARR(Application Request Routing)模块默认缓存机制导致的。直接访问node-app:3000绕过了IIS代理层,没有缓存逻辑介入,所以无延迟,和Node应用逻辑、数据库执行速度没有关系。
默认配置下,ARR会对没有明确声明Cache-Control: no-store的GET/HEAD响应做本地磁盘/内存缓存,默认缓存有效期1-5分钟不等。缓存有效期内,所有匹配请求会直接由IIS返回本地存储的旧响应,根本不会转发到后端的3000端口Node服务,等缓存过期才会重新拉取新内容,和你描述的现象完全匹配。
排查步骤
- 打开IIS管理器,选中服务器根节点,找到「Application Request Routing Cache」功能,点击右侧操作栏的「Server Proxy Settings」,临时取消勾选「Enable disk cache」,执行
iisreset命令重启IIS后测试数据库更新操作,如果延迟直接消失,即可100%确认是ARR缓存导致的问题。 - 走代理路径访问任意数据查询接口,查看响应头:如果存在
Age字段、X-ARR-CACHE: HIT标记,或是Cache-Control头带max-age/public属性,说明当前响应直接来自ARR缓存,没有转发到Node服务。 - 选中部署Node应用的对应站点,打开「输出缓存」功能,检查是否存在针对接口路径、无扩展名路径的缓存规则,若存在可临时禁用后测试。
解决方案
直接修改站点下的web.config即可完成配置,不需要逐一点击IIS界面调整,配置可随站点文件同步迁移。
完整可用配置如下:
<configuration> <system.webServer> <rewrite> <!-- 声明规则中可修改的服务器变量,不添加会报500错误 --> <allowedServerVariables> <add name="HTTP_CACHE_CONTROL" /> <add name="RESPONSE_Cache-Control" /> <add name="ARR_DISABLE_CACHE" /> </allowedServerVariables> <rules> <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" /> <action type="Rewrite" url="http://localhost:3000/{R:1}" logRewrittenUrl="true" /> <serverVariables> <!-- 强制禁用ARR对该规则转发请求的缓存 --> <set name="ARR_DISABLE_CACHE" value="1" /> <!-- 转发请求时携带no-cache头,告知后端返回最新内容 --> <set name="HTTP_CACHE_CONTROL" value="no-cache, no-store, max-age=0" /> </serverVariables> </rule> </rules> <!-- 给动态响应强制覆盖no-cache头,避免后端没返回缓存头时被ARR缓存 --> <outboundRules> <rule name="ForceNoCacheForDynamic" preCondition="IsDynamicResponse"> <match serverVariable="RESPONSE_Cache-Control" pattern=".*" /> <action type="Rewrite" value="no-cache, no-store, must-revalidate" /> </rule> <preConditions> <preCondition name="IsDynamicResponse"> <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/|application/json" /> </preCondition> </preConditions> </outboundRules> </rewrite> <!-- 关闭站点级内核缓存和输出缓存 --> <caching enabled="false" enableKernelCache="false" /> </system.webServer> </configuration>
配置注意事项:
- 替换原
web.config内容后,执行iisreset重启IIS即可生效,不需要重启Node应用。 - 若需要保留静态资源的缓存能力提升性能,可以拆分反向代理规则:将
/static、/public等静态资源路径单独配置规则,允许缓存;/api、页面渲染路径等动态内容走禁用缓存的规则,兼顾性能和数据实时性。 - 长期建议在Express侧统一给动态接口返回
Cache-Control: no-store响应头,从源头避免所有中间代理层缓存动态数据,是最稳妥的方案。
内容的提问来源于stack exchange,提问作者b0bbydev
相关产品推荐
相关产品推荐

