FrankenPHP: Máy chủ ứng dụng PHP hiện đại
(frankenphp.dev)- Trong quy trình triển khai muốn chạy ứng dụng PHP mà không cần PHP-FPM riêng, FrankenPHP là máy chủ ứng dụng dựa trên Go, tích hợp trình thực thi PHP chính thức vào Caddy, cho phép chạy ứng dụng web PHP và script CLI bằng một lệnh
- Gộp các tính năng cơ bản như HTTP/1.1, HTTP/2, HTTP/3, chứng chỉ HTTPS tự động, nén Brotli/Zstandard/Gzip, ghi log có cấu trúc và chỉ số Prometheus để giảm cấu hình máy chủ
- Worker mode khởi động ứng dụng một lần rồi giữ trong bộ nhớ; dự án cho biết trong benchmark tự thực hiện với ứng dụng API Platform, kết quả nhanh hơn FPM 3,5 lần
- Tương thích với PHP 8.2+, hầu hết extension PHP và module Caddy; đồng thời hỗ trợ native các extension phổ biến như OPcache và XDebug
- Hỗ trợ triển khai bằng image Docker, Kubernetes, nền tảng đám mây và binary tĩnh độc lập, giúp đơn giản hóa đơn vị triển khai ứng dụng PHP
Cách chạy và luồng sử dụng cơ bản
- FrankenPHP hướng tới vai trò máy chủ ứng dụng PHP hiện đại viết bằng Go, tổ chức việc cài đặt và chạy máy chủ ứng dụng PHP xoay quanh một lệnh
- Ví dụ cài đặt được chia theo hệ điều hành
- Linux/macOS:
curl https://frankenphp.dev/install.sh | sh - Windows PowerShell:
irm https://frankenphp.dev/install.ps1 | iex
- Linux/macOS:
- Chạy cục bộ bao quát cả máy chủ web lẫn CLI
frankenphp php-server -r public/: phục vụ thư mụcpublic/frankenphp php-cli script.php: chạy script PHP dòng lệnh
- Chạy bằng Docker cũng dùng cùng một image
- Phục vụ thư mục
public/bằng imagedunglas/frankenphp - Có thể chạy script CLI như
php script.phptrong cùng image
- Phục vụ thư mục
- Cấu hình dựa trên Caddy; ví dụ cấu hình bật nén trong block
localhostvà dùngphp_serverđể xử lý các file PHP cùng tài sản tĩnh trong thư mục hiện tại
Tính năng máy chủ và khả năng tương thích PHP
-
Tính năng máy chủ web
- Tích hợp trình thực thi PHP chính thức vào Caddy
- Hỗ trợ native HTTP/1.1, HTTP/2 và HTTP/3
- Tự động hóa việc tạo, gia hạn và thu hồi chứng chỉ HTTPS thông qua Let’s Encrypt hoặc ZeroSSL
- Hỗ trợ sẵn nén Brotli, Zstandard và Gzip
- Bao gồm ghi log có cấu trúc và hỗ trợ Prometheus
-
Môi trường thực thi PHP
- Tương thích với PHP 8.2+, hầu hết extension PHP và mọi module Caddy
- Hỗ trợ native các extension PHP phổ biến, gồm OPcache và XDebug
- Không cần PHP-FPM, sử dụng SAPI riêng được tạo cho máy chủ web Go
Worker mode và các tính năng hướng hiệu năng
- Worker mode khởi động ứng dụng một lần rồi giữ trong bộ nhớ, đặt ứng dụng ở trạng thái sẵn sàng xử lý yêu cầu chỉ trong vài mili giây
- Được hỗ trợ native trong Symfony, API Platform và Laravel
- Sử dụng các superglobal PHP hiện có mà không cần PSR-7
- Ngay cả khi ứng dụng không tương thích với Worker mode, vẫn có thể phục vụ như bình thường
- Cung cấp watcher tự động khởi động lại worker khi mã thay đổi
- Dự án giới thiệu rằng trong benchmark tự thực hiện dựa trên ứng dụng API Platform, hiệu năng nhanh hơn FPM 3,5 lần
Triển khai và đóng gói
- Có thể triển khai ứng dụng cloud-native bằng image Docker
- Tương thích với Kubernetes và các nền tảng đám mây hiện đại
- Có thể đóng gói ứng dụng web PHP và công cụ dòng lệnh thành binary tĩnh độc lập
- Dự án cho biết có thể chạy bằng một dịch vụ và một binary, không cần dịch vụ bên ngoài
Các tính năng nền tảng web bổ sung
- Hỗ trợ 103 Early Hints, được giới thiệu là tính năng có thể cải thiện 30% thời gian tải website dựa trên bài viết của Cloudflare
- Thông qua hub Mercure tích hợp sẵn, ứng dụng PHP có thể gửi event tới trình duyệt đã kết nối, và trình duyệt có thể nhận payload ngay lập tức dưới dạng event JavaScript
- Hỗ trợ triển khai không gián đoạn bằng graceful reload
1 bình luận
Ý kiến trên Hacker News
Nhân vật voi Frankenstein trông kỳ quặc, xấu xí mà dễ thương. Thiết kế, màu sắc, câu chữ và animation cũng gọn gàng. Với người đã rời xa việc phát triển PHP một thời gian, value proposition được thể hiện rõ, và trông có vẻ phù hợp để bắt đầu nhanh những thứ nhỏ
Tôi không muốn chạy 8 container chỉ để cô lập phần mềm tệ hoặc dependency rối rắm. Tôi không thích kiểu thay vì đưa ra phần mềm có thể cài đặt được thì lại đóng gói câu “trên máy tôi chạy được” rồi ném ra thế giới. Vì hoài niệm thì có thể nghịch thử, nhưng không chắc tôi còn muốn đưa thứ như vậy vào môi trường production nữa không
Ngôn ngữ nên đi theo hướng này, thay vì theo kiểu cần cấu hình Apache hơi phức tạp như LAMP ngày trước
Tôi cũng định thử cái này, nhưng chưa từng gặp bottleneck với nginx hay Apache. Cả hai đều dựng lên được trong nhiều nhất vài phút
Nó chạy như một dịch vụ đơn lẻ giống Apache + mod_php, xử lý multiprocessing cho PHP và các ngôn ngữ khác, file tĩnh, reverse proxy, và có thể quản lý chính nó cùng PHP trong một cấu hình duy nhất theo kiểu runtime qua file hoặc socket: https://unit.nginx.org/configuration/#php
Ví dụ cấu hình thực tế ở https://github.com/PrivateBin/docker-unit-alpine/blob/master..., và image container tạo ra cũng có thể khá nhỏ: https://hub.docker.com/r/privatebin/unit-alpine
Ngoài việc restart Apache, tôi không nhớ là đã phải làm gì thêm đáng kể
Đại khái là
LoadModule proxy_fcgi_module "/usr/lib/apache2/modules/mod_proxy_fcgi.so"vàSetHandler "proxy:fcgi://127.0.0.1:9000". Cũng có ví dụ Nginx tương tự về mặt khái niệm với cách cấu hình Apache, bao gồm cả cài các package cần thiết: https://news.ycombinator.com/item?id=37443911Cũng có các container image build sẵn để đạt kết quả tương tự, nhưng nếu muốn xem bên trong vận hành thế nào thì có thể tự làm. Chắc chắn dễ hơn việc cấu hình thủ công Tomcat hay GlassFish trong các Java application server ngày xưa; và dù một lệnh chạy duy nhất trong bất kỳ môi trường nào vẫn tốt hơn, LAMP cũng không tệ đến thế so với các stack khác
Có binary thì cũng dễ đóng gói vào app Electron hơn
php -S 0.0.0.0:8000 public/index.phpNhưng nó single-thread và chậm nên không dành cho production. FrankenPHP trông có triển vọng, nhưng vấn đề giới hạn core/thread[2] cũng có vẻ có thể trở thành vấn đề trong production. Dù vậy, tôi có thể thử áp dụng vào dự án pure-todo[1] để xem có gặp cùng vấn đề không. Docker image mặc định trông khá tốt
1: https://github.com/sandreas/pure-todo
2: https://github.com/dunglas/frankenphp/discussions/294
Xem cảnh báo ở đầu trang: https://www.php.net/manual/en/features.commandline.webserver...
Tôi cũng không chắc lấy nó làm đối tượng so sánh trong bối cảnh này có công bằng không
PHP_CLI_SERVER_WORKERSthì có thể chạy với nhiều threadVới một site nhỏ có ít người dùng, tôi muốn biết sẽ thiếu những gì so với các môi trường “sẵn sàng cho production” khác
Họ nói chỉ với vài lệnh là sẵn sàng cho production và nhanh hơn FPM 3,5 lần, nhưng trong môi trường của tôi nó chạy ở mức khoảng 1% hiệu năng của FPM. Tôi cũng thử file thực thi nhưng vẫn cùng vấn đề; với hello world thì tôi kỳ vọng ít nhất 200K rps
Trong hầu hết benchmark, khi bật chế độ worker, FrankenPHP thường nhanh hơn FPM rất nhiều, khoảng 3 lần. Dù vậy vẫn có một số trường hợp ngoại lệ và đang được khắc phục cùng các maintainer PHP
Bản thân Caddy khi dùng cùng PHP vẫn cho hiệu năng rất tốt, nên đây là một tình huống khá kỳ lạ
Hiện tại nó nằm ở cuối với trạng thái did not complete
Có vấn đề về hiệu năng. Ngoài chuyện đó ra thì đây là một dự án thật sự nhiều hứa hẹn
Tuy nhiên tôi chưa đào sâu, và bài test cũng chạy trong Docker chứ không phải cấu hình thông thường. WordPress cũng gần như cấu hình mặc định, không có theme nặng, nên không phải điều kiện thực tế. Dù vậy tôi muốn thử lại và hiểu rõ hơn
Tuy nhiên, với 103 Early Hints có thể preload tài nguyên và giảm độ trễ tải trang 30%. Dù vậy FrankenPHP giúp bật HTTP cache cho WordPress dễ hơn và đơn giản hóa triển khai. Cũng có dự án chuyên cho WordPress và FrankenPHP, bao gồm HTTP cache tích hợp tùy biến cho WordPress dùng thư viện Souin Go: https://github.com/StephenMiracle/frankenwp
Có thể tiết kiệm thêm một chút bộ nhớ Apache và tạo dư địa xử lý nhiều request PHP hơn
docker run -v $PWD:/app/public -p 443:443 \ dunglas/frankenphpNếu muốn tự tạo Docker container để phục vụ ứng dụng, có vẻ các lệnh dưới đây là đủ để biến một Debian mới thành container cần thiết:
apt install -y apache2 libapache2-mod-phpvà cấu hình/etc/apache2/sites-enabled/000-default.confTôi cùng bạn bè duy trì một repository cho thấy quá trình đi từ con số 0 đến một web application đang chạy bằng nhiều ngôn ngữ và framework phổ biến: https://github.com/no-gravity/web_app_from_scratch
Mỗi lần bật xdebug, sau phiên debug lại phải restart Apache. Từ hôm qua tôi bắt đầu cấu hình apache2 dùng php-fpm, và tự hỏi liệu FrankenPHP này có phù hợp với chúng tôi, ít nhất là trong môi trường dev hay không. Tuy nhiên tôi không tìm thấy trong tài liệu cách cài các extension PHP
000-default.confmặc định của Apache có redirect từ 443 sang 80 không?Tôi cảm thấy FPM và kiến trúc share-nothing của nó từng là cốt lõi cho thành công của PHP từ lâu, nhưng đồng thời cũng là xiềng xích của PHP