0Pricing
PHP Academy · Pelajaran

Model Konkurensi PHP

Pahami I/O yang memblokir dan kapan pemrosesan asinkron membantu.

Model Konkurensi PHP adalah pelajaran PHP Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar PHP Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus PHP Academy mencakup 4 pelajaran total.

PHP Bersifat Sinkron Secara Bawaan

PHP klasik menjalankan satu permintaan per proses, dari atas ke bawah, dengan I/O yang memblokir. Pemanggilan file_get_contents() ke API yang lambat membekukan seluruh skrip sampai byte-byte tiba. Model tanpa berbagi (proses baru untuk setiap permintaan, keadaan dihentikan pada akhir proses) sangat sederhana — tetapi ini berarti satu pekerja hanya dapat melakukan tepat satu hal pada satu waktu. Pelajaran ini memetakan situasi yang menimbulkan masalah dan situasi yang terbantu oleh pemrosesan asinkron.

Mengukur I/O yang Memblokir

Perhatikan bahwa waktu nyata didominasi oleh penantian, bukan perhitungan. Tiga permintaan berurutan yang masing-masing memerlukan 1 detik membutuhkan sekitar 3 detik, meskipun CPU menganggur sepanjang waktu.

<?php
$start = microtime(true);
foreach (['a', 'b', 'c'] as $job) {
    usleep(1_000_000); // simulate a 1s blocking network call
    echo "done $job\n";
}
printf("elapsed: %.2fs\n", microtime(true) - $start); // ~3.00s

Terikat CPU vs Terikat I/O

Konkurensi hanya membantu pekerjaan yang terikat I/O — waktu yang dihabiskan untuk menunggu jaringan, disk, atau basis data. Untuk pekerjaan yang terikat CPU (pembuatan hash, pengubahan ukuran gambar, penguraian), satu utas sudah sepenuhnya sibuk; pemrosesan asinkron hanya menambah beban penjadwalan. Lakukan diagnosis terlebih dahulu:

  • Banyak panggilan HTTP atau kueri basis data yang lambat → pemrosesan asinkron sangat membantu.
  • Perulangan numerik yang intensif → gunakan paralelisme (proses/utas), bukan perulangan kejadian.

Cara PHP Menskalakan Aplikasi Selama Ini

Secara historis, PHP diskalakan dengan konkurensi tingkat proses: PHP-FPM mempertahankan kumpulan proses pekerja; setiap proses menangani satu permintaan pada satu waktu, lalu OS menjadwalkannya secara bergantian. Ini adalah konkurensi nyata antarpermintaan, tetapi tidak menawarkan apa pun di dalam satu permintaan — Anda tetap tidak dapat menjalankan 50 panggilan API secara paralel dalam satu penangan dengan kode pemblokiran biasa.

Gagasan Perulangan Peristiwa

PHP asinkron memperkenalkan perulangan peristiwa: satu utas yang mendaftarkan operasi masukan/keluaran sebagai nonblokir, lalu tidur di stream_select()/epoll sampai salah satunya siap, dengan menjalankan panggilan balik saat data tiba. Satu utas mengelola ribuan soket karena tidak pernah menganggur sambil menunggu satu soket tertentu.

<?php
// Conceptual loop: poll many non-blocking streams at once
$streams = openManyNonBlockingSockets();
while ($streams) {
    $read = $streams; $write = $except = [];
    stream_select($read, $write, $except, null); // sleeps until ANY is ready
    foreach ($read as $s) {
        handleReadyStream($s); // runs only the sockets that have data now
    }
}

Kooperatif, Bukan Preemtif

PHP asinkron bersifat kooperatif: tugas berjalan sampai secara sukarela menyerahkan kendali pada titik masukan/keluaran. Tidak ada pengambilalihan paksa, sehingga panggilan pemblokir yang lama atau perulangan CPU yang sibuk menghentikan seluruh perulangan — semua tugas lain kelaparan. Aturan emas: jangan pernah memanggil fungsi pemblokir (sleep, PDO yang memblokir, file_get_contents) di dalam tugas perulangan peristiwa. Gunakan padanan asinkron dari perulangan tersebut.

Tiga Pendekatan dalam PHP

PHP modern menyediakan perangkat berlapis:

  • Fiber (PHP 8.1, inti) — primitif tingkat rendah untuk menjeda dan melanjutkan tumpukan pemanggilan. Komponen dasar, bukan kerangka kerja lengkap.
  • ReactPHP / Amp — perulangan peristiwa di ruang pengguna yang dibangun di atas aliran, dan kini juga Fiber, untuk operasi masukan/keluaran nonblokir tanpa ekstensi.
  • Swoole / OpenSwoole — ekstensi C yang menyediakan korutin, server berperforma tinggi, dan panggilan pemblokir yang dialihkan.

Deteksi apa yang tersedia saat eksekusi sebelum memilih strategi.

<?php
echo 'Fibers: ' . (class_exists('Fiber') ? 'yes' : 'no'), PHP_EOL;
echo 'Swoole ext: ' . (extension_loaded('swoole') ? 'yes' : 'no'), PHP_EOL;
echo 'parallel ext: ' . (extension_loaded('parallel') ? 'yes' : 'no'), PHP_EOL;
echo 'PHP ' . PHP_VERSION, PHP_EOL;

Janji Memodelkan Nilai Masa Depan

Sebelum Fiber, PHP asinkron menampilkan hasil yang masih tertunda sebagai janji: penampung untuk nilai yang akan diselesaikan nanti. Anda memasang panggilan balik melalui then(). Cara ini berfungsi, tetapi menghasilkan rantai bersarang; Fiber memungkinkan pustaka menyembunyikannya di balik await yang tampak sinkron.

<?php
use React\Promise\Promise;

$promise = new Promise(function ($resolve) {
    // resolved later when I/O completes
    $resolve(42);
});
$promise->then(function ($value) {
    echo "got $value\n";
});

Konkurensi vs Paralelisme

Gunakan istilah secara tepat:

  • Konkurensi — banyak tugas yang sedang berjalan, diselang-seling pada satu utas (perulangan peristiwa). Sangat cocok untuk masukan/keluaran.
  • Paralelisme — banyak tugas yang dijalankan secara bersamaan pada beberapa inti (proses, ekstensi parallel, pekerja tugas Swoole). Diperlukan untuk pekerjaan CPU.

Perulangan peristiwa memberikan konkurensi, bukan paralelisme. Potongan kode di bawah menunjukkan paralelisme pada tingkat proses dengan proc_open — tiga pekerja berjalan pada proses OS terpisah secara bersamaan.

<?php
$procs = [];
foreach (range(1, 3) as $i) {
    // Each worker is a separate OS process -> real parallelism
    $procs[] = proc_open(
        "php -r 'usleep(500000); echo \"worker $i done\\n\";'",
        [1 => ['pipe', 'w']], $pipes
    );
}
foreach ($procs as $p) { proc_close($p); }
echo "all workers launched in parallel\n";

Kapan NOT Memilih Asinkron

Asinkron memiliki biaya: pekerja yang berjalan lama berarti PHP tidak lagi menghapus keadaan di antara permintaan, sehingga kebocoran memori, tembolok statis, dan koneksi yang kedaluwarsa menjadi tanggung jawab Anda. Jika pengendali permintaan menjalankan satu kueri basis data lalu selesai, PHP-FPM lebih sederhana dan sama cepatnya. Gunakan asinkron ketika Anda memerlukan percabangan masukan/keluaran, WebSockets/polling panjang, pengaliran data, atau server persisten.

Paralelisme Nyata: ext-parallel dan Proses

Untuk percabangan yang terikat CPU, PHP dapat menjalankan paralelisme nyata pada tingkat OS. Ekstensi parallel membuat utas pekerja dengan memori yang terisolasi; sebagai alternatif, proc_open/pcntl_fork membuat proses. Berbeda dari perulangan peristiwa, cara ini menggunakan beberapa inti secara bersamaan — pilihan yang tepat ketika hambatannya adalah komputasi, bukan penantian.

<?php
// Requires ext-parallel — runs tasks on separate threads/cores
use parallel\Runtime;

$runtime = new Runtime();
$future = $runtime->run(function (): int {
    $sum = 0;
    for ($i = 0; $i < 1_000_000; $i++) $sum += $i; // CPU work on another core
    return $sum;
});
echo $future->value(), PHP_EOL;

Pemeriksaan Singkat

Apa yang terjadi jika Anda memanggil sleep(2) yang memblokir di dalam tugas perulangan peristiwa?

Rangkuman

Sekarang Anda memiliki model mental tentang konkurensi PHP:

  • PHP bawaan bersifat sinkron, memblokir, tanpa berbagi keadaan; FPM menskalakan jumlah permintaan, bukan pekerjaan dalam satu permintaan.
  • Asinkron membantu pekerjaan yang terikat masukan/keluaran melalui perulangan peristiwa berutas tunggal menggunakan aliran nonblokir.
  • Modelnya kooperatif — jangan pernah memblokir perulangan; pekerjaan CPU yang lama membutuhkan paralelisme, bukan konkurensi.
  • Perangkat PHP: Fiber (primitif), ReactPHP/Amp (perulangan di ruang pengguna + janji), Swoole (ekstensi korutin).

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Model Konkurensi PHP” gratis?

Ya — teks lengkap “Model Konkurensi PHP” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus PHP Academy, upgrade ke CoddyKit PRO. Kursus PHP Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Model Konkurensi PHP”?

Pahami I/O yang memblokir dan kapan pemrosesan asinkron membantu. Kamu berlatih PHP Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai PHP Academy?

Tidak diperlukan pengalaman sebelumnya. PHP Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Model Konkurensi PHP” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran PHP Academy ini?

Ya. Setiap pelajaran PHP Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Model Konkurensi PHP
  2. Fiber PHP 8.1
  3. Perulangan Peristiwa dengan ReactPHP
  4. Server Berkinerja Tinggi dengan Swoole
← Kembali ke PHP Academy