Blog / Teknoloji

Go ile yüksek eşzamanlılık: PsyBank'ın görüşme altyapısı

Binlerce eşzamanlı video seansını tek Go servisiyle nasıl yönettik? Goroutine mimarisi, WebRTC sinyalleşmesi ve yük testlerinden öğrendiklerimiz.

PsyBank'ı tasarlarken en net gereksinimlerden biri şuydu: bir terapi seansı asla kesilmemeli. Video görüşmesi düşen bir danışan için bu, alışveriş sepetinin boşalmasından çok daha hassas bir an. Bu yazıda, platformun görüşme altyapısını Go ile nasıl kurduğumuzu, hangi kararları neden verdiğimizi ve yük testlerinde öğrendiklerimizi anlatacağız.

Yazının sonunda elinizde şunlar olacak: goroutine tabanlı oturum yönetiminin kaba mimarisi, WebRTC sinyalleşme sunucusunun Go'daki iskeleti ve 10.000 eşzamanlı bağlantı hedefiyle yaptığımız testlerin sonuçları.

Neden Go?

Görüşme altyapısının doğası gereği uzun ömürlü, düşük gecikmeli on binlerce bağlantıyı aynı anda açık tutması gerekiyor. Thread-per-connection modelleri bu ölçekte bellek maliyetiyle boğuşurken, Go'nun goroutine'leri birkaç KB'lık yığınlarla başlayıp ihtiyaca göre büyüyor. Her seans için üç goroutine açıyoruz: sinyalleşme, durum izleme ve kayıt akışı.

func handleSession(s *Session) {
  go s.signal()   // WebRTC sinyalleşme
  go s.monitor()  // bağlantı sağlığı
  go s.audit()    // KVKK denetim izi
}

Bu modelin güzelliği basitliğinde: her seansın yaşam döngüsü kendi goroutine'lerinde izole. Bir seansta oluşan hata diğerlerini etkilemiyor; context iptalleriyle kapanış tek satıra iniyor.

Sinyalleşme katmanı

WebRTC'de medya uçtan uca akar; sunucunun görevi tarafları tanıştırmaktır. Sinyalleşme sunucumuz WebSocket üzerinden SDP tekliflerini ve ICE adaylarını taşıyor. Redis pub/sub, birden fazla sunucu örneği arasında oda durumunu senkron tutuyor — böylece danışan ve terapist farklı sunuculara düşse bile eşleşme sorunsuz kuruluyor.

Seans içeriği hiçbir zaman sunucuya uğramaz. Sunucu yalnızca "kim, kiminle, hangi odada" bilgisini bilir — KVKK uyumunun temeli bu ayrımdır.

Yük testleri: 10.000 eşzamanlı seans

Yayın öncesi hedefimiz tek düğümde 10.000 eşzamanlı WebSocket bağlantısını, p99 gecikmesi 50ms altında tutarak taşımaktı. Test kurulumunda üç şey öğrendik:

  • Dosya tanımlayıcı limitleri ilk darboğaz: işletim sistemi varsayılanları binlerce bağlantı için yetersiz, dağıtım imajında ulimit ayarı şart.
  • JSON marshalling CPU'nun beklenmedik müşterisi: sıcak yolda önceden ayrılmış buffer'lara geçmek CPU kullanımını üçte bir azalttı.
  • Kademeli yeniden bağlanma olmadan sunucu yeniden başlatması "bağlantı fırtınası" yaratıyor: jitter'lı exponential backoff ile çözüldü.

Sonuç: tek 4 vCPU'luk düğümde 12.400 eşzamanlı bağlantıda p99 gecikme 38ms. Üretimde iki düğümle, en yoğun akşam saatlerinde bile %40 yedek kapasiteyle çalışıyoruz.

Sonuç

Go'nun eşzamanlılık modeli, görüşme altyapısı gibi uzun ömürlü bağlantı yükleri için doğal bir eşleşme. Ancak asıl kazanım dilin kendisinden değil, izolasyon ilkesinden geldi: her seans kendi küçük dünyasında yaşar, çöker, kapanır. Benzer bir altyapı kuruyorsanız, önce bu izolasyonu tasarlayın — dili sonra seçin.

Benzer bir altyapı mı kuruyorsunuz? Deneyimimizi projenize taşıyalım — 1 iş gününde teklif.
Teklif Al
yazilim.tech © 2026 yazilim.tech — Fikirden ürüne. Bir diji.tech markasıdır.