YAZILIM MİMARLIĞINDA İLKELER VE TEKNİKLER

Çift Yönlü İletişim Gerektiren Sistemlerde Durumsuzluk Tasarımı

Durumsuz Mimariler — 3. Bölümde en çetrefilli ölçeklenebilirlik/ulaşılabilirlik problemlerinden birisinin çözümünü keşfedin!

Ersin Er
Bilgisayımcı

--

Fotoğrafçı: Sophie Dale / Unsplash

Durumsuz Mimariler yazı dizisinin önceki bölümlerinde konuya etraflı bir giriş yapmış ve çeşitli soyutlamalarla meseleye genel olarak nasıl yaklaşabileceğimiz ile ilgili bir bakış açısı kazanmaya çalışmıştık. Bu bölümde ise öğrendiğimiz bilgiler ışığında ölçeklenebilirliği ve ulaşılabilirliği en çok zorlayan gereksinimlerden birisine değineceğiz: çift yönlü iletişim (ing. two-way/duplex communication).

Bu dizinin tüm yazılarına aşağıdaki listeden ulaşabilirsiniz.1. Durumsuz Mimarilere Giriş
Durumsuz Mimariler — 1. Bölümde Ölçeklenebilirlik ve Ulaşılabilirlik için Durum (ing. State) ile başa çıkmayı öğrenin!
2. Durumsuz Mimariler Tasarlamak için bir Genelleme ve Modelleme Yaklaşımı
Durumsuz Mimariler — 2. Bölümde Durum (ing. State) ve ilişkili diğer kavramlara daha soyut ve geniş bir açıdan bakın!
3. Çift Yönlü İletişim Gerektiren Sistemlerde Durumsuzluk Tasarımı
Durumsuz Mimariler — 3. Bölümde en çetrefilli ölçeklenebilirlik/ulaşılabilirlik problemlerinden birisinin çözümünü keşfedin!
Not: "Yazma Üslubum ve Okuyucuya Beklenen-Olası Yansımaları Hakkında" bilgilere dizinin ilk yazısının giriş kısmından ulaşabilirsiniz.

Web Mimarisinde İletişim Modellerine Kısa bir Giriş

İstemci-sunucu (ing. client-server) mimarilerinde en çok ihtiyaç duyulan iletişim türlerinden birisi sunucunun da istemciye istediği anda ulaşıp ileti (ing. message) gönderebildiği çift yönlü iletişim kanallarıdır (ing. duplex communication channels). Bu iletişim modelinde istemci, sunucunun erişim bilgilerini bilir; tam tersi ise normal şartlarda söz konusu değildir. Bağlantıyı sunucuya doğru istemci açar. Durumsuz klasik HTTP iletişimindeki — evet, HTTP bir protokol olarak durumsuzduristek-yanıt modelinden farklı olarak kalıcı (ing. persistent) bağlantı üzerinden her iki taraf da ihtiyaç duyduğunda birbirine ileti gönderebilir. Tam çift yönlü (ing. full-duplex) iletişimde (ör. telefon) her iki taraf da eşanlı (ing. simultaneously) olarak karşılıklı konuşabilirken yarı çift yönlü (ing. half-duplex) iletişimde (ör. “bas-konuş”) belirli bir anda sadece tek bir taraf karşıya ileti gönderebilir. Güncel web tekniklerinden böyle bir bağlantı türüne en bariz örnek WebSocket’tir. (Tek yönlü [ing. simplex] iletişime yine günlük hayattan bir örnek verebilir misiniz?)

Ölçeklenebilirliği ve Ulaşılabilirliği Baltalayan bir Durum olarak Kalıcı Bağlantı

Durumu, bir sistemde bir bilgiişlem birimine bağımlılık oluşturarak varlığını zorunlu kılan ve dolayısıyla ölçeklenebilirlik ve ulaşılabilirlikle bağdaşmayan bir olgu olarak tanımlamıştık. Kullanıcı verisi, zamanlandırılmış işlerin kaydı ya da sabit IP adresi gibi farklı durum bilgilerinin ötesinde belki de en çarpıcı durum örneği kalıcı bağlantıların kendileridir. Bu tür bağlantıların yaşam süresi bir istek-yanıt çiftinin aktarımı ile sınırlı değildir.

Kalıcı bağlantı, belirli bir istemciyi belirli bir bilgiişlem birimine mahkum eder.

Sunucunun da istemci ile istediği zaman iletişim kurabilmesi için bağlantının sürekli açık kalması zorunludur. Diğer türlü, bir sunucu bir istemcinin adresini bilip de ona bağlantı açabilir miydi? Hayır elbette — istemci-sunucu mimarisi böyle çalışmaz. (Mikroservis mimarilerinde ise iletişim özellikleri açısından genelde özdeş olan servisler, aracılı ya da aracısız birbirlerine adresleri üzerinden erişebilirler.)

Geçici ve Kalıcı Bağlantıların Aynı Serviste Karşılandığı Örnek Mimari

Böyle bir bağlantı doğal olarak bir oturum teşkil eder. (Oldukça önemli bir teknik: Böyle tür bir iletişim modelinde her bir istek yerine sadece bağlantıyı bir kere kimlik doğrulama ve yetkilendirmeye tâbi tutarız!) Ağ iletişimi kütüphaneleri (ing. library) ve çerçeveleri (ing. framework) bu oturumlar bağlamında veri saklamak için olanaklar sağlar ve bunlar sıkça geliştiricilerce kullanılır. Bağlantı kapanmadığı sürece istemci-sunucu arasında oturum açık kalır. Bağlantı bizzat bu oturumun garantörüdür. Bu oturumlar genelde durumlu servis yazılımları tarafından yönetilir ve kullanılır. Sunucu tarafındaki sistemler kendi taraflarından bir iletiyi istemciye gönderebilmek adına genelde durumlu bir kurguya sahiptir. En azından servis uygulaması veri modeli ile bağlantı kanalı kimliği arasında bir eşleştirme (ing. mapping) bilgisi kaçınılmaz olarak tutulur — “A kullanıcısı şu an B kanalından bağlı” gibi.

Öyle olmak zorunda olmamasına rağmen durumun geliştiricilerce en az sakınılan “konağı”, kalıcı bağlantının anlamlı görüldüğü, gerçek zamanlı (ing. real-time) ve zamanuyumsuz (ing. asynchronous) olarak sunucunun istemci ile iletişim kurma ihtiyacının olduğu sistemlerdir.

Kalıcı bağlantı, kendisi dışındaki durum bilgisine de çanak tutar.

Bir oyun sunucusunu örnek olarak ele alalım. Her şeyden önce böyle sistemler istemci ve oturumu başına çok miktarda verinin bellekte tutulması konusunda ciddi bir eğilim gösterilen sistemlerdir. (Ben de birçoğunu bu şekilde geliştirdim.) Çünkü veriye hızlı erişim ve ilişkisel veri tabanlarının yetenekleri (ya da sağlayabilecekleri performans) ötesinde veri işleme ve ilişkilendirme elzemdir. Bunca veri genelde istemcileri çift yönlü bağlantının da ötesinde belirli bir sunucuyla iletişimde olmaya zorunlu kılar. Oyuncunun verisi — en azından oturumu etkinken — hep aynı sunucudadır. Çift yönlü iletişim sayesinde de oyunda olan olayların bilgileri oyuncunun istemcisine anında bildirilir. Oyun gibi bir alan bir kenara, benzer çözümlerin tercih edilebileceği sosyal medya uygulamaları (ör. Twitter) ya da finans uygulamaları (ör. X bankası mobil uygulaması) gibi sistemlerin sunucudan istemciye istenildiğinde veri aktarılabilsin diye aynı durumluluk batağına batmaktan kaçınmaları gerekir.

Bağlantının ve bellekteki durum bilgisinin istemciye özel olarak tutulduğu böyle bir sunucu sistem çöktüğünde ya da planlı olarak donanıma ya da servis yazılımı yeniden başlatıldığında, bağlantı koptuğu gibi, ilgili istemci için de servis artık ulaşılamaz olur.

Mimarî Çözüm Seçenekleri

Bu çift yönlü bağlantının nasıl bir dert oluşturduğunu anladık umarım. Bu konunun gerçekten de böyle sistemleri geliştirmiş ve bu sorunu deneyimlemiş farkındalığı yüksek geliştiricilerce çok çetrefilli sorun olarak bilindiğini söyleyebilirim. Şimdi gelelim olası çözümlere…

En basit çözüm: Çift yönlü bağlantı kullanma! Durumdan da kaçın.

Sunucudan istemciye bir ileti aktarılmak istendiğinde elimizde bir temel araç var: istemciden sunucuya istek iletmek için açılan bağlantı üzerinden verilecek yanıt. Bu yanıt bir bakış açısı ile istemciye aktarılmak istenen herhangi bir bilgi olabilir. İstemci, bağlantıyı kurup bir istek ya da genel olarak bir ileti gönderdiğinde sunucu “tetiklenip” istemci ile ilgili göndereceklerini bir yanıtmışçasına paketleyip aktarabilir. Bu yaklaşımın zamanlama açısından sunucuya yeterli gelmediği hâllerde genellikle periyodik sorgulama (ing. polling) ile sonuçlanan bir iletişim biçimi ortaya çıkar. (“Hey sunucu! Bana söyleyeceğin bir şey var mı? Bana söyleyeceğin bir şey var mı? Var mı?…” gibisinden bir iletişim.) Tabii ki bu da çok tercih edilen bir yöntem değildir. Çünkü belki sunucunun istemciye 1 saat içinde sadece 1 kereliğine ileti aktarma ihtiyacına karşın istemcinin dakikada 1 sorgulamalarına maruz kalabilir. Bu da ciddi bir kaynak israfı olabilir yerine göre. Örnekteki bir dakikalık periyot yeterli gelmeyebilir de. Bu sefer yarım dakika, 15 saniye, 5 saniye diye gider bu değer…

Ara çözüm: Kalıcı bağlantı kalsın ama oturum hariç başka hiçbir durum bilgisine izin yok!

Kalıcı bağlantı, çeşitli senaryolarda kaçınılmaz olabilir ve yazılımınızı bu iletişim biçimini desteklemek üzere gerçekleştirebilirsiniz. Ancak bu kadarla yetinmelisiniz. Oturum bilgisi dahil tüm durum bilgilerini bilgiişlem birimi dışına çıkarmalısınız. Bu durumda tek derdiniz bağlantının kendisi olarak kalır. Böylece çift yönlü bağlantının daha fazla durumu bilgiişlem birimi içine, bir cadının kötü ruhları çağırdığı gibi, çağırmasını engellemiş olursunuz.

Böyle sistemlerde sunucunun belirli bir istemciye bir ileti göndermesini tetikleyen şey eğer ilgili istemcinin kendisinin sunucuya bir istekte bulunmuş olması değilse, daha önce bir bilgiişlem birimi dışına taşınmış tüm ilgililer olabilir: zamanlanmış işler, bir veri tabanı ya da önbellekleme sisteminden gelecek güncelleme bilgisi ve — belki daha önce bahsetmediğimiz — bir başka istemcinin isteği (bir sohbet servisini düşünün). Bu tarz bir sistemde bağlantı kanalının kimliği doğrudan ya da dolaylı olarak dışarıya çıkarılmış durum bilgileri ile birlikte ilgili sistemlerde tutulur ki herhangi bir durum geçişinde ilgili istemci haberdar edilebilsin (onun da durumu güncellensin).

Esas çözüm: Duranı dışarıda bırak!

Esas çözüm iddialı ama artık bizim için ilginç değil. Madem bu tür bağlantılar bize ayak bağı oluyor, demek ki onları da dışarı çıkaracağız! Bu arada istemcimizin de bağlantısının başına olur olmaz şeylerin gelmesine izin vermeyeceğiz.

Bu şekilde dışarıda bırakarak sorunları tamamen çözüyor muyuz? Hayır, ama sorunu parçalıyoruz ve her bir sistemin kendi iyi bildiği işi yapmasını sağlıyoruz. İş mantığını barındıran servisimizin aslî görevi bağlantıları güvenilir bir şekilde yönetmek olmasa gerek!..

Şimdi buradan konuyu biraz genişletelim…

İletişim Yönetimini İş Mantığından Ayırma Yaklaşımı

Bu yaklaşım altında da farklı seçeneklerimiz mevcut. Bu seçenekler günümüzdeki teknolojilere göre değişiyor ama teknolojinin ötesinde tekniğe odaklanmak ve daha genel çıkarımlar yapmak gerekir. Yeri geldikçe bu çıkarımlar doğrultusunda yorumlarımızı yapacağız.

İletişim Yönetimini Ayrı Bir Servise Devretme

Malum ilkemizi uygularsak varacağımız mimaride istemci iletişimini farklı adanmış bir servisle yönetiyor oluruz. Böyle bir sistemde istemciler kalıcı bağlantılarla çift yönlü iletişimden sorumlu sunuculara bağlanır. İletişim sunucuları (ing. communication server) ise bir servis iletişim arakatmanı (ing. service comminication middleware) aracılığıyla iş mantığı bilgiişlem birimleri ile konuşurlar.

Bilgiişlem birimlerimizin durumsuz olduklarını varsayarsak bir istemcinin kalıcı bağlantı üzerinden gelen bir istekleri her ne kadar iletişim yönetimin servisinde belirli bir iletişim sunucusu üzerinden geçmek zorunda olsa da iş mantığı servisine aktarılırken servis iletişim katmanında yük dengelemeye tâbi tutulabilir. İş mantığı servisinden bir yanıt ya da bir güncelleme istemciye aktarılmak istenirse de iletinin doğru iletişim sunucusuna aktarılması gerekir. Bu hizalama (ing. alignment) esas olarak servis iletişimi arakatmanı tarafından sağlanır.

İletişim Yönetiminin İş Mantığından Ayrı Ele Alındığı Örnek Mimari

Bu mimaride bazı istekler yine geçici bağlantı üzerinden aktarılıp istek-yanıt modeli ile ele alınabilir. Bazı istekler ise kalıcı bağlantı üzerinden aktarılıp yanıtları zamanuyumsuz olarak herhangi bir anda alınabilir. Asıl avantaj ise tamamen sunucu tarafından tetiklenen güncellemelerin istenildiği zaman istemciye aktarılabilmesidir elbette.

Bu yazının başında problem olarak ortaya konan sistem mimarisinde de istemciler hem geçici hem de kalıcı bağlantı kullanıyorlardı. Buradaki çözümde yine iki tür bağlantı kullanılıyor ama farklı servislerce karşılanıyorlar. Elimizde kalıcı bağlantı varken neden geçici bağlantıya ihtiyaç duyarız ki? İş mantığı servisini istemcilerle karşılaşmaktan tamamen azat etsek ya?

TAM-ÇİFT Yönlü İletişim Sağlayan Kalıcı Bağlantıyı Sadece TEK Yönlü İletişim İçin Kullanma

Kalıcı bağlantıları iş mantığı servisimizin sorumluluğu dışına taşımış olsak da iletişim yönetim servisi için hâlâ bir sorunlar. Veri tabanı sistemleri gibi iletişim yönetimi için çok fazla hazır sistem yoktur; o yüzden bu yapının kurulmasında iş biraz size kalacak. Dolayısıyla kurguladığımız mimari üzerinde ek inisiyatifler alarak işimizi kolaylaştıracak ya da kaliteyi arttıracak adımlar atmak için imkanımız — ve aslında gereksinimimiz de — var.

İletişim sunucuları bağlantıları sürekli açık tuttukları için bu bağlantılardan gidip gelen iletileri yük dengelemeye tâbi tutmak mümkün değildir. Yük dengeleme ancak ilk anda bir istemci bir sunucu ile ilişkilendirmek için kullanılır ve bunun sonucunda oluşan bağlantı (ya da daha doğrusu bağlantı zinciri) kapatılana/kopana kadar aynı şekilde kalır.

Yük dengelemeyi ve aslında ölçeklenebilirliği ve ulaşılabilirliği yeterince iyi sağlayamadığımız bir yerden neden daha fazla trafik geçirelim?

İhtiyacımız olan şey gerçekten de çift yönlü iletişim mi? Bağlantımız bunu desteklese bile hattı bu şekilde mi kullanmalıyız?

Sadece servis tarafındaki güncellemeleri (ing. updates) sunucudan istemciye aktaran bir akışımız olsa hem çok verimli olmayan bir hattı sadece gerektiği kadar kullanmış oluruz, hem de geriye kalan trafiği ölçeklenebilirlik konusunda birçok teknolojinin halihazırda elverişli olduğu alışıldık istek-yanıt modeline kaydırmış oluruz.

İletişim Yönetiminin Tek Yönlü Bilgi Aktarımı ile Daha Ölçeklenebilir Olarak Ele Alındığı Örnek Mimari

Diğer taraftan, isteklerin kalıcı bir bağlantı üzerinden aktarılmadığı bir model ulaşılabilirlik açısından çok daha etkilidir. Neden?

İletişim yönetimi sunucularından birisi devre dışı kalsa zararımız ne olur? İlgili istemci güncellemeleri almaktan mahrum olurlar ama diğer geçici kanaldan servisle hâlen iletişim halindedirler. Kalıcı kanalı yeniden kurmak için tekrar bir bağlantı açar ve uygun olan bir başka sunucuya bağlanır. Bu servis ile ilgili tek derdi güncellemeleri almak olduğundan, en son aldığı güncellemenin kimliğini servise bağlantı sırasında aktarır ve servis de kaldığı yerden bu istemciye güncellemeleri göndermeye devam edebilir.

Farkettiniz mi? Son paragrafta çok şey söyledik! Koca bir tasarımı ve çeşitli varsayımları birkaç cümle ile geçiştirdik. Biraz daha açalım.

İletişim servisine ve iş mantığı servisi ile arayı yapan arakatman servisine biraz daha görev yükleyerek bu sistemin daha güvenilir çalışması sağlanabilir. Her istemci için bir güncelleme kuyruğu tutulduğunu varsayın. Bu kuyruğu iş mantığı servisi besler. Arakatman aracılığıyla ise iletişim yönetim servisi tüketir ve her bir güncellemeyi ilişkini kanaldan istemciye gönderir. Bu “ilişkili kanal” da yine arakatman ve iletişim yöneticisi arasında ele alınması gereken bir eşleştirme problemidir. Şimdi ayrıntısına girmeyeceğim kuyruk yapısı gereksinimi ve güncelleme-kanal eşleştirme problemi yine kendi işinde özelleşmiş bir önbellekleme sistemi üzerinden karşılanabilir ve çözülebilir. Bu iş için örneğin Redis biçilmiş kaftan olur.

Tüm bu karmaşıklığı ölçeklenebilir ve en az oynar parça ile çözmüş en iyi ürünlerden birisi WebSocket Desteği ile AWS API Gateway Servisi. Daha çok mobil uygulama geliştiricilere dönük gerçek-zamanlı iletişim hizmeti veren daha birçok servis var, örneğin Ably.

Diğer taraftan, bulut sağlayıcıları tarafından sunulan IoT servisleri ve özelde iyi bir örnek olarak Device Gateway özelliği ile AWS IoT Servisi de karşılık geldikleri problem alanının doğası gereği benzer bir mimariyi hazır sunarlar.

Güncellemeler: Verinin Yeni Hâli mi yoksa sadece Değişen Parçalar mı yoksa sadece Değişiklik Oldu Bilgisi mi?

İletişim Yönetimi Servisi üzerindeki yükü azaltmaya devam ediyoruz. Kalıcı bağlantı üzerinden eğer takip edilen güncellemelere ilişkin verinin yeni hali bütün olarak alınıyorsa istemci sadece bir güncellemeden haberdar olmuş olmakla kalmaz, aynı zamanda güncellemeye konu olan veriyi de almış olur. Verinin tamamı alınmak yerine sadece değişen parçaları da alınabilir. Örneğin böyle bir hat üzerinden, kullanıcının takip ettiği bir hisse senedi portföyüne ilişkin güncellemeler geliyor olsun. Senetlerden birisinin değeri değiştiği zaman tüm portföyle ilgili bilgilerin son hali de aktarılabilir ya da sadece değişen senedinki de aktarılabilir. İkincisi daha durumlu bir yaklaşımdır ve anlaşılacağı üzere daha az trafik tüketir. (Ödünleşimler…)

Burada bir önemli seçeneğimiz daha var. O da sadece ilgili portföyde ya da senette bir değişiklik oldu bilgisini (güncel tam veriyi ya da oluşan fark verisini içermeden) istemciye aktarmak ve istemcinin güncel veriyi geçici bağlantı ile almasını sağlamaktır!

Yine çok kritik bir şey söyledik. İrdeleyelim. İş mantığı servisinde RESTful bir model oturtmuş olabilirsiniz. Ayrıca, yük dengeleme gibi hizmetlerden de güzelce faydalanıyorsunuz. Buradaki modeli ya altyapıyı sonuna kadar kullanmak varken neden kalıcı bağlantı tarafını aşırı yükleyelim? Burada bahsettiğimiz iyileştirme de bu yönde atılmış bir adım. Sistemimizde bir servis belli işleri, belli bir model ve altyapı ile yapmak için eniyilenmiş durumda zaten. Bu olanağı sonuna kadar kullanmak gerekir. Kalıcı bağlantıların yönetildiği kısıma ise mümkün olan en az sorumluluk yüklenerek zaten zor olan işini yapabilmesi için alan açılır.

Bu yapı ile iletişim modelimizi tutarlı bir hale de getirmiş oluruz.

Peki bu model her durumda çalışır mı? Hayır, bu modelin yersiz olacağı senaryolar azımsanmayacak sayıda. Eğer ilk baştaki tartışmalarda bahsettiğimiz türden bir oyun sunucusu ya da bir sohbet uygulaması geliştiriyorsanız bu şekilde kulağınızı öbür taraftan göstermenin bir âlemi yoktur. Çünkü bu uygulamaların gerçek zamanlı ve yoğun veri iletişimi ihtiyaçlarından dolayı böyle bir gitgele tahammülleri olmaz.

İletişim yönetimini ve iş mantığını birbirinden ayırmakla aslında bilgisayar biliminin temel ilkelerinden birisini uygulamaktan farklı bir şey yapmadık: “İlgilerin Ayrılması” (ing. “Separation of Concerns”). “Duranı dışarıda bırak!”a ne kadar da benziyor değil mi? Evet, aslında onu da kapsayan bir ana ilke İlgilerin Ayrılması. (Bu konuda daha geniş yazacağım bir ara.)

Burada anlatılanları uygulamada görmek için Slack’in iletişim modelini inceleyebiliriz. Slack’te sohbetlerdeki metin iletileri bir WebSocket kanalından doğrudan aktarılırken, yüklenen ikili dosyalara (ing. binary files) ilişkin indirme adresi vb. üstveri (ing. metadata) WebSocket üzerinden aktarıldıktan sonra geçici bir HTTP bağlantısı ile yüklendiği Slack sunucularından istemci tarafından çekilir. Dosya aktarımı gibi ölçeklenme ihtiyacı yüksek olan bir işin bu şekilde ele alınmış olması ne kadar da doğru bir seçim olmuştur!

Çift yönlü iletişimle işimiz yoksa tekniğimizi gözden geçirip tam amaca dönük bir sisteme doğru ilerleyelim!

Özellikle modern web mimarisi söz konusu olduğunda kullanabileceğimiz teknikler çeşitleniyor. Yukarıda sözünü ettiğimiz yaklaşımı gerçekleştireceğimiz yaygın teknoloji WebSocket’tir. Ancak WebSocket bağlantıları — giderek daha iyi desteklenseler de — genel web altyapısına uygunluk anlamında birçok sorun yaratırlar. Herhangi bir kalıcı bağlantı gibi ölçeklenme sorunu yaşadığını zaten söylemiştik. Bunun ötesinde WebSocket HTTP/2 biraz üvey evlat muamelesi gördü. Sonradan toparlanmaya çalışılsa da tam verim alınabildiği ve yeterince yaygınlaştığı söylenemez.

WebSocket’in, dediğimiz gibi, yüksek başarım (ing. performance) gerektiren oyun türü sistemlerin geliştirilmesinde kullanılması kaçınılmaz olabilir. Ama belli senaryolar için daha iyi bir alternatifimiz var: Sunucu İtmesi (ing. Server Push) tekniği ya da web mimarisindeki modern karşılığı ile Sunucudan Gönderilen Olaylar (ing. Server-Sent Events [SSE]). SSE, daha önceki Comet şemsiyesi altında sayılabilecek tekniklerin en modern olanı ve HTTP’nin standart “açık-tut” (ing. keep-alive) özelliğini kullanıyor. Açılan standart bir kalıcı HTTP bağlantısı ile servisten yapılan güncelleme bildirimleri istemci tarafından alınabiliyor. Ayrıca SSE iletişiminde istemci bağlantı açarken kaldığı yeri belirtmek için son olay kimliği (ing. last event id) gibi bilgilere de yer verebiliyor. Bu da yukarıda önerdiğimiz mimari için hazır altyapı demek. Bunun bir diğer alternatifi de istemci ilk açıldığında ya da kalıcı bağlantı koptuğunda geçici bağlantı üzerinden tüm veriyi tazeleyerek çekmektir. (Evet, bu da önemli bir teknik ve irdelenmesini size bırakıyorum.)

Dikkat edin: SSE tek yönlü bir iletişim modeline izin verir. Kurulması aşamasında elbette HTTP sunucuya bir istekte bulunulur ve burada çeşitli bilgiler, parametreler de aktarılabilir, fakat sonrasında kontrol tamamen sunucudadır. Sağlayabildikleri itibariyle WebSocket’ten önemli ölçüde ayrılır: Tek yönlü olmasının yanında, sadece metin (ing. text) tabanlı aktarıma izin vermesi, HTTP yanıtına ilişkin üstveri (ing. metadata) olan başlıkları (ing. header) her seferinde yanıtla göndermek zorunda olması gibi.

SSE, HTTP/2 ile birlikte daha da iyi gidiyor. Buna rağmen artılarını-eksilerini gözden kaçırmamak lazım. Olası sorunları ele alacak hazır çözümler de yok değil.

Dipsiz Kuyudan Çıkış

Özellike web mimarisine ve internet altyapısına yönelik düşündüğümüzde biraz dipsiz bir kuyuya düşmüş gibi oluruz. Bu yazıda konuya durumdan giriş yapmış olsak da yazılım ve web mimarisinin dehlizlerinde gezinmiş olduk. Daha önce de belirttiğim gibi durumu ele almanın ötesinde ilgilerin ayrılması ilkesinin peşinden koştuk.

Son bir analoji ile bu yazıyı da sonlandırayım:

Mobil uygulamaları zamanuyumsuz (ing. asynchronously) — diğer bir deyişle, bir istek olmadan — beslemek için kullanılan itme bildirimleri (ing. push notifications) ya da yaygın bilinen ismiyle anlık bildirimler de aynı mimarî ilkelerin yaygın kullanıma sunulmuş hâlinden başka bir şey değildir.

Her şeye rağmen kalıcı bağlantılar yerine yoklama (ing. polling) yöntemi de yerine göre çok elverişli olabilir, unutmayın! (Bkz. bilumum Google Servisleri.)

Uzunca bir yazının daha sonuna geldik. Sabırla okuduğunuz için teşekkür ederim. Yararlanmış olmanızı umuyorum. Başka yazılarda görüşünceye değin hoşçakalın!

--

--

Ersin Er
Bilgisayımcı

Teknoloji Stratejisi, Mühendislik Yönetimi, Liderlik, Yazılım-Sistem & Ürün Mimarisi, Organizasyon Tasarımı, Akış & Ölçeklenme, Sistemlerle & Karmaşıkla Düşünme