Belajar RoadRunner - Arsitektur & Konsep Utama
Episode 2 of 26

Belajar RoadRunner - Arsitektur & Konsep Utama

Membedah arsitektur RoadRunner sebagai server Go dengan worker pool PHP persistent, memahami peran .rr.yaml sebagai pusat konfigurasi, jalur komunikasi via pipes atau Unix socket dengan protokol Goridge, serta siklus hidup worker yang dijaga supervisor.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 1 kita memahami mengapa RoadRunner ada — mengatasi cost of bootstrap PHP-FPM — pada episode kali ini kita membedah arsitektur dan konsep utama yang jadi fondasi semua plugin dan praktik di episode-episode berikutnya. Ini episode paling konseptual dalam fase awal, dan pemahaman yang kuat di sini akan membuat episode 3-25 terasa mudah.

Mengapa arsitektur penting? Karena kesalahan paling umum pengguna baru RoadRunner adalah memperlakukannya seperti web server biasa — menjalankan rr serve tanpa memahami apa yang terjadi di dalamnya, lalu kebingungan saat worker crash, memory bocor, atau request tiba-tiba lambat. Padahal hampir semua gejala itu bisa dianalisis hanya dari pemahaman arsitektur.

Arsitektur Dua Lapisan

RoadRunner terdiri dari dua komponen besar yang berjalan di dua bahasa berbeda:

100%
  • Lapisan Go: binary rr menjalankan server jaringan (HTTP/gRPC), plugin ekosistem, dan manager worker pool. Semua hal yang butuh konkurensi dan I/O tinggi ada di sini.
  • Lapisan PHP: proses app.php yang di-spawn sebagai worker. Ia tidak mendengarkan port apa pun — ia hanya berbicara dengan server Go melalui saluran komunikasi Goridge.

Pemisahan ini adalah keputusan desain inti: beban konkurensi ditangani Go, beban logika bisnis ditangani PHP. Kalian tidak perlu menulis kode PHP asinkron atau coroutine — cukup tulis PHP biasa yang melayani satu request pada satu waktu, dan biarkan pool yang menangani paralelisme.

.rr.yaml: Pusat Konfigurasi

Semua aspek RoadRunner dikonfigurasi dari satu file .rr.yaml. Strukturnya adalah kumpulan blok plugin, plus blok server dan rpc:

Struktur .rr.yaml minimal
version: "3"
 
server:
  command: "php app.php"
  relay: pipes
 
http:
  address: 0.0.0.0:8080
  pool:
    num_workers: 4
 
rpc:
  listen: tcp://127.0.0.1:6001

Blok server mendefinisikan cara worker dijalankan: command adalah perintah untuk spawn satu worker (biasanya php app.php), dan relay menentukan jalur komunikasi (pipes atau Unix socket). Blok http mengatur plugin HTTP beserta pool-nya. Blok rpc membuka port RPC yang dipakai aplikasi PHP untuk memanggil method plugin (KV, jobs, metrics, dan lain-lain).

Tip

Jalankan ./rr config:info di direktori berisi .rr.yaml untuk melihat seluruh konfigurasi default yang berlaku setelah merge dengan file kalian. Ini cara tercepat memverifikasi blok mana yang terbaca.

Komunikasi: Pipes dan Unix Socket

Worker PHP bukan web server — ia tidak memiliki port sendiri. Komunikasi antara server Go dan worker terjadi melalui salah satu dari dua jalur (relay):

  • pipes (default): stdin/stdout dari proses worker dipakai sebagai saluran biner. Paling sederhana dan portable — tidak butuh file socket di filesystem.
  • Unix socket: komunikasi lewat file socket di filesystem, berguna saat kalian butuh memisahkan hak akses atau men-debug traffic.

Di atas jalur tersebut berjalan protokol Goridge — protokol RPC biner (sejak v2 berbasis protobuf) yang meng-encode payload antara Go dan PHP. Kalian jarang berinteraksi langsung dengan byte-nya, tapi package spiral/goridge di sisi PHP dan implementasi di sisi Go menangani semuanya transparan.

Siklus Hidup Worker

Worker tidak berjalan selamanya. RoadRunner mengelola siklus hidupnya:

  1. Spawn — server Go menjalankan server.command (php app.php) dan melakukan handshake Goridge.
  2. Ready — worker masuk pool dan siap menerima task (HTTP request, job, atau pemanggilan RPC).
  3. Kerja — worker melayani task satu per satu; server memastikan satu worker hanya memproses satu request pada satu waktu.
  4. Restart / Destroy — supervisor memutuskan worker harus diganti bila: melebihi max_jobs, melebihi max_worker_memory, ada error fatal, atau menerima sinyal restart. Server spawn worker baru untuk menggantikannya.

Alur inilah yang membuat aplikasi PHP bisa "abadi" tanpa khawatir memory leak permanen — leak pada satu worker dibatasi oleh max_worker_memory, lalu worker diganti bersih.

Konsep Pool dan Supervisor

Worker pool adalah sekumpulan worker PHP yang dikelola server. Parameter pentingnya:

Konfigurasi pool yang umum
server:
  command: "php app.php"
  relay: pipes
 
http:
  address: 0.0.0.0:8080
  pool:
    num_workers: 4
    max_jobs: 500
    max_worker_memory: 128
    allocate_workers_by_tasks: true
    supervisor:
      max_worker_memory: 128
      exec_ttl: 0
      idle_ttl: 60
ParameterArti
num_workersJumlah worker yang di-spawn saat start
max_jobsWorker di-restart setelah memproses N task (anti memory leak)
max_worker_memoryWorker di-restart jika RSS melebihi N MB
allocate_workers_by_tasksSpawn worker baru sesuai beban, bukan semua sekaligus
supervisorAturan restart: memory limit, TTL eksekusi, dan TTL idle

Semua parameter ini kita bedah mendalam untuk tuning performa di episode 20 — untuk sekarang cukup paham perannya.

Jalur Request: Di Balik rr serve

Saat kalian menjalankan rr serve dengan config HTTP, alur satu request kira-kira:

  1. Client mengirim HTTP request ke http.address.
  2. Plugin HTTP mengambil worker idle dari pool (atau menunggu/ spawn sesuai kebijakan).
  3. Request dikirim ke worker lewat Goridge; worker mem-build objek PSR-7 dan menyerahkannya ke kode aplikasi kalian.
  4. Kode aplikasi menghasilkan PSR-7 response; worker mengirimkannya kembali ke Go.
  5. Go menulis response HTTP ke client dan worker kembali idle di pool.

Langkah 3 adalah alasan pentingnya PSR-7 handling — topik episode 4.

Penutup

Pada episode 2 ini, kalian telah memahami peta arsitektur RoadRunner.

Inti yang harus dibawa pulang:

  • Arsitektur dua lapisan: server Go (jaringan, plugin, pool) dan worker PHP (logika bisnis).
  • .rr.yaml adalah pusat konfigurasi; blok server, http, dan rpc adalah fondasinya.
  • Komunikasi via Goridge di atas pipes atau Unix socket.
  • Worker punya siklus hidup yang dijaga supervisor: spawn, kerja, restart.
  • Satu request diproses satu worker; konkurensi ditangani banyak worker.

Di episode 3 selanjutnya, kita masuk ke hands-on: instalasi lengkap dan konfigurasi .rr.yaml — semua cara mengunduh binary, struktur config lengkap, enable/disable plugin, dan verifikasi config sebelum menjalankan server. Pastikan pemahaman arsitektur ini kuat, karena dari sini semuanya praktik!