Apache Kafka dengan PHP
Alirkan peristiwa berthroughput tinggi menggunakan Kafka.
Apache Kafka dengan PHP adalah pelajaran PHP Academy gratis di CoddyKit. Ini adalah pelajaran 3 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.
Kafka dengan PHP
Kafka bukanlah antrean tugas — Kafka adalah log komit terdistribusi yang hanya dapat ditambahi. Produsen menambahkan catatan ke topik; konsumen membaca dari posisi masing-masing dan dapat memutar ulang riwayat. Hal ini membuat Kafka ideal untuk aliran peristiwa ber-throughput tinggi, sumber peristiwa, dan memasok beberapa kelompok konsumen independen dari satu aliran.
Di PHP, Anda berkomunikasi dengan Kafka melalui ext-rdkafka, yaitu pengikatan ke pustaka C librdkafka yang telah teruji.
Log, Bukan Antrean
Perubahan cara berpikir dari RabbitMQ ke Kafka:
- Pesan tidak dihapus saat dikonsumsi; pesan kedaluwarsa berdasarkan kebijakan retensi (waktu atau ukuran).
- Setiap konsumen melacak posisinya sendiri — letaknya di dalam log.
- Sebuah topik dibagi menjadi partisi; pengurutan hanya dijamin di dalam satu partisi.
- Beberapa kelompok konsumen membaca topik yang sama secara independen.
Jika Anda memerlukan pemutaran ulang, distribusi ke banyak pembaca, atau volume yang sangat besar, Kafka cocok. Jika Anda memerlukan perutean per pesan dan waktu kedaluwarsa, RabbitMQ lebih cocok.
Memasang ext-rdkafka
Pasang pustaka asli terlebih dahulu, kemudian ekstensi PECL, lalu, jika diperlukan, pembungkus tingkat lebih tinggi.
# Debian/Ubuntu
apt-get install -y librdkafka-dev
pecl install rdkafka
echo "extension=rdkafka.so" >> php.ini
# Optional ergonomic wrapper
composer require longlang/phpkafka # or arnaud-lb/php-rdkafka-stubs for IDEMenghasilkan Catatan
Buat RdKafka\Producer, dapatkan pengendali topik, lalu panggil produce(). Kunci menentukan partisi tempat sebuah catatan berada — kunci yang sama menghasilkan partisi yang sama dan urutan tetap terjaga. Selalu panggil flush() sebelum keluar, atau catatan yang masih tersangga akan hilang.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$producer = new RdKafka\Producer($conf);
$topic = $producer->newTopic('orders');
// RD_KAFKA_PARTITION_UA = let the partitioner choose by key
$key = 'order-42';
$topic->produce(RD_KAFKA_PARTITION_UA, 0, json_encode(['id' => 42]), $key);
$producer->poll(0);
$result = $producer->flush(10000); // wait up to 10s
if ($result !== RD_KAFKA_RESP_ERR_NO_ERROR) {
throw new RuntimeException('Failed to flush');
}Mempartisi Berdasarkan Kunci
Pemartisian adalah inti skalabilitas dan pengurutan Kafka. Pembagi partisi bawaan menghitung nilai ringkas dari kunci catatan: partition = hash(key) % numPartitions. Memilih kunci yang baik penting:
- Kunci berdasarkan
customerId→ semua peristiwa milik seorang pelanggan tetap terurut dan berada di satu partisi. - Kunci tanpa nilai → dibagikan secara bergiliran ke seluruh partisi (volume maksimum, tanpa pengurutan).
Anda tidak pernah dapat mengurangi jumlah partisi sebuah topik, dan menambahkan partisi akan mengubah pemetaan nilai ringkas — jadi tentukan ukuran partisi untuk paralelisme puncak sejak awal.
Kelompok Konsumen dan Posisi
Gunakan KafkaConsumer tingkat tinggi dengan group.id. Kafka membagikan partisi kepada the anggota kelompok dan menyeimbangkan ulang pembagian saat anggota bergabung atau keluar. Setiap anggota hanya membaca partisi yang ditugaskan kepadanya, sehingga Anda mendapatkan penskalaan horizontal secara cuma-cuma.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$conf->set('group.id', 'order-emailers');
$conf->set('auto.offset.reset', 'earliest'); // start of log if no offset
$conf->set('enable.auto.commit', 'false'); // we commit manually
$consumer = new RdKafka\KafkaConsumer($conf);
$consumer->subscribe(['orders']);
while (true) {
$msg = $consumer->consume(5000);
if ($msg->err === RD_KAFKA_RESP_ERR_NO_ERROR) {
handle($msg->payload);
$consumer->commit($msg); // commit offset AFTER work
}
}
function handle(string $p): void {}Kapan Harus Melakukan Komit
Komit posisi menentukan semantik pengiriman Anda:
- Lakukan komit setelah pemrosesan → setidaknya sekali (kegagalan sebelum komit akan memutar ulang catatan tersebut).
- Lakukan komit sebelum pemrosesan → paling banyak sekali (kegagalan akan menyebabkan catatan hilang).
Komit otomatis (enable.auto.commit=true) dilakukan berdasarkan pewaktu, terlepas dari apakah pekerjaan Anda selesai — praktis, tetapi dapat menghilangkan catatan secara diam-diam saat terjadi kegagalan. Nonaktifkan komit otomatis dan lakukan komit secara manual saat ketepatan penting.
Menangani Kesalahan Konsumsi
Tidak setiap hasil dari consume() merupakan pesan. Anda harus memilih cabang berdasarkan kode kesalahan — __PARTITION_EOF dan __TIMED_OUT adalah sinyal kendali normal, bukan kegagalan.
<?php
$msg = $consumer->consume(2000);
switch ($msg->err) {
case RD_KAFKA_RESP_ERR_NO_ERROR:
echo "Got: {$msg->payload} @ offset {$msg->offset}\n";
break;
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
echo "Reached end of partition\n"; // caught up, keep polling
break;
case RD_KAFKA_RESP_ERR__TIMED_OUT:
echo "No message this poll\n";
break;
default:
throw new \Exception($msg->errstr(), $msg->err);
}Penyetelan Volume
Volume Kafka berasal dari pengelompokan pesan. Pengaturan utama produsen:
linger.ms— tunggu sebentar untuk mengelompokkan lebih banyak catatan dalam setiap permintaan (misalnya, 5–20 md).batch.size/queue.buffering.max.messages— penyangga yang lebih besar berarti lebih sedikit perjalanan bolak-balik.compression.type—lz4atauzstdmengurangi biaya jaringan secara drastis.acks—alluntuk ketahanan,1untuk latensi yang lebih rendah.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$conf->set('compression.type', 'lz4');
$conf->set('linger.ms', '10');
$conf->set('batch.size', '65536');
$conf->set('acks', 'all');
$producer = new RdKafka\Producer($conf);Panggilan Balik Laporan Pengiriman
Karena produce() bersifat asinkron, pengiriman yang gagal tidak akan langsung menimbulkan pengecualian. Daftarkan panggilan balik laporan pengiriman pada konfigurasi produsen untuk mengetahui nasib setiap catatan — inilah satu-satunya cara yang andal untuk mendeteksi kegagalan produsen yang tidak terlihat di PHP.
<?php
$conf = new RdKafka\Conf();
$conf->set('bootstrap.servers', 'localhost:9092');
$conf->setDrMsgCb(function ($producer, $msg) {
if ($msg->err) {
fwrite(STDERR, 'Delivery FAILED: ' . rd_kafka_err2str($msg->err) . "\n");
} else {
echo "Delivered to partition {$msg->partition} @ offset {$msg->offset}\n";
}
});
$producer = new RdKafka\Producer($conf);
// poll() services the callback queue; call it after producing
$producer->poll(0);Jebakan Khusus PHP
Kafka mengasumsikan klien berumur panjang; siklus hidup permintaan PHP tidak cocok dengan asumsi itu:
- Produsen melakukan penyanggaan secara asinkron — selalu panggil
flush()sebelum the skrip berakhir, atau catatan akan hilang. - Jalankan konsumen sebagai proses pekerja CLI permanen di bawah pengawas, jangan pernah di dalam permintaan web.
- Proses penyeimbangan ulang menghentikan sementara konsumsi; buat pekerjaan per pesan tetap singkat atau gunakan
max.poll.interval.msdengan nilai yang cukup besar agar Anda tidak dikeluarkan dari kelompok. - Atur
log_leveldan daftarkan panggilan balik laporan pengiriman produsen untuk menangkap kegagalan yang tidak terlihat.
Pemeriksaan Singkat
Jaminan pengurutan dalam Kafka.
Rangkuman
Kafka dengan pendekatan PHP:
- Kafka adalah log yang dapat diputar ulang, bukan antrean; konsumen melacak posisi.
- Pemartisian berdasarkan kunci memberikan pengurutan per kunci dan penskalaan.
- Kelompok konsumen membagi partisi dan melakukan penyeimbangan ulang secara otomatis.
- Lakukan komit posisi setelah pekerjaan untuk pengiriman setidaknya sekali; nonaktifkan komit otomatis agar tetap terkendali.
- Sesuaikan
linger.ms,batch.size, dancompression.type; selalu panggilflush().
Berikutnya: merangkai primitif ini menjadi alur kerja berbasis peristiwa yang andal.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Apache Kafka dengan PHP” gratis?
Ya — teks lengkap “Apache Kafka dengan 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 “Apache Kafka dengan PHP”?
Alirkan peristiwa berthroughput tinggi menggunakan Kafka. 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 3 dari 4.
Berapa lama pelajaran “Apache Kafka dengan 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
- Mengapa Pesan Asinkron
- Bekerja dengan RabbitMQ di PHP
- Apache Kafka dengan PHP
- Membangun Alur Kerja Berbasis Peristiwa