news 2026/3/27 16:08:05

FrankenPHP实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FrankenPHP实践

目录

1. 说明

2. 程序修改

3. 性能测试

4. 配置

4.1 Docker化部署

4.2 Caddy泛域名和证书设置

4.3 相关命令

5. 要点:

6. 参考


1. 说明

Frankenphp是一个先进的,结合了高性能Caddy服务器的PHP环境框架,它允许用户只需要少量改动,就能让传统的php前端应用插上翅膀,享受到异步服务带来的量级提升体验,官网:https://frankenphp.dev。

它实际上是有两种运行模式:普通模式和worker模式,其中的普通模式类似于传统的LNMP容器,只是Nginx换成了Caddy Server,带来的提升并不特别明显。而worker模式就不同了,效果是原来性能的三倍左右。

2. 程序修改

以TP6为例,用worker模式的话,入口程序需改由frankenphp_handle_request包裹使用,参考官网docs:FrankenPHP: the modern PHP app server

<?php ignore_user_abort(true); require __DIR__ . '/../vendor/autoload.php'; $thinkApp = new hinkApp(); $http = $thinkApp->http; $handler = static function () use ($http) { // 初始化并处理请求 $response = $http->run(); // 发送响应 $response->send(); // 返回响应后终止应用 $http->end($response); }; $maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0); for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests) { // 处理请求 $keepRunning = rankenphp_handle_request($handler); // 执行一些在发送 HTTP 响应后的操作 gc_collect_cycles(); // 垃圾回收 if (!$keepRunning) break; }
3. 性能测试

Performance benchmark of PHP runtimes - DEV Community

4. 配置
4.1 Docker化部署
  • docker-compose.yml,其中: 证书路径映射到 /data0/Server/Auths/certs

  • 多个应用需添加不同的worker入口描述

    compose.yaml

    services:
    php:
    container_name: frankenphp
    # image: dunglas/frankenphp
    build:
    dockerfile: frankenphp.Dockerfile
    context: ./docker
    restart: always
    # restart: unless-stopped
    # uncomment the following line if you want to use a custom Dockerfile
    #build: .
    environment:
    SERVER_NAME: php:80
    MAX_REQUESTS: 600
    FRANKENPHP_CONFIG: |
    worker {
    file /app1/public/index.php
    num 42
    watch
    }
    worker {
    file /app2/public/index.php
    num 42
    watch
    }
    #CADDY_SERVER_EXTRA_DIRECTIVES: try_files {path} {path}/ /index.php?s=/{path}&{query}
    CADDY_SERVER_EXTRA_DIRECTIVES: |
    try_files {path} {path}/ /index.php?s=/{path}&{query}
    ports:
    - “80:80” # HTTP
    - “443:443” # HTTPS
    - “443:443/udp” # HTTP/3
    volumes:
    - /data0/Server/Logs/caddy:/logs
    # - /data0/Projects/Test/test001:/app/public
    #- /home/website/ad_serving_backend:/app # App src
    - /home/website/app1:/app1 # App1 src
    - /home/website/app2:/app2 # App2 src
    - /data0/Server/Settings/caddy/Caddyfile:/etc/caddy/Caddyfile
    - /data0/Server/Db/caddy:/data
    - /data0/Server/Settings/caddy/config:/config
    - /data0/Server/Auths/certs:/certs
    # comment the following line in production, it allows to have nice human-readable logs in dev
    tty: true

4.2 Caddy泛域名和证书设置

尽管Caddy自带无敌好感的自注册安全证书机制,但有时候我们还是需要手动部署一些已有的证书(nginx原有证书即可),这时我们要编辑Caddyfile做定制:

{ {$CADDY_GLOBAL_OPTIONS} frankenphp { #worker /path/to/your/worker.php {$FRANKENPHP_CONFIG} } # Logging log { output stderr level INFO #level DEBUG } } {$CADDY_EXTRA_CONFIG} {$SERVER_NAME:localhost} { #log { # # Redact the authorization query parameter that can be set by Mercure # format filter { # request>uri query { # replace authorization REDACTED # } # } #} root * public/ encode zstd br gzip # Uncomment the following lines to enable Mercure and Vulcain modules #mercure { # # Transport to use (default to Bolt) # transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db} # # Publisher JWT key # publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG} # # Subscriber JWT key # subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG} # # Allow anonymous subscribers (double-check that it's what you want) # anonymous # # Enable the subscription API (double-check that it's what you want) # subscriptions # # Extra directives # {$MERCURE_EXTRA_DIRECTIVES} #} #vulcain {$CADDY_SERVER_EXTRA_DIRECTIVES} php_server } app1.com { #log { # # Redact the authorization query parameter that can be set by Mercure # format filter { # request>uri query { # replace authorization REDACTED # } # } #} root * /app1/public/ encode zstd br gzip tls /certs/app1.com/serv.pem /certs/app1.com/serv.key {$CADDY_SERVER_EXTRA_DIRECTIVES} log { output file /logs/app1.com.log { rotate_size 100 # Rotate after 100 MB rotate_keep 5 # Keep at most 20 log files roll_keep_for 72h } } php_server } app2.com { root * /app2/public/ encode zstd br gzip tls /certs/app2.com/serv.pem /certs/app2.com/serv.key {$CADDY_SERVER_EXTRA_DIRECTIVES} log { output file /logs/app2.com.log { rotate_size 100 # Rotate after 100 MB rotate_keep 5 # Keep at most 20 log files roll_keep_for 72h } } php_server }
4.3 相关命令
docker compose down && docker compose up -d --wait # 修改配置后重拉容器 docker compose -f /data0/Server/Settings/docker-compose/frankenphp/docker-compose.yml down && docker compose -f /data0/Server/Settings/docker-compose/frankenphp/docker-compose.yml up -d --wait # restart docker compose -f /data0/Server/Settings/docker-compose/frankenphp/docker-compose.yml restart # 日志 docker logs frankenphp
5. 要点:

如果自建镜像扩展插件,需三思是否需要加Opcache,开启后 frankenphp 的watch功能(监控文件修改自动热启)将不能正常使用,但开启后,性能将提高40%左右。

6. 参考

-FrankenPHP: the modern PHP app server

-Performance benchmark of PHP runtimes - DEV Community

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 4:28:19

深入解析DDR内存原理、测试方法及在嵌入式系统中的应用

文章目录摘要1. DDR内存核心技术解析1.1 物理架构与存储原理1.2 关键时序参数2. DDR测试方法与工具链2.1 测试环境搭建2.2 MemTest86测试流程3. 嵌入式系统集成实践3.1 ARM Cortex-A内存控制器配置4. 完整测试代码实现5. 常见问题解决5.1 信号完整性问题6. 成果展示技术图谱摘要…

作者头像 李华
网站建设 2026/3/27 8:38:00

交通仿真软件:Aimsun_(3).Aimsun基本操作

Aimsun基本操作 创建和配置仿真网络 在Aimsun中&#xff0c;创建和配置仿真网络是仿真过程的第一步。仿真网络是交通仿真的基础&#xff0c;它包括道路网络、交叉口、交通信号、交通流等基本元素。本节将详细介绍如何在Aimsun中创建和配置仿真网络&#xff0c;以及如何导入和导…

作者头像 李华
网站建设 2026/3/23 8:30:39

docker下搭建redis集群

1. 环境准备 准备好Linux系统机器&#xff0c;并安装好docker&#xff0c;阅读这篇文章前请先了解清楚docker的基本知识并且会熟悉运用docker的常用命令。学习docker基础知识可以参考这篇博文 安装好并启动docker后就可以开始搭建redis了 2. docker容器下安装redis 本篇文章…

作者头像 李华
网站建设 2026/3/23 23:26:44

docker 安装 mysql

目录 一、下载mysql镜像 1.查看你自己的镜像下载 ?2.运行一个mysql容器 方法一、?直接运行 方法二、创建脚本 直接使用脚本运行 3.连接数据库 一、下载mysql镜像 docker pull mysql:5.71.查看你自己的镜像下载 docker images?2.运行一个mysql容器 方法一、直接运行…

作者头像 李华
网站建设 2026/3/25 22:04:45

二分猜答案

二分前后缀分解lc786二分查找分数值范围&#xff0c;统计小于等于中间值的分数个数&#xff0c;定位第k小的素数分数并返回#include <vector> using namespace std;class Solution { private:vector<int> arr;int n, a, b; public:vector<int> kthSmallestPr…

作者头像 李华
网站建设 2026/3/22 2:28:32

信使(msner)(信息学奥赛一本通- P1376)四种做法

【题目描述】战争时期&#xff0c;前线有n个哨所&#xff0c;每个哨所可能会与其他若干个哨所之间有通信联系。信使负责在哨所之间传递信息&#xff0c;当然&#xff0c;这是要花费一定时间的&#xff08;以天为单位&#xff09;。指挥部设在第一个哨所。当指挥部下达一个命令后…

作者头像 李华