
后端即时通讯【免费下载链接】laravel-websocketsWebsockets for Laravel. Done right.项目地址https://gitcode.com/gh_mirrors/la/laravel-websockets点击查看免费下载本文聚焦 laravel-websockets 包中的websockets:restart命令讲解如何像queue:restart一样在 Supervisor 托管环境下优雅地重启 WebSocket 服务器。读完本文你将掌握该命令的用法、10 秒内完成重启的底层原理、优雅关停软关停的完整流程以及搭配 Supervisor 实现零中断运维的实战配置。适用场景为什么 WebSocket 服务器需要优雅重启WebSocket 服务器是一个长期驻留的守护进程。官方建议在生产环境使用 Supervisor 这类进程管理器来保证它始终存活详见 部署文档。当你修改了配置、更新了代码、或注册了新的自定义路由参见 自定义 WebSocket 处理器之后往往需要重启服务器才能让改动生效。此时如果直接粗暴地 kill 进程正在连接中的客户端会立即断线且可能丢失状态。laravel-websockets 为此提供了与 Laravel 队列系统queue:restart类似的解决方案向正在运行的服务器广播一个重启信号让它优雅地关闭现有连接再交由 Supervisor 重新拉起进程。快速上手一条命令触发重启根据 官方文档 的定义使用方式极其简单与php artisan queue:restart的体验完全一致php artisan websockets:restart执行后终端会输出如下提示Broadcasted the restart signal to the WebSocket server!该命令本身没有参数选项其全部职责就是广播重启信号。自命令下达起最多 10 秒内正在运行的 WebSocket 服务器会完成软关停随后由 Supervisor配置了autorestarttrue自动把服务重新拉起。底层原理一如何广播重启信号websockets:restart的实现非常精简完整源码位于 src/Console/Commands/RestartServer.php核心逻辑只有两步public function handle() { Cache::forever( beyondcode:websockets:restart, $this-currentTime() ); $this-info( Broadcasted the restart signal to the WebSocket server! ); }通过 Laravel 的Cache门面以Cache::forever将当前时间戳写入固定键名beyondcode:websockets:restartforever表示该值永不过期直到下一次命令再次覆盖它在控制台输出成功提示。也就是说命令本身并不直接操作服务器进程它只是向共享的缓存写入一个信号值时间戳。服务器进程通过周期性地读取这个缓存键感知到时间戳变化后自行触发关停流程。一个关键前提Cache 驱动必须是共享且持久的从上述机制可以推断出一个重要约束命令进程与服务器进程必须能够读到同一个缓存值。生产环境应使用file、redis、memcached或database等持久化且跨进程共享的 Cache 驱动绝不能使用array驱动否则命令写入的信号只存在于当前 CLI 进程的内存中服务器进程根本读不到重启信号会静默丢失。这一点虽然未在文档中显式强调但从 RestartServer.php 与 StartServer.php 均通过Illuminate\Support\Facades\Cache读写同一键名的代码结构可以直接确认。底层原理二服务器端如何感知信号并触发软关停服务器端由websockets:serve命令StartServer.php驱动。该命令在启动时会调用configureRestartTimer()注册一个每 10 秒触发一次的周期性定时器public function configureRestartTimer() { $this-lastRestart $this-getLastRestart(); $this-loop-addPeriodicTimer(10, function () { if ($this-getLastRestart() ! $this-lastRestart) { $this-triggerSoftShutdown(); } }); } protected function getLastRestart() { return Cache::get( beyondcode:websockets:restart, 0 ); }工作流程如下服务器启动时将缓存中的重启时间戳读入内存变量$this-lastRestart作为基线事件循环每 10 秒执行一次回调调用getLastRestart()重新读取缓存中的时间戳若两次读取的值不一致说明有人执行过websockets:restart随即调用triggerSoftShutdown()进入优雅关停。这正是文档中最多 10 秒内服务器会被重启的由来——10 秒是轮询周期上限而不是延迟固定为 10 秒。实际等待时间取决于轮询定时器恰好落在哪个相位上最短可能仅需数毫秒。优雅关停Soft Shutdown完整流程triggerSoftShutdown()是整套机制的落点其实现见 StartServer.php展示了一个教科书式的优雅关停流程protected function triggerSoftShutdown() { $channelManager $this-laravel-make(ChannelManager::class); // 1. 关闭新连接入口 $channelManager-declineNewConnections(); // 2. 收集本地全部连接逐个触发 onClose 并关闭 $channelManager-getLocalConnections() -then(function ($connections) { return all(collect($connections)-map(function ($connection) { return app(websockets.handler) -onClose($connection) -then(function () use ($connection) { $connection-close(); }); })-toArray()); }) -then(function () { // 3. 全部连接处理完毕后停止事件循环 $this-loop-stop(); }); }三个阶段环环相扣拒绝新连接调用ChannelManager::declineNewConnections()将实例内部标记acceptsNewConnections置为false对应 LocalChannelManager.php此后新的 WebSocket 握手请求将不再被接受逐个关闭现有连接通过getLocalConnections()获取当前实例上的所有连接逐个交给websockets.handler的onClose()完成反订阅清理连接会自动从所有频道中注销随后调用$connection-close()真正断开。这些操作以 React Promise 链式串联全部完成前不会进入下一步停止事件循环所有连接优雅关闭后$this-loop-stop()让进程自然退出。进程退出后Supervisor 检测到子进程结束配置了autorestarttrue会自动重新启动websockets:serve新进程从缓存读取到的是更新后的重启时间戳基线从而继续正常运行。与 SIGTERM/SIGINT 软关停的异同值得一提的是同样的triggerSoftShutdown()也被用于处理系统信号。在 StartServer.php 中当 PCNTL 扩展可用时服务器会注册 SIGTERM 与 SIGINT 的监听器收到信号后打印Closing existing connections...并执行同样的软关停流程$this-loop-addSignal(SIGTERM, function () { $this-line(Closing existing connections...); $this-triggerSoftShutdown(); }); $this-loop-addSignal(SIGINT, function () { $this-line(Closing existing connections...); $this-triggerSoftShutdown(); });两者的区别在于触发源websockets:restart由外部命令驱动通过缓存信号触发适合在部署脚本、CI 流程或运维操作中调用SIGTERM/SIGINT由操作系统驱动例如手动CtrlC或执行kill时触发。殊途同归两者最终都走declineNewConnections()→ 逐个onClose()→loop-stop()这条优雅路径确保连接不丢失、频道状态被正确清理。相关行为在 StartServerTest.php 中有对应测试test_pcntl_sigint_signal与test_pcntl_sigterm_signal均会先建立活跃连接再发送信号。结合 Supervisor 的完整运维方案既然优雅重启依赖 Supervisor 自动拉起进程这里给出完整的配套配置。首先安装 SupervisorDebian/Ubuntuapt install supervisorRed Hat/CentOSyum install supervisor并systemctl enable supervisord然后在/etc/supervisor/conf.dDebian/Ubuntu或/etc/supervisord.dRed Hat/CentOS下创建websockets.conf[program:websockets] command/usr/bin/php /home/laravel-echo/laravel-websockets/artisan websockets:serve numprocs1 autostarttrue autorestarttrue userlaravel-echo加载配置并启动supervisorctl update supervisorctl start websockets supervisorctl status这样一套组合的日常运维节奏是发布新代码、修改配置或注册新路由后执行php artisan websockets:restart服务器在 10 秒内优雅关闭所有连接并退出Supervisor 检测到进程退出立即自动重启websockets:serve服务无缝衔接。完整的 Supervisor 部署说明包括minfds打开文件数上限调整可参考 部署文档服务启动参数如--host、--port详见 启动文档。多实例 / 多服务器场景下的行为从机制上看该重启信号是广播式的所有运行中的 WebSocket 服务器实例都会周期性地读取同一个缓存键因此一次websockets:restart会让集群中的每个实例都在各自的事件循环内感知到信号变化并各自执行软关停。在多节点横向扩展部署时参见 横向扩展文档这意味着你只需要在任意一台机器上执行一次命令即可对整个集群发出重启请求无需逐个节点操作。测试与验证仓库为这套机制提供了自动化测试保障tests/Commands/RestartServerTest.php 中的test_it_can_broadcast_restart_signal验证了执行websockets:restart后缓存键beyondcode:websockets:restart的值会更新为当前时间assertGreaterThanOrEqual断言新值不小于执行前的时间tests/Commands/StartServerTest.php 则验证了服务器在 SIGINT / SIGTERM 信号下能够正常完成软关停间接佐证了triggerSoftShutdown()流程的可用性。你也可以在自己的环境中手动验证先以php artisan websockets:serve启动服务器并保持终端在前台运行另开一个终端执行php artisan websockets:restart观察服务器终端——它会在 10 秒内安静地完成关停流程并退出若由 Supervisor 托管则会立刻看到进程被重新拉起。常见问题与注意事项重启命令没有生效优先检查 Laravel 的 Cache 驱动配置。array驱动下信号无法跨进程传递同时确认服务器进程与命令运行在同一个应用实例/同一个.env配置下二者读取的缓存后端必须一致。10 秒是从哪里来的来自 StartServer.php 中addPeriodicTimer(10, ...)的轮询周期这是最迟 10 秒而非固定 10 秒。为什么是优雅关闭而非强杀软关停会先拒绝新连接、再逐个清理频道订阅关系、最后才停止事件循环避免客户端数据与频道成员状态不一致强杀进程则可能留下脏状态。务必配合进程管理器使用websockets:restart只是发出信号它不会自己拉起新进程。没有 Supervisor 守护时进程退出后将不再提供服务此时需要手动重新执行php artisan websockets:serve。赞分享后端即时通讯【免费下载链接】laravel-websocketsWebsockets for Laravel. Done right.项目地址https://gitcode.com/gh_mirrors/la/laravel-websockets点击查看免费下载相关推荐零停机重启革命Goagain优雅重启原理解析零停机重启革命Goagain优雅重启原理解析 引言服务重启的痛点与解决方案 你是否曾因服务重启导致用户请求失败而头疼在高可用系统架构中零停机部署后端gorilla/mux优雅关闭实现零停机部署的平滑重启机制gorilla/mux优雅关闭实现零停机部署的平滑重启机制 痛点为什么需要优雅关闭 在现代微服务架构中服务部署和更新是家常便饭。传统的粗暴关闭方式会导致后端Laravel Octane 命令详解启动、停止、重载等所有操作指南Laravel Octane 命令详解启动、停止、重载等所有操作指南 Laravel Octane 是专为 Laravel 应用程序设计的性能加速工具通过利后端开发工具上一篇3大核心技术深度解析MFCUK从DarkSide攻击到MiFare Classic安全研究实战下一篇Olares files 路径语法与命名空间规则全解从 drive/Home 到云盘账号的地址体系与命令约束创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考