4 คะแนน โดย GN⁺ 2024-05-31 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในเวิร์กโฟลว์การดีพลอยที่ต้องการรันแอป PHP โดยไม่ต้องมี PHP-FPM แยกต่างหาก FrankenPHP คือแอปเซิร์ฟเวอร์บน Go ที่ฝัง ตัวรัน PHP อย่างเป็นทางการไว้ใน Caddy ทำให้รันเว็บแอป PHP และสคริปต์ CLI ได้ด้วยคำสั่งเดียว
  • รวม HTTP/1.1, HTTP/2, HTTP/3, ใบรับรอง HTTPS อัตโนมัติ, การบีบอัด Brotli/Zstandard/Gzip, structured logging และเมตริก Prometheus เป็นฟีเจอร์พื้นฐาน เพื่อลดการตั้งค่าเซิร์ฟเวอร์
  • Worker mode บูตแอปหนึ่งครั้งแล้วคงไว้ในหน่วยความจำ โดยอธิบายว่าจากเบนช์มาร์กของแอป API Platform เองให้ผลลัพธ์ เร็วกว่า FPM 3.5 เท่า
  • เข้ากันได้กับ PHP 8.2+, ส่วนขยาย PHP ส่วนใหญ่ และโมดูล Caddy รวมถึงรองรับส่วนขยายยอดนิยมอย่าง OPcache และ XDebug แบบเนทีฟ
  • รองรับ Docker image, Kubernetes, แพลตฟอร์มคลาวด์ และการดีพลอยเป็นไบนารีสแตติกแบบ standalone ช่วยทำให้ หน่วยการดีพลอยแอป PHP เรียบง่ายขึ้น

วิธีรันและโฟลว์การใช้งานพื้นฐาน

  • FrankenPHP มุ่งเป็น แอปเซิร์ฟเวอร์ PHP สมัยใหม่ที่เขียนด้วย Go โดยจัดโครงสร้างการติดตั้งและการรันแอปเซิร์ฟเวอร์ PHP ให้เน้นคำสั่งเดียว
  • ตัวอย่างการติดตั้งแบ่งตามระบบปฏิบัติการ
  • การรันบนเครื่องรองรับทั้งเว็บเซิร์ฟเวอร์และ CLI
    • frankenphp php-server -r public/: เสิร์ฟไดเรกทอรี public/
    • frankenphp php-cli script.php: รันสคริปต์ PHP บน command line
  • การรันด้วย Docker ก็ใช้ image เดียวกัน
    • เสิร์ฟไดเรกทอรี public/ ด้วย image dunglas/frankenphp
    • สามารถรันสคริปต์ CLI เช่น php script.php จาก image เดียวกันได้
  • การตั้งค่าอิงกับ Caddy โดยตัวอย่างคอนฟิกจะเปิดการบีบอัดในบล็อก localhost และใช้ php_server เพื่อจัดการไฟล์ PHP และไฟล์ static asset ในไดเรกทอรีปัจจุบัน

ฟีเจอร์เซิร์ฟเวอร์และความเข้ากันได้กับ PHP

  • ฟีเจอร์เว็บเซิร์ฟเวอร์

    • ฝังตัวรัน PHP อย่างเป็นทางการไว้ใน Caddy
    • รองรับ HTTP/1.1, HTTP/2, HTTP/3 แบบเนทีฟ
    • สร้าง ต่ออายุ และเพิกถอนใบรับรอง HTTPS ผ่าน Let’s Encrypt หรือ ZeroSSL โดยอัตโนมัติ
    • รองรับการบีบอัด Brotli, Zstandard และ Gzip เป็นค่าเริ่มต้น
    • รวม structured logging และ การรองรับ Prometheus
  • สภาพแวดล้อมรันไทม์ PHP

    • เข้ากันได้กับ PHP 8.2+, ส่วนขยาย PHP ส่วนใหญ่ และโมดูล Caddy ทั้งหมด
    • รองรับส่วนขยาย PHP ยอดนิยม รวมถึง OPcache และ XDebug แบบเนทีฟ
    • ไม่ต้องใช้ PHP-FPM และใช้ SAPI ของตัวเองที่สร้างมาสำหรับเว็บเซิร์ฟเวอร์ Go

Worker mode และฟีเจอร์ที่มุ่งเน้นประสิทธิภาพ

  • Worker mode บูตแอปพลิเคชันหนึ่งครั้งแล้วคงไว้ในหน่วยความจำ ทำให้พร้อมจัดการคำขอได้ภายในไม่กี่มิลลิวินาที
  • รองรับแบบเนทีฟใน Symfony, API Platform และ Laravel
  • ใช้ PHP superglobals เดิมโดยไม่ต้องมี PSR-7
  • แม้แอปจะไม่เข้ากันได้กับ Worker mode ก็ยังสามารถเสิร์ฟได้ตามเดิม
  • มี watcher สำหรับรีสตาร์ท worker อัตโนมัติเมื่อโค้ดเปลี่ยน
  • แนะนำว่าจากเบนช์มาร์กของตัวเองบนแอป API Platform แสดงประสิทธิภาพ เร็วกว่า FPM 3.5 เท่า

การดีพลอยและแพ็กเกจจิง

  • สามารถดีพลอยแอป cloud-native ด้วย Docker image
  • เข้ากันได้กับ Kubernetes และแพลตฟอร์มคลาวด์สมัยใหม่
  • สามารถแพ็กเกจเว็บแอปพลิเคชัน PHP และเครื่องมือ command line เป็น ไบนารีสแตติกแบบ standalone ได้
  • อธิบายว่ารันเป็นบริการเดียวและไบนารีเดียว โดยไม่ต้องมีบริการภายนอก

ฟีเจอร์เว็บแพลตฟอร์มเพิ่มเติม

  • รองรับ 103 Early Hints และแนะนำว่าเป็นฟีเจอร์ที่สามารถปรับปรุงเวลาโหลดเว็บไซต์ได้ 30% โดยอ้างอิงบทความของ Cloudflare
  • ผ่านฮับ Mercure ในตัว แอป PHP สามารถส่งอีเวนต์ไปยังเบราว์เซอร์ที่เชื่อมต่ออยู่ และเบราว์เซอร์รับ payload ได้ทันทีในรูปแบบอีเวนต์ JavaScript
  • รองรับการดีพลอยแบบไม่หยุดให้บริการด้วย Graceful reload

1 ความคิดเห็น

 
GN⁺ 2024-05-31
ความคิดเห็นจาก Hacker News
  • ผมไม่ได้พัฒนา PHP มาเกือบ 10 ปีแล้ว แต่พอเห็น landing page นี้ก็เกือบจะลองทำแค่ hello world ขึ้นมาดูแล้ว
    คาแรกเตอร์ช้างแฟรงเกนสไตน์มันประหลาด หน้าตาไม่สวย แต่น่ารัก ดีไซน์ สี ข้อความ และแอนิเมชันก็ดูเรียบร้อย จากมุมของคนที่ห่างจากการพัฒนา PHP ไปพักใหญ่ value proposition สื่อออกมาได้ชัด และดูเหมาะกับการเริ่มทำอะไรเล็ก ๆ ได้อย่างรวดเร็ว
    • ผมย้ายจาก PHP ไป Golang เมื่อสิบกว่าปีก่อน เพราะชอบ การแจกจ่ายเป็นไบนารี มาก
      ไม่อยากต้องรันคอนเทนเนอร์ 8 ตัวเพื่อแยกซอฟต์แวร์ห่วย ๆ หรือ dependency ที่พันกันยุ่ง ๆ ออกมา ผมไม่ชอบแนวทางที่แทนจะปล่อยซอฟต์แวร์ที่ติดตั้งได้ กลับเอา “บนเครื่องผมรันได้นะ” มาห่อแล้วโยนออกสู่โลก อาจจะลองจับดูเพราะความคิดถึงได้ แต่ไม่แน่ใจแล้วว่าอยากเอาอะไรแบบนี้เข้า production อีกไหม
    • เป็นหนึ่งใน landing page ที่ดีที่สุดเท่าที่เคยเห็นมา สนุกและเข้าใจได้ทันที
  • ผมใช้ C# มานาน และตอนนี้เขียนโค้ดหลัก ๆ ด้วย PHP 8 ซึ่งเป็นภาษาที่ยอดเยี่ยมสำหรับสร้างอะไรบางอย่างอย่างรวดเร็ว
    ภาษาควรไปในทิศทางแบบนี้ มากกว่าจะเป็นแนวที่ต้องตั้งค่า Apache ค่อนข้างซับซ้อนเหมือน LAMP สมัยก่อน
    • ผมใช้ PHP มา 18 ปีแล้ว ถ้าใช้ nginx + php-fpm การตั้งค่าใช้เวลาแค่ 5 นาทีก็พอ
      ผมก็คิดว่าจะลองตัวนี้ดูเหมือนกัน แต่ไม่เคยเจอคอขวดจาก nginx หรือ Apache เลย ทั้งคู่ใช้เวลามากสุดไม่กี่นาทีก็รันขึ้นได้
    • อีกทางเลือกหนึ่งคือ Nginx Unit: https://unit.nginx.org/
      มันรันเป็นบริการเดียวเหมือน Apache + mod_php จัดการ multiprocessing ของ PHP และภาษาอื่น ๆ, ไฟล์ static, reverse proxy และสามารถจัดการทั้งตัวมันเองกับ PHP จาก config เดียวกันแบบ runtime ผ่านไฟล์หรือ socket ได้: https://unit.nginx.org/configuration/#php
      ตัวอย่าง config จริงอยู่ที่ https://github.com/PrivateBin/docker-unit-alpine/blob/master... และยังทำ container image ผลลัพธ์ให้ค่อนข้างเล็กได้ด้วย: https://hub.docker.com/r/privatebin/unit-alpine
    • ผมแทบไม่ค่อยตั้งค่า PHP แต่จากที่จำได้ว่าต้องทำทุกครั้งที่ติดตั้งเดสก์ท็อปใหม่ มันจบได้เร็วและลื่นมากด้วย apt-get
      นอกจากรีสตาร์ต Apache แล้วก็จำไม่ได้ว่าต้องทำอะไรเพิ่มเป็นพิเศษ
    • ผมก็สงสัยว่า config ของ Apache มันแย่ขนาดนั้นจริงหรือเปล่า ถ้าใช้ของอย่าง PHP-FPM ก็ดูใช้ได้ดีทีเดียว: https://news.ycombinator.com/item?id=40256843
      ก็ประมาณ LoadModule proxy_fcgi_module "/usr/lib/apache2/modules/mod_proxy_fcgi.so" กับ SetHandler "proxy:fcgi://127.0.0.1:9000" นอกจากนี้ยังมีตัวอย่าง Nginx ที่คล้ายกันในเชิงแนวคิดกับวิธีตั้งค่า Apache และรวมถึงการติดตั้งแพ็กเกจที่จำเป็นด้วย: https://news.ycombinator.com/item?id=37443911
      มี container image ที่ build ไว้ล่วงหน้าซึ่งให้ผลใกล้เคียงกันด้วย แต่ถ้าอยากดูว่าข้างในทำงานอย่างไร ก็ลองทำเองได้ แน่นอนว่าง่ายกว่าการตั้งค่า Tomcat หรือ GlassFish ด้วยมือใน application server ของ Java สมัยก่อน และแม้คำสั่งรันเดี่ยว ๆ จะดีกว่าในทุกสภาพแวดล้อม แต่ LAMP ก็ไม่ได้แย่ขนาดนั้นเมื่อเทียบกับ stack อื่น ๆ
    • เห็นด้วย ถ้าวัฒนธรรมที่พึ่งพา SQLite แทน PostgreSQL/MySQL เข้าที่แล้ว แอปพลิเคชันฝั่งเซิร์ฟเวอร์ทั้งตัวก็สามารถกลายเป็นไบนารีแบบ standalone ง่าย ๆ ได้
      ถ้ามีไบนารี ก็ผูกเข้ากับแอป Electron ได้ง่ายขึ้นด้วย
  • ตอนพัฒนาผมมักใช้เว็บเซิร์ฟเวอร์ในตัวของ PHP: php -S 0.0.0.0:8000 public/index.php
    แต่มันเป็น single-thread และช้า จึงไม่เหมาะกับ production FrankenPHP ดูมีอนาคต แต่ปัญหาเรื่องข้อจำกัดของ core/thread[2] ก็ดูเหมือนอาจเป็นปัญหาใน production ได้เหมือนกัน ถึงอย่างนั้นก็อาจลองนำไปใช้กับโปรเจกต์ pure-todo[1] เพื่อดูว่ามีปัญหาเดียวกันไหม Docker image พื้นฐานดูค่อนข้างดี
    1: https://github.com/sandreas/pure-todo
    2: https://github.com/dunglas/frankenphp/discussions/294
    • ในเอกสารของเซิร์ฟเวอร์ในตัว PHP ระบุชัดเจนว่า ไม่ใช่สำหรับ production และมีไว้เพื่อการพัฒนาเท่านั้น
      ดูคำเตือนด้านบนของหน้า: https://www.php.net/manual/en/features.commandline.webserver...
      ผมก็ไม่แน่ใจว่าการเอามาเป็นตัวเปรียบเทียบในบริบทนี้ยุติธรรมหรือเปล่า
    • ถ้าตั้งค่า PHP_CLI_SERVER_WORKERS ก็สามารถรันแบบ หลายเธรด ได้
    • ผมสงสัยว่าที่บอกว่าใช้ใน production ไม่ได้ เป็นปัญหาเรื่อง ประสิทธิภาพ อย่างเดียวหรือเปล่า
      ถ้าเป็นไซต์เล็ก ๆ ที่มีผู้ใช้น้อย ผมอยากรู้ว่าจะขาดอะไรไปเมื่อเทียบกับสภาพแวดล้อมอื่นที่ “พร้อมสำหรับ production”
    • เท่าที่ผมเข้าใจ ปัญหาเฉพาะอย่าง single-thread และช้าจนไม่เหมาะกับ production นั้นตัวนี้แก้ได้แล้ว น่าจะยังแก้ปัญหาอื่น ๆ เพิ่มด้วย
  • ผมลองใช้เองแล้ว มันช้ามากจริง ๆ และดูเหมือนใช้ core ได้ไม่เต็มที่ด้วย อ่านเอกสารที่ยังไม่พออยู่นานแต่ก็แก้ไม่ได้
    เขาบอกว่าใช้ไม่กี่คำสั่งก็พร้อม production และเร็วกว่า FPM 3.5 เท่า แต่ในสภาพแวดล้อมของผมมันทำงานได้ประมาณ 1% ของประสิทธิภาพ FPM เท่านั้น ลองใช้ไฟล์ executable แล้วก็เจอปัญหาเดียวกัน และถ้าเป็น hello world อย่างน้อยผมคาดหวังไว้สัก 200K rps
    • ผมเป็นคนสร้าง FrankenPHP เอง อยากได้ตัวอย่างที่ reproduce ได้ มาก

ในเบนช์มาร์กส่วนใหญ่ เมื่อเปิดโหมด worker แล้ว FrankenPHP มักเร็วกว่า FPM มาก โดยประมาณราว 3 เท่า ถึงอย่างนั้นก็ยังมีบางกรณียกเว้น และกำลังแก้ไขร่วมกับผู้ดูแล PHP อยู่

  • ถ้าแชร์ประสบการณ์นั้นมาได้ จะช่วยแก้ปัญหานี้ได้: https://github.com/dunglas/frankenphp/discussions/294
    ตัว Caddy เองให้ประสิทธิภาพดีมากเมื่อใช้ร่วมกับ PHP จึงเป็นสถานการณ์ที่ค่อนข้างแปลก
  • อยากรู้ว่าจะออกมาอย่างไรในเบนช์มาร์ก TechEmpower: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&s...
    ตอนนี้อยู่ท้ายสุดด้วยสถานะ did not complete
  • บทความที่เกี่ยวข้อง: Show HN: FrankenPHP, แอปเซิร์ฟเวอร์สำหรับ PHP ที่เขียนด้วย Go - https://news.ycombinator.com/item?id=33205282 - ตุลาคม 2022, 83 ความเห็น
  • https://github.com/dunglas/frankenphp/discussions/294
    มี ปัญหาด้านประสิทธิภาพ อยู่ ถ้าไม่นับเรื่องนั้น ก็เป็นโปรเจกต์ที่มีอนาคตมากจริง ๆ
    • ถ้าทำให้เกิดซ้ำได้ ก็ยินดีลางาน 2 สัปดาห์ จากบริษัทเพื่อไปแก้ ไม่มีใครบอกวิธีทำให้เกิดซ้ำมาเลย
  • ลองเบนช์มาร์ก WordPress บน FrankenPHP กับ Apache Mod-PHP แล้ว แต่ไม่เห็นหลักฐานว่า FPHP ชนะ
    อย่างไรก็ตาม ยังไม่ได้ขุดลึก และการทดสอบก็ทำใน Docker ไม่ใช่การตั้งค่าทั่วไป WordPress ก็แทบเป็นค่าเริ่มต้น จึงไม่มีธีมหนัก ๆ ทำให้ไม่ใช่เงื่อนไขที่สมจริงนัก ถึงอย่างนั้นก็อยากลองทดสอบใหม่และทำความเข้าใจให้ดีขึ้น
    • ต่างจาก Laravel และ Symfony ตรงที่ WordPress ยังไม่รองรับ โหมด worker ของ FrankenPHP จึงไม่ได้มีข้อได้เปรียบด้านประสิทธิภาพมากนัก
      อย่างไรก็ตาม สามารถใช้ 103 Early Hints เพื่อโหลด asset ล่วงหน้าและลด latency ของการโหลดหน้าได้ 30% ถึงอย่างนั้น FrankenPHP ก็ทำให้เปิด HTTP cache ใน WordPress ได้ง่ายขึ้น และทำให้การ deploy ง่ายขึ้นด้วย ยังมีโปรเจกต์เฉพาะสำหรับ WordPress กับ FrankenPHP ซึ่งมี HTTP cache ในตัวที่ปรับแต่งสำหรับ WordPress โดยใช้ไลบรารี Souin Go รวมอยู่ด้วย: https://github.com/StephenMiracle/frankenwp
    • อาจเป็นเพราะคุ้นเคยจึงใช้ชื่อนั้น แต่ตามมาตรฐานแล้วบน Apache ควรใช้ proxy_fcgi
      จะช่วยประหยัดหน่วยความจำของ Apache ได้อีกเล็กน้อย และเปิดพื้นที่ให้รองรับคำขอ PHP ได้มากขึ้น
  • docker run -v $PWD:/app/public -p 443:443 \ dunglas/frankenphp
    ถ้าต้องการสร้าง Docker container เพื่อให้บริการแอปเอง คำสั่งด้านล่างน่าจะเพียงพอสำหรับเปลี่ยน Debian ใหม่ให้เป็น container ที่ต้องการ: apt install -y apache2 libapache2-mod-php และตั้งค่า /etc/apache2/sites-enabled/000-default.conf
    กำลังดูแล repository ที่แสดงกระบวนการตั้งแต่ศูนย์ไปจนถึงเว็บแอปพลิเคชันที่รันอยู่จริง ด้วยภาษาและเฟรมเวิร์กยอดนิยมหลายตัว ร่วมกับเพื่อน ๆ: https://github.com/no-gravity/web_app_from_scratch
    • เพิ่งเริ่มทำงานที่บริษัทที่ใช้ mod_php เมื่อหนึ่งเดือนก่อน และมันทรมานมาก
      ทุกครั้งที่เปิด xdebug หลังจบเซสชันดีบักต้องรีสตาร์ต Apache ตั้งแต่เมื่อวานเริ่มตั้งค่า apache2 ให้ใช้ php-fpm แล้ว และสงสัยว่า FrankenPHP นี้จะเหมาะกับเราหรือไม่ อย่างน้อยก็ในสภาพแวดล้อมพัฒนา แต่หาในเอกสารไม่เจอว่าจะติดตั้ง PHP extension อย่างไร
    • ถ้าผมไม่ได้เข้าใจผิด สิ่งนี้น่าจะไม่ทำงานนะ virtual host 000-default.conf ค่าเริ่มต้นของ Apache redirect จาก 443 ไป 80 หรือเปล่า?
  • ดีใจที่เห็นสิ่งนี้บนหน้าแรกของ HN
    FPM และสถาปัตยกรรมแบบไม่แชร์อะไรเลยของมันเคยเป็นหัวใจสำคัญของความสำเร็จของ PHP มานานแล้ว แต่ก็รู้สึกว่าในขณะเดียวกัน มันก็เป็นโซ่ตรวนของ PHP ด้วย