İstek-yanıt modeliyle çalışan bir sistemde diyagramdaki oklar doğrudan çağrı grafiğidir. Olay güdümlü bir sistemde öyle değildir. Producer bir olayı bir topic'e yazar ve onu kimin okuduğunu bilmez. Bunu en basit haliyle, her servisi tek bir büyük Kafka kutusuna bağlayarak çizerseniz diyagram ihtiyacınız olan her şeyi gizler: hangi olayların var olduğunu, onlara kimin hangi sırayla tepki verdiğini ve bir consumer hata verdiğinde ne olduğunu.
Bu rehber, olay güdümlü mimari diyagramları için akışı okunur tutan bir gösterim sunuyor, Kafka üzerinde bir sipariş işleme örneğini adım adım ele alıyor ve çizilmesi en sık unutulan ayrıntıları kapsıyor: anahtarlar, consumer group'lar, outbox ve dead-letter yolu.
Diyagramın göstermesi gerekenler
Olay güdümlü bir diyagram, ayrı bir belgeye gerek kalmadan şu sorulara yanıt vermelidir:
- Hangi olaylar var? Geçmiş zaman kipinde adlandırılır; örneğin
OrderPlacedya daPaymentFailed. - Her birini kim üretiyor? Sağlıklı varsayılan, her olay tipinin tam olarak tek bir sahibi olmasıdır.
- Kim tüketiyor ve hangi consumer group olarak? Kafka'da her consumer group her olayı alır; bu yüzden her grup ayrı bir okuyucudur.
- Sıralamayı ne belirliyor? Kafka sırayı yalnızca bir partition içinde korur ve partition'ı anahtar seçer.
- Hata durumunda ne oluyor? Yeniden denemeler, dead-letter topic'ler ve replay'i kimin yaptığı.
İşe yarayan bir gösterim
| Öğe | Nasıl çizilir |
|---|---|
| Producer | Topic'e kesik çizgili bir kenarla bağlanan servis düğümü; kenar olay tipiyle etiketlenir |
| Topic | Kendi başına bir düğüm; cluster'daki adıyla (orders.v1) adlandırılır, etiketinde anahtar yer alır |
| Consumer group | Topic'ten consumer'a giden, group id ile etiketlenmiş kesik çizgili bir kenar |
| Olay ve komut | Olaylar geçmiş zamanla (OrderPlaced), komutlar emir kipiyle (ReserveStock) |
| Dead-letter topic | Vazgeçen consumer'ın beslediği ayrı bir topic düğümü |
| Connector | Bir topic ile harici bir depo arasında duran düğüm; örneğin bir warehouse sink |
| Broker cluster'ı | Topic'leri çevreleyen bir çerçeve; broker'lar ve partition'lar operasyon diyagramına aittir |
Düz çizgili kenarları yalnızca senkron çağrılar için kullanın; örneğin bir ödeme sağlayıcısına giden HTTP isteği. Böylece okuyan kişi, bir akışın hangi kısımlarının aynı istek içinde, hangilerinin daha sonra gerçekleştiğini bir bakışta görür.
Örnek: Kafka üzerinde sipariş olayları
Bir online mağaza siparişleri olaylarla işliyor:
- orders servisi siparişi ve bir outbox satırını aynı veritabanı transaction'ında yazar.
- Bir outbox relay (Kafka Connect üzerinde Debezium), outbox'ı veritabanı log'u üzerinden okur ve
OrderPlacedolayınıorder_idanahtarıylaorders.v1topic'ine yayınlar. - Üç consumer group
orders.v1topic'ini okur: payments karttan tahsilat yapar, inventory stok ayırır, bir warehouse sink de her olayı veri ambarına yükler. - Payments,
PaymentSucceededya daPaymentFailedolayını yineorder_idanahtarıylapayments.v1topic'ine yayınlar; orders servisi de sipariş durumunu güncellemek için bu topic'i tüketir. - Bir mesajı üç denemede işleyemeyen inventory, mesajı
inventory.dlqtopic'ine yazar ve sıradakine geçer.
Akışın tamamı tek bir tuvalde:
Diyagram içeriği
- Orders
- Orders DB (orders + outbox)
- Outbox relay
- Kafka cluster
- payments.v1 · key order_id
- orders.v1 · key order_id
- inventory.dlq
- Payments
- Warehouse sink
- Inventory
- Data warehouse
- order + outbox row, one transaction
- reads WAL
- OrderPlaced
- group: payments
- group: warehouse-sink
- group: inventory
- PaymentSucceeded/Failed
- group: orders
- load
- after 3 failed attempts
Diyagramın neyi apaçık ortaya koyduğuna dikkat edin: payments'ı kimse çağırmıyor, dördüncü bir consumer group eklemek üst akışta hiçbir şeyi değiştirmiyor ve iki topic de order_id ile anahtarlandığı için bir siparişin olayları her topic içinde sırasını koruyor (Kafka, topic'ler arasında sıralama garantisi vermez).
Olay güdümlü diyagramlar için beş kural
1. Topic'ler ok değil, düğümdür
"Kafka" etiketiyle orders'tan payments'a çizilmiş bir ok, var olmayan bir çağrıyı ima eder. Topic'i ikisinin arasında bir düğüm olarak çizin. Topic gerçek bir şeydir: bir adı, bir sahibi, bir saklama süresi ve bir şeması vardır.
2. Oklar veriyi izler
Producer'dan topic'e, topic'ten consumer'a, verinin hareket ettiği yönde çizin. Kafka consumer'ları veriyi kendileri çeker (pull); ama okları consumer'lardan topic'lere doğru çizen bir diyagram neredeyse herkese ters gelir. Pull semantiği tartışma için önemliyse bir not ekleyin.
3. Olayları ve consumer group'ları etiketleyin
Olay tipini producer kenarına, consumer group'u da her consumer kenarına yazın. Biri "OrderPlaced'i başka kim okuyor?" diye sorduğunda cevap, topic'ten çıkan etiketli kenarların listesidir.
4. Sıralama önemliyse anahtarı gösterin
Kafka sırayı bir partition içinde garanti eder ve aynı anahtara sahip olaylar aynı partition'a gider. Consumer'larınız OrderPlaced olayını OrderCancelled olayından önce göreceklerini varsayıyorsa anahtarı topic'in üzerine yazın: orders.v1 · key order_id. Etiketinde anahtar olmayan bir topic, bu soruyu ister istemez akla getirir.
5. Hata yolunu da çizin
Kafka consumer group'larının yerleşik bir dead-letter kuyruğu yoktur: kaç kez yeniden deneneceğine ve işlenemeyen bir mesajın nereye konacağına consumer kodunuz ya da framework'ünüz karar verir (Kafka Connect sink connector'larında ise bir dead-letter topic ayarı vardır). Bu kararı çizin. Consumer'dan bir kenarla bağlanan bir dead-letter topic ile onu kimin izlediğini ve mesajların nasıl yeniden işlendiğini anlatan bir not, sizi bir incident'tan kurtarır.
Kestirmeyi değil, outbox'ı çizin
Bir servis önce veritabanına yazıp ardından Kafka'ya iki ayrı adımda yayın yaparsa, arada yaşanan bir çökme ya bir olayın kaybolmasına ya da hiç commit edilmemiş bir değişiklik için olay yayınlanmasına yol açar. Outbox kalıbı bu çift yazmayı önler: servis olayı aynı transaction içinde bir outbox tablosuna yazar, bir relay de onu yayınlar.
Diyagramda gerçek yolu çizin: servisten veritabanına, oradan relay'e, oradan da topic'e. Servisten topic'e doğrudan giden bir ok, başka ve daha az güvenilir bir sistemi anlatır; insanlar da kararlarını buna göre verir.
Koreografi mi, orkestrasyon mu
Örnekte koreografi kullanılıyor: servisler birbirlerinin olaylarına tepki verir ve akışın tamamını yöneten kimse yoktur. Bunun yerine bir orkestratör, yani ReserveStock gibi komutlar gönderip yanıt bekleyen bir iş akışı motoru kullanıyorsanız, orkestratörü ortada bir servis olarak çizin ve kenarlarını komut olarak etiketleyin. Her iki durumda da ana akışın adımlarını kenarların üzerinde numaralandırın ki okuyanlar saga'yı sırasıyla takip edebilsin.
Cluster'ı mantıksal görünümün dışında tutun
Broker'lar, partition'lar, replikasyon faktörleri ve controller düğümleri kapasite ve operasyon için önemlidir, akışı anlamak için değil. Bunları ayrı bir operasyon diyagramına koyun. Mantıksal görünümde, topic'lerin çevresinde "Kafka cluster" etiketli bir çerçeve yeterlidir.
Archboard'da oluşturun
- Google ya da GitHub ile giriş yapın ve bir diyagram oluşturun.
- Servisleri C4 Modeli paketinden Konteyner düğümleri olarak, orders veritabanını da Veri paketinden (Postgres) ekleyin.
- Temel paketinden
Kafka clusteretiketli bir Çerçeve ekleyin ve içine Veri paketinden Konu düğümleri yerleştirin. - Outbox relay ile warehouse sink'i, Teknoloji alanında
Kafka Connectyazan konteynerler olarak ekleyin; Veri paketinden de bir Veri ambarı düğümü ekleyin. - Port'ları bağlayın, olay kenarlarını kesik çizgiye çevirin ve kenarları olay tipleri ile consumer group'larla etiketleyin.
- İnceleme için diyagramı sunum modunda açın, canlı bağlantıyı paylaşın ya da SVG ve PNG olarak dışa aktarın.
Örnek 11 diyagram düğümü kullanıyor ve Free planın 15 düğümlük sınırına sığıyor. Başka bir streaming yerleşimi için /examples/streaming-data-platform sayfasına, benzer bir mağazanın senkron tarafı için de mikroservis mimari diyagramı rehberine bakın.
SSS
Partition'ları çizmeli miyim? Mantıksal görünümde hayır. Önemliyse partition sayısını topic etiketine yazın; partition'ları ve broker'ları ise bir operasyon diyagramında çizin.
Diyagramda kuyruğun topic'ten farkı nedir? Kuyrukta her mesaj tek bir consumer'a gider; Kafka topic'inde ise her consumer group her mesajı alır. SQS ya da RabbitMQ gibi kuyruklar için bir Kuyruk düğümü kullanın ve hangi semantiğe dayandığınızı belirtin.
Olay şemaları nereye konur? Bir nota ya da topic etiketine; schema registry'ye veya şemanın sahibi olan repoya bir bağlantıyla birlikte. Diyagram, bir sözleşmenin var olduğunu ve nerede durduğunu göstermelidir.
Replay'i nasıl gösteririm?
Saklama süresini topic'in üzerine yazın (örneğin retention 7d) ve bir consumer group'un offset'lerini nasıl sıfırladığını anlatan bir not ekleyin. Replay bir tasarım özelliğidir; onu görünür kılın.
Her olay için ayrı bir diyagram mı gerekir? Hayır. Her iş akışı için bir diyagram iyi sonuç verir. Olayları kenarların üzerinde listeleyin, tam liste için de bir olay kataloğu tutun.