NATS vs RabbitMQ vs Kafka: Mana Sesuai Untuk Satu VPS?
Ketahui perbezaan NATS, RabbitMQ dan Kafka untuk satu pelayan VPS. Kami bandingkan jaminan penghantaran, penggunaan memori, serta bila Postgres lebih berbaloi digunakan.
Jawapan ringkas untuk satu pelayan
Message queue pada satu VPS adalah keputusan mengenai jaminan penghantaran, bukan mengenai kelajuan. Pada satu mesin, broker jarang menjadi penyekat (bottleneck), kerana kod aplikasi, pangkalan data dan cakera anda akan mencapai had tersebut terlebih dahulu. Pilih alat yang tingkah laku kegagalannya boleh anda terima, kemudian ukur prestasi mesin yang anda miliki.
Empat pilihan, mengikut urutan yang perlu dipertimbangkan oleh kebanyakan pembaca.
- Gunakan pangkalan data yang sudah anda jalankan. Postgres dengan
SELECT ... FOR UPDATE SKIP LOCKEDialah baris gilir tugasan (job queue) yang berfungsi, dan ia tidak menambah proses baharu untuk dipantau. - Gunakan RabbitMQ apabila setiap mesej adalah unit kerja yang mesti diakui (acknowledged), dicuba semula dalam bilangan kali yang terhad, kemudian diletakkan di tempat yang boleh diperiksa oleh manusia.
- Gunakan NATS apabila mesej adalah peristiwa yang ditindakbalas oleh beberapa bahagian sistem anda. Hidupkan JetStream untuk peristiwa yang mesti bertahan selepas but semula (restart).
- Gunakan Kafka apabila alat hiliran (downstream) hanya menggunakan protokol Kafka. Pada satu pelayan, itu hampir menjadi satu-satunya alasan yang tinggal.
Selebihnya panduan ini memberikan penjelasan: apakah kos setiap pilihan dari segi memori dan cakera pada VPS kecil, apa yang berlaku apabila mesin but semula, dan arahan tepat yang menunjukkan kepada anda tunggakan (backlog) sebelum pengguna anda merasakannya.
Maksud sebenar jaminan penghantaran
At most once bermaksud broker menyerahkan mesej tersebut dan melupakannya. Jika tiada pengguna (consumer) yang disambungkan, atau pengguna terhenti di tengah-tengah proses kerja, mesej tersebut akan hilang dan tiada apa-apa yang melaporkannya.
At least once bermaksud pengguna menghantar pengakuan (ack) selepas kerja berjaya diselesaikan. Selagi ack tersebut belum tiba, broker akan menyimpan mesej itu dan akan menghantarnya semula. Penghantaran semula adalah sebab mengapa pengendali (handler) anda mestilah bersifat idempoten: memproses mesej yang sama dua kali tidak boleh menyebabkan kad dicaj dua kali. Exactly once, dari hujung ke hujung, bukanlah sesuatu yang disediakan oleh broker. Ia datang daripada kunci unik dalam pangkalan data anda sendiri.
Replay ialah sifat yang berasingan. Baris gilir (queue) akan membuang mesej sebaik sahaja ia diakui. Log pula menyimpannya untuk tempoh pengekalan tertentu, supaya pengguna baharu boleh bermula dari awal dan membaca keseluruhan sejarah. Kafka dan NATS JetStream adalah log. RabbitMQ adalah baris gilir. Perbezaan itu membentuk lebih banyak seni bina berbanding kadar pemprosesan (throughput).
Dead lettering ialah perkara yang berlaku kepada mesej yang terus gagal. Tanpanya, mesej "beracun" (poison message) akan bergelung selama-lamanya, dan gelung tersebut kelihatan seperti pekerja yang sibuk dan bukannya pekerja yang rosak.
Mulakan dengan Postgres dan biarkan broker membuktikan keupayaannya
Kebanyakan beban kerja aplikasi tunggal hanya melibatkan beberapa ribu tugasan latar belakang sehari. Jumlah ini muat dalam satu jadual.
CREATE TABLE job (
id bigserial PRIMARY KEY,
payload jsonb NOT NULL,
run_after timestamptz NOT NULL DEFAULT now(),
attempts int NOT NULL DEFAULT 0
);
CREATE INDEX job_ready_idx ON job (run_after, id);Seorang pekerja menuntut satu tugasan di dalam satu transaksi.
BEGIN;
SELECT id, payload
FROM job
WHERE run_after <= now()
ORDER BY id
FOR UPDATE SKIP LOCKED
LIMIT 1;
-- run the work, then remove the row
DELETE FROM job WHERE id = $1;
COMMIT;FOR UPDATE SKIP LOCKED ialah helah keseluruhannya. Ia mengunci baris yang dikembalikan dan melangkau mana-mana baris yang telah dikunci oleh transaksi lain, jadi dua pekerja tidak akan menuntut tugasan yang sama. Jika seorang pekerja terhenti secara tiba-tiba, Postgres akan membatalkan transaksinya, kunci akan dilepaskan, dan baris tersebut menjadi boleh dilihat oleh pekerja seterusnya. Anda mendapat penghantaran sekurang-kurangnya sekali (at-least-once delivery), percubaan semula dengan meningkatkan attempts, dan jadual surat mati (dead letter table), semuanya dengan ketahanan data yang anda sudah bayar. Tunggakan tugasan hanyalah satu pertanyaan: SELECT count(*) FROM job WHERE run_after <= now();
Di mana ia berhenti berfungsi. Setiap tuntutan dan pemadaman adalah satu penulisan, jadi kadar tugasan yang tinggi akan meninggalkan versi baris mati, dan jadual baris gilir adalah kes klasik di mana bloat mengatasi autovacuum. Tugasan yang lama memburukkan lagi keadaan, kerana transaksi yang dibiarkan terbuka sepanjang tempoh kerja juga menahan ufuk vakum (vacuum horizon) bagi keseluruhan pangkalan data. Polling menambah latensi, dan LISTEN dengan NOTIFY membuang polling tetapi bukan penulisan. Apabila jadual tugasan menjadi jadual paling sibuk yang anda miliki, atau perkhidmatan kedua memerlukan peristiwa yang sama, pindahkan kerja tersebut keluar. Pilihan itu berinteraksi dengan cara pangkalan data itu sendiri digunakan, jadi tentukan sama ada pangkalan data berjalan dalam Docker atau pada hos sebelum anda menambah broker di sebelahnya.
Redis adalah perkara lain yang mungkin sudah anda jalankan. Redis Streams memberikan anda kumpulan pengguna dengan XADD dan XREADGROUP, senarai tertunda bagi setiap kumpulan, dan XAUTOCLAIM untuk mengambil semula kerja daripada pengguna yang telah terhenti. Ia kecil dan pantas. Kekangan jujur pada satu kotak: dengan tetapan appendfsync everysec yang biasa, kehilangan kuasa boleh menyebabkan kehilangan kira-kira satu saat penulisan. Itu tidak mengapa untuk pembatalan cache tetapi salah untuk pembayaran. Jika aplikasi anda adalah satu proses tunggal yang dibina di sekitar SQLite dalam pengeluaran pada VPS, corak tuntut-dan-padam yang sama berfungsi, walaupun SQLite tidak mempunyai setara dengan SKIP LOCKED dan setiap pekerja bersiri pada satu kunci tulis.
NATS core: penghalaan subjek tanpa memori
docker run -d --name nats \
-p 4222:4222 -p 127.0.0.1:8222:8222 \
nats:2.14 -m 8222Sehingga Ogos 2026, barisan pelayan semasa ialah 2.14. -m 8222 menghidupkan port pemantauan HTTP, yang dimatikan secara lalai dan tidak mempunyai pengesahan, jadi ikat (bind) ia kepada localhost seperti di atas.
NATS teras adalah bersifat "at most once" dan ia tidak menyimpan apa-apa. Penerbit menghantar kepada subjek seperti orders.created, dan setiap pelanggan (subscriber) yang penapisnya sepadan akan mendapat satu salinan. Jika tiada sesiapa yang melanggan, mesej tersebut digugurkan dan penerbit tidak melihat sebarang ralat, kerana tugas penerbit tamat sebaik sahaja pelayan menerima bait tersebut. Kumpulan baris gilir (beberapa pelanggan yang berkongsi satu nama kumpulan) menyebabkan pelayan memilih satu ahli bagi setiap mesej, yang berkongsi beban kerja tanpa menyimpan baris gilir.
Jejak memori (footprint) adalah status langganan ditambah penimbal tulis (write buffer) untuk setiap sambungan, jadi ia menjejaki bilangan sambungan dan bukannya volum mesej, dan tiada apa-apa yang terkumpul pada cakera. Kelakuan selepas but semula (restart) adalah berdasarkan perkara tersebut: mesej yang sedang dalam transit akan hilang, pelanggan akan menyambung semula secara automatik, dan tiada langkah pemulihan yang perlu ditunggu.
Tiada tunggakan (backlog) untuk dipantau, jadi pantau kehilangan mesej sebaliknya. Apabila pelanggan membaca soketnya dengan lebih perlahan daripada pelayan menulis kepadanya, penimbal pelayan untuk pelanggan tersebut akan penuh. Jika pelanggan tidak sempat mengejar sebelum tarikh akhir penulisan, pelayan akan menutup keseluruhan sambungan dan menambah nilai pembilang.
curl -s http://localhost:8222/varz | jq '.slow_consumers, .connections, .in_msgs, .out_msgs'Nilai slow_consumers yang terus meningkat bermakna mesej sedang digugurkan, jadi tetapkan amaran untuknya dan bukannya membacanya sekali sahaja. NATS teras sesuai untuk mesej yang nilainya luput dengan cepat: metrik, kemas kini kehadiran, atau pembatalan cache yang akan digantikan oleh acara seterusnya.
NATS JetStream: strim tahan lasak dan main semula dalam proses yang sama
JetStream bukanlah produk kedua. Ia merupakan subsistem dalam binari yang sama, yang diaktifkan dengan satu flag.
docker run -d --name nats \
-p 4222:4222 -p 127.0.0.1:8222:8222 \
-v nats-data:/data \
nats:2.14 -js -sd /data -m 8222-sd /data menetapkan direktori storan. Jika ditinggalkan, JetStream akan menyimpan datanya di bawah /tmp, yang ketahanannya adalah seperti yang digambarkan oleh namanya. Cipta strim menggunakan CLI, yang disertakan dalam imej nats-box.
docker run --rm -it --network host natsio/nats-box:latest \
nats stream add ORDERS \
--subjects 'orders.>' \
--storage file \
--retention limits \
--max-age 72h \
--max-bytes=1073741824 \
--discard old \
--defaultsSetiap had di situ penting untuk pelayan bersaiz kecil. --storage file ialah perkara yang terselamat daripada kegagalan sistem (crash), memandangkan strim memori tidak akan terselamat. --max-bytes=1073741824 mengehadkan strim kepada 1 GiB yang ditulis sebagai kiraan bait, dan --discard old akan membuang mesej paling lama apabila had dicapai dan bukannya menolak penulisan baharu. Jika had tidak ditetapkan, penerbit yang tidak terkawal akan memenuhi cakera, dan pada ketika itu pangkalan data anda juga akan terhenti kerana ia berkongsi cakera yang sama.
Pengguna (consumer) yang tahan lasak mengekalkan kedudukannya sendiri dalam strim dan mengekalkannya merentasi but semula. Tetapkan --max-deliver pada pengguna supaya mesej yang sentiasa gagal berhenti dihantar semula selama-lamanya. Apabila mesej kehabisan percubaan penghantaran, JetStream menerbitkan notis nasihat pada $JS.EVENT.ADVISORY.CONSUMER.MAX_DELIVERIES.>, dan melanggan subjek tersebut adalah cara anda membina laluan dead letter yang diberikan oleh RabbitMQ sebagai satu ciri. Itu adalah kerja sebenar yang anda tulis sendiri.
Untuk melihat tunggakan, jalankan nats stream report bagi kiraan mesej yang disimpan dan nats consumer report ORDERS bagi pengakuan (acknowledgements) yang belum selesai serta mesej yang belum diproses bagi setiap pengguna. Nombor yang belum diproses adalah perkara yang perlu diberi amaran. Kos cakera boleh dilihat dengan du -sh terhadap direktori storan, dan ia akan terus berkembang sehingga had pengekalan mengecilkannya.
RabbitMQ: akui setiap mesej, parkir kegagalan
docker run -d --name rabbitmq \
-p 5672:5672 -p 127.0.0.1:15672:15672 \
-v rabbitmq-data:/var/lib/rabbitmq \
rabbitmq:4-managementSehingga Ogos 2026, siri semasa ialah 4.3. Port 5672 ialah AMQP (advanced message queuing protocol) dan 15672 ialah antara muka pengurusan. Kekalkan antara muka tersebut pada localhost dan capai ia melalui SSH tunnel.
Isytiharkan baris gilir (queues) dengan argumen x-queue-type ditetapkan kepada quorum; lalai (default) masih lagi classic. Quorum queues sentiasa bersifat tahan lama (durable) dan menulis data ke cakera sebelum melakukan perkara lain, jadi pada satu nod anda mendapat satu kelakuan yang jelas dan bukannya matriks pilihan tahan lama dan sementara. Tetapkan sasaran dead letter dengan polisi.
docker exec rabbitmq rabbitmqctl set_policy DLX ".*" \
'{"dead-letter-exchange":"my-dlx", "dead-letter-routing-key":"my-routing-key"}' \
--apply-to queues --priority 7Sesuatu mesej akan menjadi dead letter atas empat sebab: pengguna (consumer) menolaknya dengan basic.reject atau basic.nack dan requeue ditetapkan kepada false, TTL (time to live) per-mesejnya tamat, baris gilir melepasi had panjang, atau ia melebihi had penghantaran quorum queue. Had tersebut ditetapkan secara lalai kepada 20 bermula dari RabbitMQ 4.0 dan seterusnya, jadi pengendali yang membuang (throw) dan melakukan nack akan mencuba semula sebanyak dua puluh kali dan kemudian menyerahkan mesej tersebut kepada dead letter exchange dan bukannya bergelung (looping).
Memori adalah tempat di mana RabbitMQ mengejutkan pengguna pada VPS kecil. Tanda aras tinggi (high watermark) lalai ialah 0.6 daripada RAM yang tersedia, dan apabila nod melintasinya, RabbitMQ menyekat setiap sambungan yang sedang menerbitkan (publishing) mesej. Aplikasi anda tidak menerima ralat. Ia menerima terbitan yang tidak pernah kembali, yang kelihatan seperti tergantung (hang) dalam kod anda sendiri. Log permulaan mencetak nombor yang dikira oleh nod tersebut:
Memory high watermark set to 1024 MiB (1073741824 bytes) of 8192 MiB (8589934592 bytes) totalPenggera cakera menyekat penerbit dengan cara yang sama apabila ruang bebas jatuh di bawah 50 MB secara lalai. Quorum queues menambah aritmetik mereka sendiri di atasnya: dokumentasi memperuntukkan sekurang-kurangnya 32 bait metadata dalam memori bagi setiap mesej, kira-kira 1 MB bagi setiap 30,000 mesej, dan mengesyorkan sekurang-kurangnya tiga kali ganda saiz write-ahead log yang berkesan dalam RAM. Had WAL lalai ialah 512 MiB, jadi cadangan itu sahaja memerlukan 1.5 GB. Pada pelayan 2 GB, rendahkan nilainya dalam rabbitmq.conf dan bukannya mengharapkan nilai lalai itu mencukupi.
raft.wal_max_size_bytes = 64000000
vm_memory_high_watermark.relative = 0.5Backlog terdiri daripada dua nombor, dan pasangan tersebut memberitahu anda kegagalan yang mana satu yang anda hadapi.
docker exec rabbitmq rabbitmqctl list_queues name messages messages_ready messages_unacknowledgedmessages_ready sedang menunggu pengguna. messages_unacknowledged telah dihantar dan tidak pernah diakui (acked). Kiraan tidak diakui yang meningkat di sebelah kiraan sedia yang mendatar bermakna pekerja anda mengambil tugasan tersebut dan berhenti menyelesaikannya, yang merupakan pepijat yang berbeza daripada baris gilir yang hanya ketinggalan.
Kafka pada satu kotak, dan di mana ia tidak lagi masuk akal
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
bin/kafka-storage.sh format --standalone -t $KAFKA_CLUSTER_ID -c config/server.properties
bin/kafka-server-start.sh config/server.propertiesItu adalah panduan permulaan pantas untuk Kafka 4.3.1, yang terkini setakat Ogos 2026, berjalan dalam mod KRaft (Kafka Raft, pengawal terbina dalam yang menggantikan ZooKeeper dalam Kafka 4.0). Setara kontena adalah apache/kafka:4.3.1.
Skrip permulaan menetapkan export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" apabila anda tidak menetapkannya sendiri, jadi broker menempah 1 GB Java heap sebelum ia menyimpan satu mesej pun, dan ia menjangkakan RAM percuma di luar jumlah itu untuk page cache yang dibacanya. Pada VPS 2 GB, aplikasi anda kemudiannya bersaing dengan JVM untuk baki RAM yang ada.
Retention adalah kejutan seterusnya. log.retention.hours secara lalai ialah 168, iaitu tujuh hari, dan log.retention.bytes secara lalai ialah -1, yang bermaksud tiada had saiz langsung. Kafka menyimpan mesej untuk keseluruhan tempoh tersebut sama ada setiap pengguna telah membacanya atau tidak. Itu adalah ciri yang anda cari, dan pada satu cakera kecil ia juga merupakan mod kegagalan, jadi tetapkan had bait bagi setiap topik sebelum anda menyedarinya.
Sekarang bahagian yang jujur. Broker tunggal bermakna replication factor 1, jadi acks=all diselesaikan kepada satu fsync pada satu cakera. Anda mendapat ketahanan satu mesin, dengan kos operasi broker JVM ditambah pengawal. Partition memberikan kesejajaran merentas broker yang anda tidak miliki. Replication, rack awareness dan ciri-ciri kumpulan yang lain kekal tidak aktif. JetStream memberikan anda main semula tahan lama yang sama pada kotak yang sama untuk sebahagian kecil daripada memori. Dua sebab masih mewajarkan Kafka di sini: alat hiliran hanya bercakap protokol Kafka (change data capture dengan Debezium, atau pemuat analitik), atau anda sedang menghasilkan semula topologi pengeluaran dalam bentuk kecil. Merancang untuk berkembang menjadi kluster adalah rancangan untuk membeli lebih banyak mesin, dan sehingga itu, pertukarannya adalah sama seperti menjalankan k3s pada satu nod, di mana anda membayar kerumitan kluster untuk kebolehpercayaan satu nod.
Backlog dalam Kafka ialah consumer lag.
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-groupBaca lajur LAG, iaitu LOG-END-OFFSET tolak CURRENT-OFFSET untuk setiap partition. Lag yang meningkat pada satu partition sementara yang lain kekal rata menunjukkan kunci yang tidak sekata, kerana semua mesej dengan kunci yang sama mendarat pada partition yang sama dan satu pengguna mengendalikannya secara bersendirian.
Apa yang berlaku apabila pelayan dimulakan semula
Core NATS kehilangan semua data yang sedang diproses dan kembali beroperasi serta-merta, kerana tiada data yang perlu dipulihkan. JetStream memuatkan semula strim dan kedudukan pengguna (consumer) daripada direktori storan, jadi pengguna akan menyambung semula pada offset yang sedia ada. RabbitMQ memulihkan quorum queues daripada cakera, manakala classic transient queues dan sebarang mesej yang diterbitkan tanpa mod persistent delivery akan hilang. Kafka memainkan semula segmen lognya semasa permulaan, dan selepas penutupan yang tidak sempurna, imbasan pemulihan tersebut boleh mengambil masa beberapa minit pada cakera kecil sebelum broker menerima sambungan.
Dua perkara perlu ditetapkan sekali sahaja. Berikan polisi mulakan semula (restart policy) kepada kontena (restart: unless-stopped) atau aktifkan unit systemd, supaya broker kembali beroperasi selepas but semula akibat naik taraf kernel tanpa campur tangan anda. Kemudian, uruskan susunan: broker yang siap sedia dua puluh saat selepas aplikasi anda akan menolak sambungan pertama, dan sesetengah pustaka klien akan keluar (exit) dan bukannya mencuba semula. Kawal aplikasi tersebut dengan broker menggunakan Compose healthchecks yang menahan servis bergantung sehingga broker siap sedia.
Kos pada VPS anda sendiri, diukur bukannya dipetik
Angka throughput yang diterbitkan diukur pada perkakasan yang tidak anda miliki, biasanya pelayan berbilang teras dengan NVMe tempatan. Anggap angka tersebut sebagai had atas dan ukur kotak anda sendiri.
docker stats --no-stream
free -m
sudo du -sh /var/lib/docker/volumes/*/_dataJalankan ujian tersebut semasa broker melahu, kemudian jalankan sekali lagi di bawah trafik sebenar anda. Jurang antara kedua-duanya ialah angka yang menentukan sama ada broker tersebut sesuai diletakkan di samping aplikasi anda. Untuk anggaran throughput minimum yang kasar, gunakan penjana beban (load generator) projek itu sendiri dan bukannya catatan blog orang lain: nats bench pub test --msgs 100000 --clients 2 untuk NATS, bin/kafka-producer-perf-test.sh untuk Kafka, dan PerfTest untuk RabbitMQ. Menjalankan penjana pada VPS yang sama akan mengukur broker dan penjana secara serentak, yang boleh diterima selagi anda menyatakannya apabila melaporkan angka tersebut.
Satu had siling terpakai untuk kesemuanya. Setiap pilihan tahan lama (durable option) di sini menunggu fsync, jadi pada VPS dengan storan yang disambungkan melalui rangkaian, cakera menetapkan hadnya, dan menukar broker tidak akan mengubah had tersebut.
Tiga beban kerja dan baris gilir mesej yang diperlukan oleh setiap satunya
- Tugasan latar belakang untuk satu aplikasi web, seperti menghantar e-mel, mengubah saiz imej, atau menyampaikan webhook. Mulakan dengan Postgres dan
SKIP LOCKED. Beralih kepada RabbitMQ dengan quorum queues apabila anda memerlukan pengakuan (ack) bagi setiap mesej, had penghantaran, dan dead letter queue yang boleh diperiksa tanpa perlu menulis logik tersebut sendiri, atau apabila jadual tugasan telah menjadi jadual paling sibuk dalam pangkalan data. - Peristiwa yang ditindakbalas oleh beberapa servis dalaman, di mana mesej yang hilang akan digantikan dengan cepat oleh mesej yang lebih baharu. Gunakan Core NATS, dengan subjek sebagai skema penghalaan dan queue groups di mana anda memerlukan perkongsian kerja. Tambahkan stream JetStream untuk set subjek terhad yang perlu bertahan selepas but semula, dan biarkan selebihnya dalam memori.
- Log peristiwa yang dibaca oleh pengguna dari permulaan, untuk jejak audit, membina semula model bacaan, atau menyalurkan analitik kemudian. Gunakan JetStream dengan storan fail dan had bait (byte cap) yang eksplisit. Pilih Kafka hanya apabila alat hiliran memerlukan protokol Kafka, dan terima penggunaan JVM heap sebagai harga untuk keserasian tersebut.
Kos bagi pilihan yang salah pada satu pelayan bukanlah throughput. Ia adalah pemulihan pada pukul tiga pagi, apabila anda perlu mengetahui sama ada mesej tersebut masih wujud. Buat pilihan berdasarkan perkara itu.
FAQ
Bolehkah saya menjalankan Kafka pada VPS 2 GB?
Ia boleh bermula, tetapi ruangnya sangat terhad. bin/kafka-server-start.sh menetapkan KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" apabila anda tidak mengubahnya, jadi JVM akan menuntut 1 GB sebelum menyimpan sebarang mesej, dan Kafka bergantung pada memori bebas selebihnya untuk page cache. Jika anda menambah aplikasi dan pangkalan data pada pelayan yang sama, sistem akan mula menggunakan swap. Anda juga akan mendapat replication factor 1, bermakna acks=all hanyalah satu fsync pada satu cakera; anda menanggung kos operasi Kafka tanpa model ketahanan datanya. NATS JetStream memberikan keupayaan ulangan (replay) yang tahan lama pada perkakasan yang sama dengan penggunaan memori yang jauh lebih rendah.
Adakah saya perlukan baris gilir mesej jika saya sudah menjalankan Postgres?
Selalunya tidak. Bacaan jadual job dengan SELECT ... FOR UPDATE SKIP LOCKED di dalam transaksi memberikan penghantaran sekurang-kurangnya sekali (at-least-once delivery), pekerja serentak yang selamat, percubaan semula dan jadual dead letter, tanpa servis tambahan untuk dipantau serta sandaran yang sudah pun anda lakukan. Isyarat untuk beralih keluar adalah khusus: jadual baris gilir menjadi beban tulis paling berat anda dan autovacuum ketinggalan, tugasan yang berjalan lama menahan transaksi terbuka dan menyekat vacuum untuk keseluruhan pangkalan data, atau servis kedua perlu menggunakan peristiwa yang sama secara bebas.
Patutkah saya menggunakan NATS JetStream atau RabbitMQ untuk tugasan latar belakang?
Gunakan RabbitMQ jika anda mahukan pengakuan (acknowledgement) setiap mesej, had penghantaran dan penghalaan dead letter sebagai ciri terbina dalam. Quorum queues sentiasa tahan lama, had penghantaran ditetapkan secara lalai kepada 20 bermula dari RabbitMQ 4.0, dan polisi akan menghantar mesej yang gagal ke dead letter exchange yang boleh anda kosongkan dan periksa. Gunakan JetStream jika peristiwa yang sama juga perlu diulang oleh pengguna lain kemudian, kerana stream menyimpan mesej selepas pengakuan manakala baris gilir tidak. Dengan JetStream, anda menetapkan --max-deliver dan membina laluan dead letter sendiri daripada nasihat $JS.EVENT.ADVISORY.CONSUMER.MAX_DELIVERIES.>.
Bagaimanakah cara untuk mengetahui sejauh mana pengguna saya ketinggalan?
Setiap broker mempunyai satu arahan. Untuk RabbitMQ, rabbitmqctl list_queues name messages messages_ready messages_unacknowledged memisahkan kerja yang menunggu pengguna daripada kerja yang telah dihantar tetapi tidak pernah diakui (acked). Untuk JetStream, nats consumer report <stream> menunjukkan mesej yang belum diproses dan pengakuan yang belum selesai bagi setiap pengguna. Untuk Kafka, kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group <group> mencetak lajur LAG bagi setiap partition. Core NATS tidak mempunyai backlog untuk dibaca kerana ia tidak menyimpan apa-apa, jadi pantau pembilang slow_consumers pada http://localhost:8222/varz sebaliknya: ia mengira sambungan yang ditutup oleh pelayan kerana ketinggalan, yang bermaksud kehilangan mesej.