当前位置: 首页 > news >正文

传统Laravel项目零改动迁移到FrankenPHP的完整流程

传统 Laravel 零改动迁移到 FrankenPHP 完整流程>先把最重要的一句话说在前面,免得你迁移到一半发现被坑: ▎ 「零改动」只在「经典模式」下成立。 经典模式=把 FrankenPHP 当成一个更快的 Nginx+PHP-FPM 替代品,你的 Laravel ▎ 代码一行都不用动。 ▎ ▎ 而「Worker 模式」(性能翻几倍那个)不是零改动——它需要装laravel/octane ▎ 这个官方包,并且你的代码得满足「无状态」要求(第10章讲过的那些泄漏陷阱)。 所以这篇分两段走:先零改动跑起来(经典模式),再可选地榨性能(worker 模式)。两条路我都给完整流程。---第一部分:真·零改动迁移(经典模式) 步骤0:迁移前盘点你现在的架构 传统 Laravel 生产环境通常长这样: 浏览器 →Nginx(收 HTTP、发静态文件、反代) →PHP-FPM(跑 PHP,通过 FastCGI 协议) →public/index.php →Laravel 涉及的配置文件:-nginx.conf/sites-available/xxx(Nginx 站点配置)-php-fpm.conf/www.conf(FPM 进程池配置)-php.ini FrankenPHP 把 Nginx+PHP-FPM 两个东西合并成一个进程,所以上面这套全部不再需要,换成一个 Caddyfile(或者干脆零配置)。 步骤1:装 FrankenPHP FrankenPHP 官方发布的是单个静态二进制(第12章讲的静态链接 libphp 那条路的成品),里面已经内置了 PHP 解释器和常用扩展,你机器上甚至不需要装 PHP。 方式 A:直接下二进制(最省事)#Linux x86_64curl https://frankenphp.dev/install.sh | shsudo mv frankenphp/usr/local/bin/# 验证:里面这个 PHP 是什么版本、带哪些扩展 frankenphp php-cli-v frankenphp php-cli-m # 列出内置扩展,先确认你 Laravel 要的扩展都在 方式 B:Docker(生产推荐,环境最干净)#Dockerfile ——这是迁移 Laravel 的标准官方镜像FROM dunglas/frankenphp:latest # 装 Laravel 常用的 PHP 扩展(官方镜像带了 install-php-extensions 工具) RUN install-php-extensions \ pdo_mysql \ redis \ intl \ gd \ zip \ bcmath \ opcache \ pcntl # 把你的 Laravel 项目拷进镜像默认的网站根目录 COPY./app WORKDIR/app # 装依赖(生产参数) RUN composer install--no-dev--optimize-autoloader ▎ 关键检查点:迁移前一定先用 frankenphp php-cli-m 或 install-php-extensions 把你 composer.json 里 ext-*▎ 要求的扩展全配齐。Laravel ▎ 常见依赖:pdo_mysql/pdo_pgsql、mbstring、openssl、tokenizer、xml、ctype、json、bcmath、fileinfo、redis(如果用 ▎ Redis)、intl、gd/imagick(如果处理图片)、pcntl(如果用队列--timeout)。少装扩展是迁移最常见的翻车点。 步骤2:让 FrankenPHP 指向 Laravel 的入口 Laravel 的 HTTP 入口永远是 public/index.php,所有请求都被 rewrite 到它(这就是 Laravel 的「前端控制器」模式)。FrankenPHP 内置了对这个模式的支持,一个命令零配置就能跑: # 进到 Laravel 项目根目录 cd/path/to/your-laravel # 一行启动,--root 指向 public 目录 frankenphp php-server--root public/就这一行。它会:-:443(带自动 HTTPS)或开发时:80起一个服务器-自动把所有请求按 Laravel 的规则 rewrite 到 public/index.php-静态文件(public/下的 css/js/图片)直接由服务器高速返回,不走 PHP 打开浏览器访问,你的 Laravel 原封不动就跑起来了。代码零改动。 步骤3:用 Caddyfile 做正经配置(生产) php-server 命令适合快速验证,生产环境用 Caddyfile 更可控。一个标准的 Laravel Caddyfile 长这样,逐行解释:#Caddyfile ——放在项目根目录{# 全局选项块 frankenphp # 启用 FrankenPHP 模块#auto_https off # 本地开发想关 HTTPS 时取消注释}your-domain.com{# 你的域名;Caddy 会自动申请并续签 Let's Encrypt 证书 root*public/# ★网站根目录指向 Laravel 的 public/encode zstd br gzip # 自动压缩响应(zstd/brotli/gzip) php_server # ★核心:把请求交给内置 PHP 处理, # 自动处理 index.php rewrite、静态文件分流}逐行大白话:-frankenphp:在全局块里打开 FrankenPHP。-your-domain.com{}:一个站点块。Caddy 最大的福利——自动HTTPS:你写个真实域名,它自动去 Let's Encrypt 申请证书、自动续期,0配置。传统 Nginx 你得手搓 certbot。-root*public/:告诉服务器网站根是 public/(Laravel 的 web 根),其它目录(app/、vendor/.env)天然不暴露,安全。-encode...:响应压缩,替代 Nginx 的 gzip on。-php_server:一条指令顶 Nginx 一大段 location~\.php$+fastcgi_pass。它内部等价于:-请求的是存在的静态文件 →直接返回-否则 →rewrite 到 index.php 交给 PHP 跑 启动: frankenphp run # 它会自动找当前目录的 Caddyfile # 或指定: frankenphp run--config/path/to/Caddyfile 步骤4:把 PHP-FPM 和 Nginx 的配置「翻译」过来 迁移时你旧配置里的设置要找到对应位置: ┌─────────────────────────────────────┬──────────────────┬────────────────────────────────────────────────────────┐ │ 你原来在哪配 │ 原来怎么写 │ FrankenPHP 里怎么配 │ ├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────────────┤ │ php.ini 的 │ │ 还是 php.ini。用 frankenphp run 时它读环境里的 │ │ memory_limit、upload_max_filesize │ php.ini │ php.ini;Docker 镜像里在 │ │ 等 │ │ $PHP_INI_DIR/php.ini。改法不变 │ ├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────────────┤ │ │ │ Caddyfile 里 request_body{max_size20MB},或 │ │ Nginx client_max_body_size20M │ nginx.conf │ php.ini 的 │ │ │ │ upload_max_filesize/post_max_size(两边取小) │ ├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────────────┤ │ FPM pm.max_children(进程数) │ http://www.conf │ Caddyfile 的 frankenphp { num_threads N },控制 PHP ││ │ │ 线程数 │ ├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────────────┤ │ Nginx 静态文件缓存头 │ location~*│ Caddyfile 的 header 指令,或交给 php_server 默认处理 │ │ │ \.(jpg|css)$ │ │ ├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────────────┤ │ Nginx 反代/负载均衡 │ upstream │ Caddy 的 reverse_proxy,但单机场景通常不需要了 │ └─────────────────────────────────────┴──────────────────┴────────────────────────────────────────────────────────┘ 设置线程数的写法:{frankenphp{num_threads40# 类比 FPM 的 pm.max_children,按内存和负载调}}步骤5:迁移验证清单(逐项打勾) 零改动不代表零验证。挨个确认: #1)扩展齐不齐(最常翻车) frankenphp php-cli-m|sort # 对照 composer.json 里所有"ext-xxx"#2)Laravel 的缓存先清,避免旧路径残留 php artisan config:clear&&php artisan route:clear&&php artisan view:clear #3)生产优化缓存(这些和 FPM 时一模一样,不变) php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache #4)文件权限(storage 和 bootstrap/cache 要可写) chmod-R ug+rw storage bootstrap/cache 功能层面要手动点一遍的:-✅ 普通页面渲染(GET)-✅ 表单提交、文件上传(POST+multipart,验证 read_post 那条链路)-✅ Session/登录态(Cookie,验证 read_cookies)-✅ 文件下载、大响应(验证 ub_write 流式输出)-✅ php artisan 命令照常能跑(CLI 不受影响)-✅ 队列 worker(php artisan queue:work)和定时任务(schedule:run)——这些是独立进程,迁移不影响它们,照旧用 supervisor/cron 跑 步骤6:队列、定时任务、Horizon 怎么办 这是迁移时容易忽略的:FrankenPHP 只负责 HTTP 那一半。Laravel 的后台部分是独立的: # 定时任务:crontab 不变,照旧*****cd/path/to/laravel&&php artisan schedule:run>>/dev/null2>&1# 队列:supervisor 配置不变,照旧用 php-cli 跑 #/etc/supervisor/conf.d/laravel-worker.conf[program:laravel-worker]command=php/path/to/laravel/artisan queue:work--sleep=3--tries=3注意 php 这里如果系统没装 PHP,用 frankenphp php-cli/path/to/artisan queue:work。FrankenPHP 二进制本身就能当 php 命令用。 到这一步,经典模式迁移完成,代码零改动,已经能上生产。性能通常已经比 Nginx+FPM 略好(少了 FastCGI 协议开销),且运维简化(一个进程、自动 HTTPS)。---第二部分:榨性能(Worker 模式,非零改动但收益巨大) 如果你想要 FrankenPHP 那个「快3-4倍」的效果,上 worker 模式。这需要 Laravel Octane(官方包,专门适配 Swoole/RoadRunner/FrankenPHP)。 为什么 worker 模式快:回顾第7章 经典模式每个请求都要:require autoload →启动整个 Laravel 框架(注册几百个服务、解析路由、读配置)→处理 → 全部销毁。Laravel 框架启动本身就要几十毫秒,90%的时间花在重复启动框架上。 Worker 模式:框架只启动一次常驻内存,之后每个请求复用,省掉那几十毫秒。 步骤1:装 Octane composer require laravel/octane # 安装并选 FrankenPHP 作为 server php artisan octane:install--server=frankenphp 这会装好 Octane 并配置成用 FrankenPHP 的 worker 模式。 步骤2:启动 # 开发 php artisan octane:start--server=frankenphp--watch # ↑改代码自动重载(第11.5节那个热重载) # 生产 php artisan octane:start--server=frankenphp--workers=4--max-requests=500#--workers worker 线程数,一般=CPU 核数 #--max-requests 每个 worker 处理 N 个请求后重启,防内存泄漏的安全阀--max-requests 很重要:它是「定期重启 worker」的兜底机制,就算你代码有轻微泄漏,跑500个请求就重启清零,不至于 OOM。 步骤3:代码体检(这是「非零改动」的核心工作) Worker 模式下框架常驻,第10章讲的所有泄漏陷阱都要排查。针对 Laravel 具体化: ①静态属性/单例累积// ☠️危险class SomeService{privatestaticarray $cache=[];// worker 模式下永不清空}排查:grep 你代码里的static属性容器、static$x=[]。 ②容器里被你手动绑定的「请求作用域」单例// 如果你在 ServiceProvider 里这样绑过单例,且它持有了请求数据:$this->app->singleton(CurrentTenant::class,...);// 小心:会跨请求残留Octane 提供了配置来每个请求后重置指定服务:// config/octane.php'warm'=>[...],// 每个请求前预热的服务'flush'=>[...],// 每个请求后清空的服务 ←把有状态的放这'listeners'=>[RequestReceived::class=>[...],RequestTerminated::class=>[FlushTemporaryContainerInstances::class,// Octane 自带的清理],],③Octane 内存泄漏检测 Octane 自带工具帮你定位: # 它会报告哪些请求导致内存持续增长 php artisan octane:start--server=frankenphp # 配合监控 memory_get_usage,或用--max-requests 兜底 ④Laravel 官方已知要注意的点(Octane 文档明确列出):-不要用 $request 的全局 helper 缓存:用 Auth::user()等没问题(Octane 会重置),但你自己static缓存了request()就会串台。-配置/容器单例里别存请求数据。-第三方包:确认你用的包兼容 Octane(大部分主流包已兼容)。 步骤4:迁移决策——到底用不用worker 模式 ┌──────────┬──────────────────────┬──────────────────────────────┐ │ 维度 │ 经典模式 │ Worker 模式(Octane)│ ├──────────┼──────────────────────┼──────────────────────────────┤ │ 代码改动 │ 零 │ 需排查无状态,可能改少量代码 │ ├──────────┼──────────────────────┼──────────────────────────────┤ │ 性能 │ 比 FPM 略好 │ 比 FPM 快3-4倍 │ ├──────────┼──────────────────────┼──────────────────────────────┤ │ 迁移风险 │ 极低 │ 中(状态泄漏风险) │ ├──────────┼──────────────────────┼──────────────────────────────┤ │ 适合 │ 想平滑替换 Nginx+FPM │ 高并发、追求极致吞吐 │ └──────────┴──────────────────────┴──────────────────────────────┘ 我的建议:分两步走。先经典模式零改动上生产、稳住(享受简化运维和自动 HTTPS),跑一段时间确认无误;之后再单独立项做 Octane 改造,在 staging 环境充分压测和泄漏排查后再切。别一步到位把「换服务器」和「改架构」两件事混在一次上线里——出问题难定位。---完整迁移路线图(一张图收尾) 现状:Nginx+PHP-FPM+Laravel │ ├─【第一阶段:零改动】─────────────────────────── │1.装 FrankenPHP(二进制 or Docker dunglas/frankenphp) │2.用 install-php-extensions 配齐扩展(对照 composer.json)★最易翻车 │3.写 Caddyfile:root →public/,php_server 一行搞定 │4.把 php.ini/FPM/Nginx 设置翻译过来(见对照表) │5.artisan config:cache/route:cache(和原来一样) │6.队列/定时任务用 frankenphp php-cli 跑,supervisor/cron 不变 │7.功能清单逐项验证(POST/Session/上传/下载) │ →上生产。代码零改动,运维简化,自动 HTTPS,性能略升 │ └─【第二阶段:可选提速】──────────────────────────1.composer require laravel/octane2.artisan octane:install--server=frankenphp3.★体检无状态:static属性、请求作用域单例、连接事务状态4.config/octane.php 配 flush 清理有状态服务5.octane:start--workers=N--max-requests=500(兜底防泄漏)6.staging 压测+内存监控,确认无泄漏 →切生产。性能3-4倍 三句话记住:1.经典模式=真零改动,root public/+php_server 一行,把它当更好用的 Nginx+FPM。2.迁移最大的坑是扩展没配齐,先 frankenphp php-cli-m 对照 composer.json。3.要极致性能上 Octane worker 模式,但那不是零改动——得排查第10章那些跨请求状态泄漏,用--max-requests 兜底。
http://www.jsqmd.com/news/1063601/

相关文章:

  • 软件测试报告万字文,在线教育系统在线教育系统(单元测试,功能测试,性能测试,缺陷测试)1 包含文档仅文档:(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • 新手如何选购尤克里里?从材质到尺寸!2026零基础尤克里里选购指南
  • Kimi K2.5:Agentic Native时代下的多模态智能体范式革命
  • GTA IV终极修复指南:FusionFix让经典游戏焕发新生
  • SPT-AKI存档编辑器:终极免费工具,5分钟掌握塔科夫离线存档完全掌控权
  • 包装设计公司怎么选不踩坑?2026 十大机构能力画像与适配指南 - 资讯速览
  • 2026阳江营业性演出许可证代办推荐哪家专业靠谱 - 资讯速览
  • 2026年申请美国藤校哪家机构最擅长,别急着签约先把这些细节看明白 - 环球新视野
  • 丢掉 Scrapy 的厚重,试试 Crawl4AI:专为大模型时代打造的轻量级网页抓取利器
  • 3步完成AI视频无损放大:免费工具Video2X终极使用指南
  • LS2088A SEC模块AIOP接口寄存器详解与故障诊断实战
  • 2026年武汉黄金回收认准本地老店!无套路高价变现超省心 - 奢侈品交易观察员
  • PMSM矢量控制软件架构:数据流与状态机设计实践
  • 如何快速部署Discuit:打造属于你的开源社区讨论平台
  • 使用wechatapi开发AI客服知识库怎么维护?避免机器人自由发挥
  • DeepSeek V4-Flash原理与实战:ima中间件驱动的低延迟API通道
  • 2026年深圳高考复读TOP榜单发布:哪些机构值得选? - 运营老默复盘
  • DeepSeek-V4极致底层重构:MoE路由如何从软件层焊死到CUDA硬件
  • DSP56321串行通信接口(ESSI/SCI)编程模型与实战避坑指南
  • 中山名酒回收终极指南:三类商家套路全解析,认准这家名酒回收商家才靠谱 - 爱吃西瓜的西高地
  • Swagger接口测试实战:从文档到自动化测试的完整指南
  • 基于GPT-4o的医学影像问答对自动化生成:提示工程与质量保证实践
  • 上海嘉定江桥汽车音响探店实录|20 年老店音乐人生,本地车主实测靠谱改装门店 - 音乐人生汽车音响
  • LLM符号推理框架:融合皮尔斯逻辑与Gamma Quintet提升大模型可靠性
  • 宝马汽车音响推荐排行:2026年车载音响升级品牌榜单,从入门到旗舰一网打尽 - 资讯快报
  • CentOS 8部署MariaDB实战:从初始化失败到生产加固
  • LLM辅助智能合约形式化验证:从VMTLC规约到安全实践
  • 基于MPC5xx与CAN总线的机器人手臂分布式控制系统设计实战
  • 2026年实测AI论文网站榜单(合规高效版)
  • 用友NC任意文件上传漏洞深度剖析与实战复现指南