执行 php artisan down 后网站仍正常访问,最常见原因是配置或路由缓存未清除,导致 laravel 启动时未读取 storage/framework/down 文件;需执行 php artisan config:clear 和 php artisan route:clear,opcache 或 octane 环境还需重启进程或运行 php artisan octane:reload。

直接执行 php artisan down 就能开启维护模式,但多数“没反应”或“页面还能访问”的问题,都卡在缓存、多服务器同步或代理环境上。
为什么执行 php artisan down 后网站还在正常访问
最常见原因是配置或路由被缓存了,Laravel 启动时根本没读到 storage/framework/down 文件。
- 必须先清掉配置缓存:
php artisan config:clear(如果用了config:cache) - 还要检查是否启用了路由缓存:
php artisan route:clear,否则缓存的路由会跳过维护拦截逻辑 - OPcache 或 Octane 环境下,PHP 可能仍运行旧字节码,需重启 PHP 进程或执行
opcache_reset() - 如果你用的是 Laravel Octane,得额外运行
php artisan octane:reload,否则新生成的down文件不生效
php artisan down 的关键参数怎么选
默认命令只写文件、返回 503,但生产环境几乎都要加参数:
-
--message="系统升级中,请稍候":控制resources/views/errors/503.blade.php中$message变量的值,别依赖视图里硬编码文本 -
--retry=300:设 HTTP 响应头Retry-After: 300,影响浏览器自动重试和爬虫抓取节奏 -
--allow=192.168.1.100:允许多个 IP,重复写多次即可;注意它只比对$_SERVER['REMOTE_ADDR'],Nginx + Cloudflare 等场景要手动解析X-Forwarded-For -
--secret="xyz123":生成可绕过的临时路径(如/xyz123),会种 cookie,适合测试人员不用配 IP 白名单
多服务器或负载均衡下怎么确保全站生效
php artisan down 默认只影响当前节点,因为 storage/framework/down 是本地文件。
- 共享存储(如 NFS)可同步该文件,但要注意文件权限和写入延迟
- 更稳妥的做法是把维护状态外置:比如用 Redis 存一个
laravel:maintenancekey,在AppServiceProvider@boot里读取并手动触发abort(503) - CDN 层(如 Cloudflare)可配合 Page Rule 返回自定义 503 页面,避免请求打到后端
- 千万别靠改
public/index.php加判断——它可能被 OPcache 缓存,且升级时容易被覆盖
怎么安全地从代码里判断或切换维护状态
不要依赖文件是否存在,app()->isDownForMaintenance() 才是唯一可靠的运行时判断方式。
- 它读的是 Laravel Application 实例内部状态,不是文件 I/O,快且稳定
- 在后台控制器里调用
Artisan::call('down')后,立刻用这个方法验证是否生效(注意:它不会因文件被手动删掉而失准) - 若你在中间件或异常处理器里做逻辑分支,务必确认该中间件在
CheckForMaintenanceMode之前注册,否则请求早被截断了 - 执行
php artisan up后,这个方法才返回false;手动删down文件无效,必须走 Artisan 流程
维护模式不是“页面开关”,而是请求生命周期早期的硬拦截。一旦漏掉缓存清理、代理 IP 处理或集群同步,就容易变成“以为关了,其实没关”。











