Selamlar,
Şimdi ana bir adet sunucumuz var.
Bu sunucumuza saniyede 20 adet sipariş gelecek.
Bu sunucu saniyede gelen 20 siparişi 10 farklı VDS makinelerine 5 saniye icinde bildirmeli ve neredeyse ve neredeyse asla yığılma olmamalı.
Şimdi ben şurada şöyle bir şey düşündüm;
10 Farklı makine her biri -> 1 worker
Yani 10 workerimiz var.
10 worker her 5 saniye aralıklarla ana sunucuya istek atsın ve eğer sipariş var ise siparişi işlesin diye düşündüm. Ama bu pek mantıklı gelmedi neden bilmiyorum ama yeteri kadar optimize gelmedi.
O zaman da şu mimariye geçtim:
Ana sunucuya sipariş gelir,araya bir tane websocket açarız sipariş geldiğinde ana sunucu websockete şuanda elimde sipariş var diye istek atsın ve bu şekilde sipariş olmadığında boşu boşuna DB istegi olmadan websocketde istekler kalır,siparişler geldiğinde ise websockete aktarılır sipariş işlenir sipariş islendikten sonra response en son ana sunucuya tekrar aktarılır diye düşündüm.
Bu şekilde hem daha az istek ana makineye ulaşır bu sayede fazla DB sorgusu olmaz ve wss ile anlık olarak wss izlenir siparişler daha hızlı işlenir gibime geldi.
Sizlere de sorayım,sizce bu mimari uygun mudur?
Eğer uygun değil ise neden ve nasıl geliştirebilirim?
Veya daha farklı bir mantık önerebilir misiniz?
Bu Yazılım İçin Bu Mimari Mantıklı Mı?
9
●286
- 12-11-2025, 02:04:15
- Kabul Edilen Cevap
- 2 Beğeni
-
- 12-11-2025, 02:15:31soylenmezsmt adlı üyeden alıntı: mesajı görüntüle
Düşündüğün 1. Yaklaşım Polling (workerlar sürekli sorgu atıyor)
10 VDS makinesi her 5 saniyede bir ana sunucuya sipariş var mı? diye soruyor.
Avantaj:
- Basit implementasyon.
- Failover durumu net (worker çökse bile diğerleri devam eder).
Dezavantaj:
- Gereksiz istek trafiği (polling overhead).
→ 10 worker × her 5 sn = dakikada 120 istek, saatte 7200 istek, boşuna. - Sipariş geldiği an gecikme olur (en fazla 5 sn).
- Ana sunucu gereksiz CPU + DB yükü alır.
- Gerçek zamanlı sistem değildir.
Bu çözüm çalışır, ama ölçeklenebilir değil ve optimize değil.
🔹 Düşündüğün 2. Yaklaşım WebSocket (push-based iletişim)
Ana sunucuya sipariş gelir, WebSocket üzerinden bağlı workerlara yeni sipariş var bildirimi gönderilir.
Avantaj:
- Gerçek zamanlı (zero-delay).
- Gereksiz sorgu yok, yük minimize.
- DBye fazladan erişim yok.
- Sipariş anında VDSe push edilir.
Dezavantaj:
- WebSocket bağlantı yönetimi karmaşıktır (özellikle 10+ worker olsa bile).
- Tek ana sunucu fan-out işlemini yapıyorsa, o sunucuya fazla yük binebilir.
- Eğer ana sunucu down olursa ya da network partition olursa sipariş kaybı yaşanabilir.
- Tek noktadan hata riski (SPOF Single Point of Failure).
Pollinge göre çok daha doğru yön, ama doğrudan WebSocket üzerinden dağıtım yapmak ölçeklenebilirlik açısından zayıf kalır.
Burada bir aracı katman (message broker) gerekir.
✅ En Doğru Mimari Message Queue + Worker Pool + Event-Driven
Gerçek dünyadaki scalable çözüm şu şekilde olur 👇
🧩 Bileşenler
- Ana API Sunucusu
- Sipariş alır (HTTP POST).
- Siparişi direkt DBye değil, mesaj kuyruğuna (Queue) atar.
- (Örn: RabbitMQ, Redis Streams, Kafka, NATS, SQS)
- Mesaj Kuyruğu / Broker
- Gelen siparişleri sıraya koyar.
- Her siparişi sadece bir workera teslim eder (round-robin, fan-out vb.).
- Geri basınç (backpressure) yönetimi yapar → yığılmayı engeller.
- Otomatik retry, ACK/NACK yönetimi.
- Workerlar (10 VDS)
- Her biri kuyruğa abone olur.
- Yeni sipariş geldiğinde mesajı alır, işler, sonucu geri gönderir (örneğin HTTP callback veya başka bir queueya result mesajı atar).
- Opsiyonel: WebSocket Katmanı (Monitoring için)
- Ana sunucu, sipariş işlendi durumlarını canlı izlemek için WebSocket üzerinden admin/monitor ekranına push edebilir.
🔄 Akış Örneği:
Kullanıcı -> Ana Sunucu (HTTP) Ana Sunucu -> Queue (publish) Queue -> Worker (consume) Worker -> Ana Sunucu (result) Ana Sunucu -> WebSocket (client notification)
💡 Bu Yapının Avantajları
- Yığılma (backpressure) yok: Queue yönetir.
- Saniyede 20 sipariş değil, 200 bile olsa sistem kaldırır.
- Retry ve fault tolerance var.
- Gerçek zamanlı işleyiş mümkün.
- DB sadece sipariş kaydı ve durum için kullanılır.
- WebSocket trafiği sadece izleme veya sonuç bildirimi için olur.
- 12-11-2025, 02:20:17ikinci yaklaşımın ilkinden çok daha iyi ama event-driven düşünmek gerekir, websocket yerine direkt Message Queue (RabbitMQ/Redis/Kafka) kullansan daha reliable olur, siparişler queueya düşer, workerlar kuyruğu dinler, otomatik load balancing yapılır, worker down olsa bile sipariş kaybolmaz, ölçeklendirmesi kolay olur, websocket de olur ama connection management zor, queue bu iş için endüstri standardıdır(BullMQ veya RabbitMQ işini görecektir, Kafka gereksiz olabilir) Polling kesinlikle çok kötü bir pratik zaten, 5 saniye beklemek yerine sipariş geldiği anda push etmek lazım. Lock konusunda da queue düzgün kullanılırsa her sipariş zaten tek workera gider, temel seviyede lock gereksiz çünkü queue kendisi koordine eder. Ama kritik işlemlerde (ödeme, stok düşme) veya worker crash sonrası requeue durumlarında idempotency için distributed lock eklemen iyi olur, mümkünse Redis..
- 12-11-2025, 02:26:042. Yaklaşım en mantıklısı ama illa redis vs kullanmasına gerek yok. Yapılan işleme bağlı. Bir workerin işi bitince/boşta olunca workere iş yönlendirerek dağıtımı kendi de yapabilir.mobileforge adlı üyeden alıntı: mesajı görüntüle
- 12-11-2025, 02:35:08Hocam yine rahatsız ediyorum ama ufak bir sorum daha var.Tarikkaya adlı üyeden alıntı: mesajı görüntüle
1 numaralı worker, 1 IDli siparişi aldı ve şu anda işliyor ise, diğer 9 sunucu boş demektir.
Diyelim ki bir sipariş daha geldi ve bu da yine 1 numaralı workera gitti. Böyle olunca diğer 9 sunucu hâlâ boşta kalıyor ama 1 makine 2 siparişi aynı anda işliyor, bu da servisi yavaşlatıyor.
Normalde, bu yeni siparişi diğer boş sunuculardan birinin alması gerekirdi.
Bunun için şöyle yapmak mantıklı mı:
Bütün workerların kendine ait bir WSS bağlantısı olacak, aradaki Redis sunucusu ise sırasıyla veya boşluk-doluluk oranına göre siparişleri rastgele atayacak.
Böyle yapmak mantıklı mı, yoksa daha mantıklı bir yöntem
var mı? - 12-11-2025, 02:39:54anlattığın okurken bile kafam karıştı niye bu kadar karışık yapıyorsun ki yada sürekli api yaptırıyorsun ki
ana server a gelenleri her bir robota id ata ana makina her birisini bir bot / robot a aktarsın atıyorum durumu bekleme ise robotu işlemede yapsın bitince geri true dönsün varsa response dönsün drumunu beklemeye al - 12-11-2025, 02:45:02Ana sunucunun sipariş işleme işlemlerinden tamamen uzak ve rahat olması gerekiyor. Saniyede 20-30 istek az bir istek sayısı değil ve olası bir yığılmada ana sunucu gelecsk olan siparişleri mı databaseye kaydetsin,sipariş durumu sorgulamaya mı baksın yoksa bir de siparişleri işlemeye mı yorulsun diye karmaşık mükemmellik yapmaya çalışıyorum hocam. Tabii en sade haliyle.Melihhh adlı üyeden alıntı: mesajı görüntüle
- 12-11-2025, 02:50:01Bu cevap, konu sahibi tarafından kabul edilebilir bir cevap olarak işaretlendi.Hocam queue zaten tam olarak istediğin şeyi yapıyor. Competitive consumers patternde her worker queueyu dinler ve queue round-robin(RabbitMQ bu algoritmayı kullanıyor load balancing için) ile mesajları dağıtır, worker bir siparişi işliyorsa ve ack göndermeden yeni mesaj çekmez, yeni sipariş geldiğinde boş olan worker o işi alır. Tek yapman gereken prefetch countu doğru ayarlamak prefetch=1 yaparak her workerın aynı anda sadece 1 sipariş almasını garantilersin, böylece load tam dengeli dağılır. Websocket ile manuel dağıtım yapman gereksiz çünkü queue zaten bunu yapıyor ve battle-tested, sen Redis ile load balancer yazarsan ekstra complexity eklersin, hata riski ortaya çıkar.Kritik işlemler için (ödeme, stok gibi) idempotency kontrolü ve gerekirse distributed lock eklemen iyi olur ama temel load balancing için queuenun kendi mekanizması yeterli, bu işini görecektirsoylenmezsmt adlı üyeden alıntı: mesajı görüntüle
- 12-11-2025, 02:54:54Çok teşekkür ediyorum hocamTarikkaya adlı üyeden alıntı: mesajı görüntüle
