Kebenaran Tentang Async PHP: Fibers, epoll, dan PHP 8.6

Saya telah bekerja dengan Laravel selama bertahun-tahun. Saya menggunakan PHP secara sinkron (sync). Satu permintaan datang, proses berjalan, dan respons dihantar. Saya tidak pernah memerlukan kod async.

Kemudian saya membaca tentang Polling API PHP 8.6 yang baharu. Ia mengubah cara saya melihat segalanya.

Inilah apa yang saya pelajari tentang bagaimana async berfungsi di sebalik tabir.

Masalah IO

Apabila anda memanggil satu API, proses PHP anda akan menunggu. Contoh: $response = Http::get('https://api.example.com');

Jika panggilan tersebut mengambil masa 300ms, CPU anda tidak melakukan apa-apa selama 300ms. Ia kekal dalam keadaan tidur (sleep state). Ini adalah I/O yang menyekat (blocking I/O).

Jika anda mempunyai tiga panggilan API:

  • API A: 300ms
  • API B: 400ms
  • API C: 200ms

Jumlah sekuensial: 900ms. Jumlah async: 400ms (masa panggilan yang paling lambat).

Async membolehkan proses anda melakukan kerja lain sementara menunggu data.

Select vs. epoll

Untuk melakukan async, anda perlu tahu soket mana yang mempunyai data yang sedia.

  1. select() PHP telah menggunakan stream_select() sejak versi 4. Ia berfungsi dengan meminta kernel untuk memerhati senarai soket. Masalahnya: Setiap kali data tiba, anda mesti mengimbas semula keseluruhan senarai tersebut. Ini adalah "rescan tax". Ia juga mempunyai had sekitar 1024 sambungan.

  2. epoll (Linux) / kqueue (macOS) Ini adalah ciri-ciri kernel. Daripada mengimbas senarai, kernel menyimpan senarai sedia (ready-list). Ia hanya memberitahu anda soket spesifik mana yang sudah sedia. Ini boleh diskalakan kepada beribu-ribu sambungan tanpa kerja tambahan.

epoll bukan ciri PHP. Ia adalah ciri Linux. Go, Rust, dan Node.js semuanya menggunakannya.

Fibers: Butang Jeda

PHP 8.1 memperkenalkan Fibers. Saya menyangka Fibers akan bangun dengan sendirinya. Hakikatnya tidak.

Sebuah Fiber adalah seperti video yang dijeda. Ia kekal dijeda sehingga seseorang memanggil $fiber->resume().

Event Loop hanyalah sebahagian daripada kod PHP yang memutuskan bila untuk memanggil resume().

Async I/O memerlukan tiga bahagian:

  • Jeda (Pause): Fibers (teras PHP 8.1)
  • Putuskan (Decide): Event Loop (kod PHP biasa)
  • Tahu (Know): Kernel Polling (epoll/kqueue)

Sebelum PHP 8.6, PHP mempunyai bahagian "Pause" dan "Decide", tetapi bahagian "Know" bergantung kepada select() yang lama atau sambungan (extensions) C yang perlahan.

PHP 8.6 merapatkan jurang ini. Ia membawa Polling API asli ke dalam teras. Kini, PHP boleh menggunakan epoll atau kqueue secara terus tanpa sambungan tambahan.

Kesimpulan

Jika anda menggunakan Laravel dengan PHP-FPM, anda tidak perlu mengubah apa-apa buat masa ini.

Tetapi fahami ini: Async bukanlah magis. Ia hanyalah cara pintar untuk menguruskan masa menunggu.

Berhenti sekadar menggunakan kod. Jalankan skrip ringkas. Rosakkannya. Begitulah cara anda benar-benar belajar.

Sumber: https://dev.to/alamriku/sync-php-developer-hisebe-async-php-bujhte-giye-yaa-shikhlaam-fibers-epoll-aar-php-86-462j