<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>IIS on 懒洋洋</title><link>https://lanlan.work/tags/iis/</link><description>Recent content in IIS on 懒洋洋</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 03 Oct 2026 14:00:00 +0800</lastBuildDate><atom:link href="https://lanlan.work/tags/iis/index.xml" rel="self" type="application/rss+xml"/><item><title>POSCMS 在 IIS + PHP 5.6 下 php-cgi 进程持续暴涨的排查与处理</title><link>https://lanlan.work/posts/technology/poscms-cgi/</link><pubDate>Sat, 03 Oct 2026 14:00:00 +0800</pubDate><guid>https://lanlan.work/posts/technology/poscms-cgi/</guid><description>&lt;h2 id="现象与结论"&gt;现象与结论&#10;&lt;/h2&gt;&lt;p&gt;Windows 服务器（IIS + FastCGI + PHP 5.6）上的一个多年未升级的 POSCMS 站点，IIS 站点一启动 php-cgi.exe 进程就不断增多，伴随偶发数据库连接失败。&lt;/p&gt;&#10;&lt;p&gt;PHP 5.6 本身不会 fork，多个 php-cgi.exe 是 FastCGI 为并发请求分配进程槽位的正常机制。真正的问题是：&lt;strong&gt;每个请求都可能被拖住最长 60 秒释放不掉，而站点被扫描机器人 7×24 轰炸，请求不断堆积，IIS 只能不停拉新进程接客&lt;/strong&gt;。把请求拖死的元凶是 PHP 文件 Session 的垃圾回收（GC）。&lt;/p&gt;&#10;&lt;h2 id="排查过程"&gt;排查过程&#10;&lt;/h2&gt;&lt;p&gt;先搜 &lt;code&gt;pcntl_fork&lt;/code&gt;/&lt;code&gt;exec&lt;/code&gt;/&lt;code&gt;fsockopen&lt;/code&gt; 等调用，确认程序没有主动起进程，也排除了 POSCMS 自带的任务队列（&lt;code&gt;SYS_CRON_QUEUE&lt;/code&gt; 为关闭）和附件同步的自我 HTTP 调用（未启用），顺手扫了一遍无 webshell。&lt;/p&gt;&#10;&lt;p&gt;决定性证据来自 &lt;code&gt;cache/errorlog/&lt;/code&gt; 的运行日志：从两年前持续到排查当天，几乎每天都是同一种致命错误，最重的日子一天 200+ 条：&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;ERROR --&amp;gt; Maximum execution time of 60 seconds exceeded&#10;C:\wwwroot\&amp;lt;站点目录&amp;gt;\diy\system\libraries\Session\drivers\Session_files_driver.php 380&#10;----&amp;gt; http://&amp;lt;域名&amp;gt;/index.php/xin/2023-11-05 14:37:57/ben/amp/a/xxxxxxx.ppt&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;报错行号 375/380/387 全落在 &lt;code&gt;Session_files_driver.php&lt;/code&gt; 的 &lt;code&gt;gc()&lt;/code&gt; 里——遍历整个 session 目录逐文件 &lt;code&gt;filemtime&lt;/code&gt;+&lt;code&gt;unlink&lt;/code&gt; 的循环。&lt;strong&gt;请求卡在&amp;quot;清扫 session 目录&amp;quot;上整整 60 秒，被入口文件的 &lt;code&gt;set_time_limit(60)&lt;/code&gt; 强杀&lt;/strong&gt;。一天 200 次即 200 分钟被记录在案的卡死，且凌晨也在持续（机器人不睡觉）。&lt;/p&gt;&#10;&lt;p&gt;session 目录为什么这么大，三个条件叠加：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;POSCMS 基础控制器对&lt;strong&gt;每个请求&lt;/strong&gt;无条件 &lt;code&gt;$this-&amp;gt;load-&amp;gt;library('session')&lt;/code&gt;；&lt;/li&gt;&#10;&lt;li&gt;文件驱动写入 &lt;code&gt;cache/session/&lt;/code&gt;；&lt;/li&gt;&#10;&lt;li&gt;机器人不带 cookie，CI3 对新访客必定写一个 session 文件（文件名 = cookie 名 + 会话 ID），只能等 GC 删。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;目录膨胀到数万文件后，PHP 默认约 1% 的请求触发 GC 全目录扫描，Windows/NTFS 上逐文件操作极慢（再叠杀软更甚）。这里有个 Windows 特有的坑：&lt;strong&gt;&lt;code&gt;max_execution_time&lt;/code&gt; 在 Windows 下算墙钟时间（含 IO 等待）&lt;/strong&gt;，所以这种 IO 型卡死在 Linux 上往往不触发超时，在 Windows 上必然 60 秒被杀。&lt;/p&gt;&#10;&lt;p&gt;请求侧还有一个细节：日志里被卡死的全是 &lt;code&gt;/index.php/xxx.ppt&lt;/code&gt; 这类扫描 URL，而 POSCMS 的伪静态解析把 &lt;code&gt;index.php&lt;/code&gt; 开头的 URI 一律置空——&lt;strong&gt;这类请求全部被当首页处理&lt;/strong&gt;，每个垃圾 URL 都完整跑一遍 CMS + MySQL + session，程序没有廉价的 404 出口。&lt;/p&gt;&#10;&lt;p&gt;连锁反应随之而来：并发 php-cgi 滚起来后 MySQL 连接被拒（日志成串的&amp;quot;由于目标计算机积极拒绝&amp;quot;），其他请求又在等连接超时，进程进一步堆住。&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;机器人 7×24 轰炸（无 cookie）&#10; → 每请求完整跑 CMS + 生成一个 session 文件&#10; → 目录膨胀到数万文件&#10; → 1% 请求触发 GC 全目录扫描，60 秒被强杀&#10; → 每个 GC 请求钉住一个 php-cgi 一分钟，新请求还在涌入&#10; → IIS 不停拉新进程，进程数暴涨，MySQL 被拖垮&#10;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="修复方案"&gt;修复方案&#10;&lt;/h2&gt;&lt;h3 id="方案一治本改三处代码无-session-cookie-的请求不启动-session"&gt;方案一（治本，改三处代码）：无 session cookie 的请求不启动 session&#10;&lt;/h3&gt;&lt;p&gt;机器人永远不携带 session cookie，真人在第一次 POST/登录/验证码后就会带上。改前需把代码里所有 session 使用点过一遍，本例只需动三处。下表行号为本站代码的&lt;strong&gt;原始行号&lt;/strong&gt;，套到其他 POSCMS 站时若版本有偏移，按&amp;quot;定位方法&amp;quot;列搜索即可：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;#&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;文件&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;位置&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;定位方法&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;①&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;diy/poscms/core/Common.php&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;第 126 行&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;搜索 &lt;code&gt;library('session')&lt;/code&gt;（全文件唯一一处）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;②&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;diy/poscms/model/Attachment.php&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;第 18 行（&lt;code&gt;__construct()&lt;/code&gt; 内）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;搜索 &lt;code&gt;userdata('siteid')&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;③&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;diy/poscms/model/Member.php&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;第 1113 行之后（&lt;code&gt;member_uid()&lt;/code&gt; 内）&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;搜索 &lt;code&gt;function member_uid&lt;/code&gt;，找到 &lt;code&gt;if (!$uid) { return NULL; }&lt;/code&gt; 的闭合 &lt;code&gt;}&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;strong&gt;① Common.php 第 126 行&lt;/strong&gt;（基础控制器构造函数内，&lt;code&gt;define('SYS_ADMIN_PAGESIZE', ...)&lt;/code&gt; 下方）：把 &lt;code&gt;$this-&amp;gt;load-&amp;gt;library('session');&lt;/code&gt; 这一行替换为：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;IS_POST&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;IS_ADMIN&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;IS_MEMBER&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;config_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sess_cookie_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;m&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;captcha&amp;#39;&lt;/span&gt; &lt;span class="c1"&gt;// 验证码图片&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;m&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;aslogin&amp;#39;&lt;/span&gt; &lt;span class="c1"&gt;// 后台免登录握手&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;auth_code&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 移动端api授权&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;library&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;session&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意 &lt;code&gt;IS_MEMBER&lt;/code&gt; 在 Init/Rewrite 阶段&lt;strong&gt;恒有定义&lt;/strong&gt;（非会员为 &lt;code&gt;FALSE&lt;/code&gt;），判断要用常量值而非 &lt;code&gt;defined('IS_MEMBER')&lt;/code&gt;（后者恒真）。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;② Attachment.php 第 18 行&lt;/strong&gt;（附件模型构造函数，全站唯一无条件下读 session 的点，而附件模型每个内容页都会实例化）：把&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;siteid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;session&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;userdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;siteid&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;替换为（紧随其后的 &lt;code&gt;SITE_ID&lt;/code&gt; 兜底行保持不变）：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;siteid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;is_loaded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;session&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;session&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;userdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;siteid&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;③ Member.php 第 1113 行之后&lt;/strong&gt;（&lt;code&gt;member_uid()&lt;/code&gt; 方法内）：处理&amp;quot;记住登录&amp;quot;用户 session 过期（2 小时）后回访的边界情况。在该方法里 &lt;code&gt;if (!$uid) { return NULL; }&lt;/code&gt; 的闭合 &lt;code&gt;}&lt;/code&gt; 与 &lt;code&gt;if (!$this-&amp;gt;session-&amp;gt;userdata('uid'))&lt;/code&gt; 之间插入一行：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;is_loaded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;session&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;library&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;session&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其余调用点天然安全：无 cookie 机器人走不到 session 读取就提前返回；评论防灌水等都是 POST；OAuth 回调在会员域被 &lt;code&gt;IS_MEMBER&lt;/code&gt; 覆盖。上线后用无痕窗口回归：前台页面不再新增 &lt;code&gt;sess&lt;/code&gt; 文件，登录/验证码/评论/后台正常。&lt;/p&gt;&#10;&lt;h3 id="方案二治流量iis-层把机器人挡在-php-之前"&gt;方案二（治流量）：IIS 层把机器人挡在 PHP 之前&#10;&lt;/h3&gt;&lt;p&gt;利用&amp;quot;&lt;code&gt;/index.php/*&lt;/code&gt; 被当首页处理、对站点毫无价值&amp;quot;这一事实，URL Rewrite 整段 404（正常链接是 &lt;code&gt;/index.php?c=xx&lt;/code&gt; 格式，不受影响），加在站点 &lt;code&gt;web.config&lt;/code&gt; 的 &lt;code&gt;&amp;lt;rewrite&amp;gt;&lt;/code&gt; 节点内：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;rule&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;blockPathInfoJunk&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;stopProcessing=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;match&lt;/span&gt; &lt;span class="na"&gt;url=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;^index\.php/.+&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;ignoreCase=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CustomResponse&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;statusCode=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;404&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;statusReason=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Not Found&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/rule&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;再开 IIS 自带的动态 IP 限制，把高频扫描源直接封掉。先执行两条前置命令（装角色服务 + 解锁站点级配置，不解锁的话 web.config 会报 500.19）：&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;Install-WindowsFeature Web-IP-Security&#10;%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/security/dynamicIpSecurity&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后在同一个 &lt;code&gt;web.config&lt;/code&gt; 的 &lt;code&gt;&amp;lt;system.webServer&amp;gt;&lt;/code&gt; 内、与 &lt;code&gt;&amp;lt;rewrite&amp;gt;&lt;/code&gt; 并列加上：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;security&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;&amp;lt;!-- 单IP并发超过10个请求、或1秒内超过30个请求即拒绝 --&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;dynamicIpSecurity&lt;/span&gt; &lt;span class="na"&gt;denyByConcurrentRequests=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;10&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;denyByRequestRate=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;30&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;requestRateInInterval=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1000&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;denyAction=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Forbidden&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;enableProxyMode=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;false&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/dynamicIpSecurity&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/security&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;套了 CDN/反代的站必须把 &lt;code&gt;enableProxyMode&lt;/code&gt; 改为 &lt;code&gt;true&lt;/code&gt; 并放宽阈值&lt;/strong&gt;，否则所有访客都记在代理 IP 一个头上，会把代理整个封掉。&lt;/p&gt;&#10;&lt;p&gt;宝塔 Windows 面板用户：面板只是壳，底层仍是 IIS，最终都落到站点根目录 &lt;code&gt;web.config&lt;/code&gt;——URL 重写用&amp;quot;网站 → 设置 → URL重写&amp;quot;或文件管理直接编辑（先备份）；动态 IP 限制按上面命令操作；session 定时清理用面板的 计划任务跑 &lt;code&gt;forfiles&lt;/code&gt; 删一天前的旧文件（注意 CI3 文件前缀是 cookie 名如 &lt;code&gt;poscms_ci_session*&lt;/code&gt;，不是 &lt;code&gt;sess_*&lt;/code&gt;）。&lt;/p&gt;&#10;&lt;h3 id="配套参数phpini"&gt;配套参数（php.ini）&#10;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;session.gc_probability = 0&lt;/code&gt; 禁用请求时 GC（靠计划任务清理），这是消灭 60 秒卡死最见效的一条。另外建议入口文件里 &lt;code&gt;memory_limit&lt;/code&gt; 从 1024M 降到 256M、&lt;code&gt;set_time_limit&lt;/code&gt; 从 60 降到 30。&lt;/p&gt;&#10;&lt;h2 id="验证清单"&gt;验证清单&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;/index.php/anything&lt;/code&gt; 返回 404；站点日志出现 403.501/403.502（IP 限制生效）；php-cgi.exe 数量回落；&lt;code&gt;cache/session/&lt;/code&gt; 不再增长；错误日志里 Session 超时基本消失；前台/登录/后台回归正常。&lt;/p&gt;&#10;&lt;h2 id="复盘要点"&gt;复盘要点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;多 php-cgi 进程 ≠ 程序在起进程&lt;/strong&gt;。进程数暴涨几乎总是&amp;quot;请求变慢 + 流量不退&amp;quot;，要找的是什么把请求拖住了；&lt;/li&gt;&#10;&lt;li&gt;&amp;ldquo;每请求无条件 session + 文件驱动&amp;quot;在 Windows 上有放大效应：墙钟超时 + NTFS 小文件遍历慢 + 杀软，GC 慢到荒谬且每次钉死一个 FastCGI 进程一分钟；&lt;/li&gt;&#10;&lt;li&gt;排查这类问题，错误日志里致命错误的&lt;strong&gt;文件名 + 行号&lt;/strong&gt;比通读代码快得多；&lt;/li&gt;&#10;&lt;li&gt;无 cookie 访客跳过 session 是普适模式：机器人在入口就被识别，真人首次需要 session 时才创建；&lt;/li&gt;&#10;&lt;li&gt;挡扫描流量优先在 Web 服务器层静态拒绝，让恶意请求的成本从&amp;quot;完整跑一遍 PHP + MySQL&amp;quot;降到一次内核态 404。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</description></item></channel></rss>