PHP Academy · Pelajaran

Apache Kafka dengan PHP

Alirkan peristiwa berkapasiti tinggi menggunakan Kafka.

Pelajaran 3 daripada 413 langkah

Apache Kafka dengan PHP ialah pelajaran PHP Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran PHP Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus PHP Academy merangkumi sejumlah 4 pelajaran.

Kafka dengan PHP

Kafka bukan baris gilir tugas — ia ialah catatan komit teragih yang hanya menerima penambahan. Pengeluar menambah rekod pada topik; pengguna membaca pada kedudukan masing-masing dan boleh memainkan semula sejarah. Hal ini menjadikan Kafka sesuai untuk strim peristiwa berkadar tinggi, sumber peristiwa dan pembekalan kepada berbilang kumpulan pengguna bebas daripada satu strim.

Dalam PHP, anda berhubung dengan Kafka melalui ext-rdkafka, iaitu pengikatan kepada pustaka C librdkafka yang telah terbukti.

Catatan, Bukan Baris Gilir

Perubahan cara fikir daripada RabbitMQ kepada Kafka:

  • Mesej tidak dipadam apabila diterima; mesej luput mengikut dasar pengekalan (masa atau saiz).
  • Setiap pengguna menjejaki kedudukannya sendiri — kedudukannya dalam catatan.
  • Sesuatu topik dibahagikan kepada partisi; susunan hanya dijamin dalam satu partisi.
  • Berbilang kumpulan pengguna membaca topik yang sama secara bebas.

Jika anda memerlukan main semula, pengedaran kepada ramai pembaca atau kadar pemprosesan yang sangat tinggi, Kafka sesuai. Jika anda memerlukan penghalaan bagi setiap mesej dan tempoh hayat, RabbitMQ sesuai.

Memasang ext-rdkafka

Pasang pustaka asli dahulu, kemudian sambungan PECL dan, secara pilihan, pembalut aras 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 IDE

Menghasilkan Rekod

Cipta RdKafka\Producer, dapatkan pemegang topik dan panggil produce(). Kunci menentukan partisi tempat rekod diletakkan — kunci sama, partisi sama, susunan dikekalkan. Sentiasa panggil flush() sebelum keluar, jika tidak, rekod yang disimpan dalam penimbal 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');
}

Membahagi Mengikut Kunci

Pembahagian ialah teras kebolehskalaan dan susunan Kafka. Pembahagi lalai mencincang kunci rekod: partition = hash(key) % numPartitions. Pemilihan kunci yang baik penting:

  • Gunakan customerId sebagai kunci → semua peristiwa pelanggan kekal tersusun dalam satu partisi.
  • Kunci kosong → secara bergilir merentasi partisi (kadar pemprosesan maksimum, tanpa susunan).

Anda tidak boleh mengurangkan bilangan partisi bagi sesuatu topik, dan penambahan partisi menyusun semula pemetaan cincangan — jadi tentukan saiz partisi untuk keserentakan maksimum lebih awal.

Kumpulan Pengguna dan Kedudukan

Gunakan KafkaConsumer aras tinggi dengan group.id. Kafka mengagihkan partisi merentasi ahli kumpulan dan melakukan pengimbangan semula apabila ahli menyertai atau meninggalkan kumpulan. Setiap ahli hanya membaca partisi yang diperuntukkan kepadanya, lalu memberikan penskalaan mendatar tanpa kos tambahan.

<?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 {}

Bila Hendak Mengesahkan

Pengesahan kedudukan menentukan semantik penghantaran anda:

  • Lakukan pengesahan selepas pemprosesan → sekurang-kurangnya sekali (jika ranap sebelum pengesahan, rekod akan dimainkan semula).
  • Lakukan pengesahan sebelum pemprosesan → paling banyak sekali (jika ranap, rekod akan hilang).

Pengesahan automatik (enable.auto.commit=true) dilakukan berdasarkan pemasa tanpa mengira sama ada kerja anda telah selesai — mudah digunakan, tetapi boleh menggugurkan rekod tanpa disedari apabila berlaku ranap. Lumpuhkannya dan lakukan pengesahan secara manual apabila ketepatan penting.

Mengendalikan Ralat Penerimaan

Bukan setiap nilai yang dipulangkan oleh consume() ialah mesej. Anda mesti bercabang berdasarkan kod ralat — __PARTITION_EOF dan __TIMED_OUT ialah isyarat kawalan biasa, bukannya 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);
}

Penalaan Kadar Pemprosesan

Kadar pemprosesan Kafka datang daripada pengumpulan dalam kelompok. Tetapan utama pengeluar:

  • linger.ms — tunggu sebentar untuk mengumpulkan lebih banyak rekod bagi setiap permintaan (contohnya 5–20ms).
  • batch.size / queue.buffering.max.messages — penimbal yang lebih besar, lebih sedikit perjalanan pergi balik.
  • compression.type — lz4 atau zstd mengurangkan kos rangkaian dengan ketara.
  • acks — all untuk ketahanan, 1 untuk kependaman 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 Penghantaran

Oleh sebab produce() tidak segerak, penghantaran yang gagal tidak akan menghasilkan pengecualian serta-merta. Daftarkan panggilan balik laporan penghantaran pada konfigurasi pengeluar untuk mengetahui nasib setiap rekod — inilah satu-satunya cara yang boleh dipercayai untuk mengesan kegagalan pengeluar yang senyap dalam 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);

Perangkap Khusus PHP

Kafka menganggap klien berjangka hayat panjang; kitar hayat permintaan PHP bercanggah dengan keperluan itu:

  • Pengeluar menyimpan data dalam penimbal secara tak segerak — sentiasa panggil flush() sebelum skrip tamat, jika tidak, rekod akan hilang.
  • Jalankan pengguna sebagai pekerja CLI berterusan di bawah penyelia, bukan di dalam permintaan web.
  • Pengimbangan semula menjeda penerimaan; pastikan kerja bagi setiap mesej ringkas atau gunakan max.poll.interval.ms yang lebih panjang supaya anda tidak dikeluarkan daripada kumpulan.
  • Tetapkan log_level dan daftarkan panggilan balik laporan penghantaran pengeluar untuk mengesan kegagalan senyap.

Semakan Pantas

Jaminan susunan dalam Kafka.

Ulang Kaji

Kafka, cara PHP:

  • Kafka ialah catatan yang boleh dimainkan semula, bukan baris gilir; pengguna menjejaki kedudukan.
  • Pembahagian mengikut kunci memberikan susunan bagi setiap kunci dan penskalaan.
  • Kumpulan pengguna membahagikan partisi dan melakukan pengimbangan semula secara automatik.
  • Lakukan pengesahan kedudukan selepas kerja untuk penghantaran sekurang-kurangnya sekali; lumpuhkan pengesahan automatik untuk mendapatkan kawalan.
  • Laraskan linger.ms, batch.size dan compression.type; sentiasa panggil flush().

Seterusnya: menghubungkan asas-asas ini ke dalam aliran kerja dipacu peristiwa yang boleh dipercayai.

Percuma untuk bermula

Pelajari PHP dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
49
Pelajaran
195

Soalan Lazim

Adakah pelajaran “Apache Kafka dengan PHP” percuma?

Ya — teks penuh “Apache Kafka dengan PHP” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus PHP Academy, tingkat taraf kepada CoddyKit PRO. Kursus PHP Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Apache Kafka dengan PHP”?

Alirkan peristiwa berkapasiti tinggi menggunakan Kafka. Anda berlatih PHP Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan PHP Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran PHP Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Apache Kafka dengan PHP” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran PHP Academy ini?

Ya. Setiap pelajaran PHP Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Mengapa Pemesejan Tak Segerak
  2. Bekerja dengan RabbitMQ dalam PHP
  3. Apache Kafka dengan PHP
  4. Membina Aliran Kerja Dipacu Peristiwa
← Kembali ke PHP Academy