直接运行 php artisan down 开启维护模式,依赖 storage/framework/down 文件标记状态;需先清配置缓存(config:clear),支持 –message 和 –retry 参数;多服务器需同步该文件;ip白名单需在 public/index.php 或事件中手动实现;注意视图/路由缓存、opcache 及 octane 兼容性。

laravel down命令怎么用
直接运行 php artisan down 就能开启维护模式,laravel 会自动返回 503 响应,并显示默认维护页面。它不是“开关文件”或改配置项,而是靠一个隐藏文件 storage/framework/down 标记状态。
常见错误是执行后没反应——其实是因为你开了缓存(比如 config:cache),Artisan 命令无法实时生效。必须先清掉配置缓存:php artisan config:clear,再执行 down。
- 支持传参:加
--message="稍候再见"自定义提示文本 - 加
--retry=60设置 http 头里的Retry-After秒数(影响浏览器重试逻辑) - 如果用了负载均衡或多台服务器,
down只影响当前机器——因为storage是本地目录
如何让部分IP绕过维护模式
Laravel 默认不支持白名单,但可以手动在 app/Http/Middleware/CheckforMaintenanceMode.php(Laravel 8 及以前)或中间件链里插一层判断。Laravel 9+ 已移除该中间件,维护逻辑收归 IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode 内部,不能直接覆盖。
更稳妥的做法是:在 app/Providers/AppServiceProvider.php 的 boot() 方法里监听 events,或直接在 public/index.php 开头加判断(虽然不优雅,但有效):
if (file_exists($maintenance = __DIR__.'/../storage/framework/down') && !in_array($_SERVER['REMOTE_ADDR'], ['123.45.67.89', '192.168.1.100'])) { header('HTTP/1.0 503 Service Unavailable'); include __DIR__.'/../storage/framework/down'; exit; }
- 别改
vendor里的源码——升级时会被覆盖 - 使用
$_SERVER['REMOTE_ADDR']要注意代理环境(如 nginx + Cloudflare),可能需要读X-Forwarded-For - 这个逻辑必须放在 Laravel 启动前,否则框架已抛出异常就来不及拦截
为什么 down 了但页面还是能访问
最常见原因是缓存——尤其是视图缓存和路由缓存。Laravel 在维护模式下仍会尝试加载缓存的路由或视图,导致跳过 503。
- 执行
php artisan view:clear和php artisan route:clear - 确认没在
AppServiceProvider或其他地方手动调用Route::get(...)动态注册路由(这些不会被down拦截) - 检查是否启用了 OPcache,且
opcache.enable_cli=1—— CLI 下的 Artisan 命令可能读到旧字节码 - 如果你用的是 Laravel Octane,
down不起作用,得改用php artisan octane:stop或配合反向代理控制
维护模式下 API 请求怎么处理
默认所有请求(包括 /api/*)都会被拦成 503。但很多系统需要让健康检查接口(如 /api/health)继续通。
做法是在 app/Exceptions/Handler.php 的 render() 方法里识别维护异常并放行特定路径:
if ($exception instanceof MaintenanceModeException && Str::startsWith($request->path(), 'api/health')) { return response()->json(['status' => 'ok'], 200); }
- 别用中间件做这事——维护模式触发早于中间件执行
- 确保
MaintenanceModeException类已引入:use IlluminateFoundationExceptionsMaintenanceModeException; - 如果用了 Sanctum 或 Passport,Token 验证失败也可能掩盖真实维护状态,建议先检查请求是否真进到了路由层
维护模式本质是文件锁 + 异常拦截,不是全链路闸机。任何绕过 Laravel 请求生命周期的操作(比如直接访问静态资源、通过队列触发的后台任务)都不会受它影响。