MikroServisler arasında bir Gökdoğan — gRPC Nedir ?

Tarihler 22 Eylül 2019, sıcak bir Antalya sabahı, yeni ekip arkadaşlarımla tanışmak ve yeni işime başlamak için yola çıktım, oldukça heyecanlıydım, ekip arkadaşlarımla tanıştıktan sonra, her hafta perşembe günü ekip içerisinden veya farklı şirketlerde görev alan arkadaşları davet ettiklerini ve her hafta yeni bir konu üzerinde tartışıp fikir alışverişi yaptıklarını söylediler.

Evet şu anda görev aldığım MobiRoller App Maker şirketinde her hafta çılgın sunumlar oluyor ve uzmanlık alanları farklı insanlardan, yeni bilgiler öğrenmek, bu konular üzerinde farklı bakış açılarıyla tartışmak, kişisel gelişimim açısından oldukça verimli oluyor.

Sonunda beklenen gün gelmişti ve sunum sırası bendeydi, görev aldığım pozisyon BackEnd Developer olduğu için biraz daha görev tanımıma yakın bir konu seçmek istedim, .Net Core 3.0 versiyonu ile birlikte her geçen gün yeni bloklar keşfediyorum, okuyarak güncel kalmaya çalışıyorum, yine blokları tararken karşıma çıkan bu konuyu araştırıp ekip arkadaşlarımı bilgilendirmek istedim.

Hadi bakalım gRPC’yi bir de benden dinleyin… :)

Yazının başlığından başlayalım, ‘MikroServisler arasında bir Gökdoğan’.

Cümlede kulağa yabancı gelen iki kelime olabilir, MikroServis ve Gökdoğan :)

Öncelikle mikroservis kelimesinin altını dolduralım, teklonoji gün geçtikçe hızla gelişiyor, yeni araçlar keşfediliyor, open source kültürünün yazılım dünyasına kazandırdağı bakış açısıyla her gün yeni bir veya daha fazla kütüphane keşfedebiliyoruz.

Teklonoji bu kadar hızlı ilerlerken geliştiriciler olarak, her zaman en hızlı ve en kolay implemente edebileceğimiz araçlarla çalışmak isteriz.

Klasik uygulama mimarilerinde monolitik bir yapı vardır, uygulamanın tüm gereksinimleri tek bir solution içerisinde yer alır.

Peki uygulamanın tüm gereksinimlerini tek bir solution içerisinde belirli teklonojilerle çözmek ne kadar mantıklı ?

Yazılım projesine yeni fonksiyonellikler eklendikçe , kodlar büyür. Bir zaman sonra, projeye hakim olmak, eklentiler yapmak ve karşımıza çıkan sıkıntıları çözmek zor bir hal almaya başlar.

Resimde görüldüğü gibi mikroservis mimarisi ile uygulamanın temel gereksinimlerini küçük otonom servisler olarak geliştirip istediğimiz durumlarda haberleşmelerini sağlayabiliriz ve servislerin gereksinimleri doğrultusunda istediğimiz teklonojiyi kullanabiliriz.

Soru : Peki bu mikroservisleri nasıl haberleştireceğiz ?

Gökdoğan Nedir ?

“Bir anlatıcının bir konu üzerindeki bilgi hakimiyeti, o konuyu anlatırken kullandığı basit tabirler kadardır.” felsefesine inanarak gRPC konusunda topladığım bilgiler doğrultusunda ona Gökdoğan lakabını layık gördüm :)

Gökdoğan dünyanın en hızlı hayvanı olarak bilinmektedir, anlayacağınız, bu gRPC her neyse mikroservisler arasında oldukça hızlı gözüküyor.

Developer için Milisaniye Neden Önemlidir ?

Geliştiriciler her zaman bir işi geliştirmenin en kolay, en hızlı ve en güvenilir yolunu ararlar. Hayatları bu döngü içerisinde devam eden bu topluluk, çoğu zaman performans için milisaniye bazında iyileştirmeler yapar.

Web Service Nedir ?

Bir web servisi, bir uygulama tarafından çağrılabilecek bir servistir. Bu web servisleri, diğer uygulamalardan bağımsız ve farklı makinelerde çalıştırılabilen ayrı programlardır.

Gerçek hayattan bir örnek olarak, bir web servisini bir kahve makinesiyle karşılaştırabilirsiniz. Bu makinenin sadece bir işi var: kahve yapmak.

Bir kullanıcı bir kahve seçebilir ve nasıl yapıldığından endişe etmeden bir fincan kahve yapılır.

Bir web servisi temelde aynısını yapar. E-posta gönderen bir web servisimiz olabilir. Bir müşteri olarak şöyle diyebilirsiniz: “Bu içeriğe sahip bir e-posta göndermek istiyorum…”.

Web servisi daha sonra e-postaların gerçekte nasıl gönderileceğini ele alır, böylece müşterinin artık bunun için endişelenmesine gerek kalmaz.

Daha önce de belirtildiği gibi, bu web servisleri farklı makinelerde çalışabilir. Bu uygulamalar ile web servisi arasında ‘Service API’si’ olarak da bilinen bir tür iletişim olması gerektiği anlamına gelir.

Günlük hayattan örnekler…

100 soruluk bir sınav yapmış olalım. Sınav kağıdımızı teslim edelim ve soruların cevabını bekleyelim. Sınav kağıdımız tamamen okunana kadar, sorduğumuz soruların cevaplarını öğrenmek pek mümkün olmaz.

Servis çağrımlarında da böyle durumlar olabiliyor; standart bir request-response modelinde, 1000 tane veriyi işleme sokulsun diye bir servise gönderdiğimizde, 1000 tane verinin de tamamen işlenmesi sonrasında sonuçları alabiliyoruz. Servise gönderdiğimizde sonuç olarak, direkt işlenen verileri sırayla gönderse iyi olmaz mıydı… (ipucu : gRPC, data stream)

RPC Nedir ?

RPC; Server ve client arasındaki iletişim için dizayn edilmiştir. Kullandığınız herhangi bir program sunucu istemci iletişimine ihtiyaç duyuyor ise, prosedürü sağlayan bilgisayar programına izin veren süreçler arası iletişim teknolojisidir.

Kısaca bir sunucunun bir client’da kod çalıştırmasına yarayan protokoldür.

gRPC Nedir ?

Protobuf serialization altyapısını kullanan gRPC, programlar arası iletişimi sağlayan bir RPC(Remote Procedure Call) yöntemidir.

Nerelerde Kullanılır ?

  • Bu yöntem, uygulamalar arası iletişim
  • Uzak metod çağrımı(RPC)
  • Web Servis gibi haberleşme yapılarının temeli olacak şekilde kullanılabilir.

Peki gRPC yokken mikroservisler arasındaki veri iletişimi nasıl sağlanıyordu ?

gRPC vs Rest

gRPC isteklerinde Encoding ve Decoding kısmı istemci makinede gerçekleşir.

Bu yüzden makinenizde REST için yaptığınız JSON encode/decode burada sizin için bir yük değildir. SOAP tabanlı API’larda olduğu gibi farklı diller arası tip dönüşümleri için serileştirme(serialization/deserialization) yapmanıza gerek kalmaz çünkü protokol üzerinde veri tipiniz bellidir ve hedef dilinize ait kod oradan üretilir.

Milisaniyenin Gücü

Testler, gRPC’nin genellikle REST’ten sadece birkaç milisaniye daha hızlı olduğunu göstermektedir. Biri şöyle düşünebilir: “Bu neden önemlidir? Milisaniye çok küçük bir birim, farkına bile varmam… ”

Aslında, bir milisaniye çok küçük bir birimdir. Bir kullanıcı, araması 1 ms daha uzun sürdüğünde doğrudan fark etmeyecektir. Ancak bu 1ms bir şirket için sorun olabilir.

Bir sunucu tüm kaynakları aynı anda işleyemez, çünkü kaynakları sınırlıdır. Örneğin bir sunucu aynı anda yalnızca 10 istek gerçekleştirebilir. Bu, aynı anda yalnızca 10 telefon görüşmesine cevap verebilecek bir şirketle karşılaştırılabilir, çünkü sınırlı sayıda telefon veya çalışan bulundurur. Bir sunucu 1000 istek alırsa ve aynı anda yalnızca 10'u idare ederse, son isteğin ele alınmadan önce bir süre beklemesi gerekir. Bu son istek siz olabilir, web sayfasının yüklenmesini bekliyor olabilirsiniz.

Aynı anda yalnızca 10 isteği işleyebilen bir sunucuya 10.000 çağrı yapan bir kıyaslama testi yaptım. Her gRPC çağrısının 1ms, bir REST çağrısının 2ms aldığını varsayıyoruz. gRPC 1 saniye içinde bitecek ve REST 2 saniye içinde bitecektir, bu 1 saniyelik bir farktır. Peki ya web servisim cevap vermeden önce aynı sınırlı kaynaklarla başka bir web servisini arayacaksa? Bu başka bir saniye daha ekleyebilir. Bu, web servislerine daha büyük veriler gönderildiğinde gerçekten toplanmaya başlar, bu da süre farkını daha da büyük yapar.

Bir web sayfası her zaman çağrılan birçok farklı web servisini kullanabilir. Tüm bu web servislerinin farklı kaynakları olabilir. Bir web sayfası daha fazla ziyaretçi aldığında, artık bir milisaniye meselesi değil. Örneğin bir web sayfasının yükleme süresi artabilir, bu da kullanıcı deneyimini azaltacaktır. Bazı şirketler bu sorunu başka bir sunucu satın alarak düzeltir. Ancak bu, verilerin web servisinden web servisine nasıl gönderildiğine bakarak da düzeltilebilir.

Ancak, hangi tekniğin kullanıldığı dışında, tüm bunlarda en dikkat çekici şey, bunun gerçekleştiği hızdır. Bu testler sırasında tüm senaryolar, istemci makineden sunucuya 25 milisaniyeden daha kısa sürede gönderilir ve cevaplanır. Verileri sunucudan istemciye bu kadar kısa sürede göndermek için binlerce satır kod okunur ve işlenir.

Senaryoları 25 Milisaniyeden kısa sürede göndermek hızlı . Ancak geliştiriciler hala bu süreyi azaltmaya çalışıyorlar çünkü milisaniyenin gücünün farkındalar.

Her gülün dikeni vardır :)

gRPC avantajlarından bahsettik, araştırmalarım sonucunda gördüğüm dezavantajlarada yazımda yer vermek istedim.

  • IIS
  • Azure App Service

buralarda gRPC servislerinizi barındıramazsanız.

Temel olarak Azure App Service, uygulamaları barındırmak için IIS kullanır. gRPC, HTTP / 2 protokolünü kullanır. Http.Sys, IIS çekirdeğinin bir parçasıdır ve bu yazı itibariyle gRPC iletişimi için gereken altyapıyı desteklemez.

Peki, bir gRPC servisine ev sahipliği yapma seçenekleri nelerdir?

En kolay yol, ASP.NET Core’un yerleşik web sunucusu Kestrel’de bir gRPC servisine ev sahipliği yapmaktır. Aslında, Visual Studio’da yeni bir gRPC projesi oluşturduğunuzda, uygulamayı çalıştırmak için Kestrel’i kullanır.

Sonuç

Servisler arasında binary stream özelliği ve istemci makinede kod çalıştırma ilkelerine dayanarak; Mikro servis dünyasında, gRPC çok yakında baskın hale gelecektir. Performansın faydaları ve gelişim kolaylığı, elde edilemeyecek kadar iyi. Ancak, REST uzun süre buralarda olacak. Hala public API’ler ve uyumluluk nedenleri için mükemmel bir çözümdür.

Son olarak .Net Core ile bir gRPC örneği yapıp bu teorik bilgileri uygulamaya dökmek isterim.

Öncelikle gRPC service projesi oluşturalım, varsayılan olarak proje içerisinde bulunan greet.proto dosyasını kullanacağım, mikroservisler haberleşirken .proto uzantılı dosyaları kullanacaklardır ve hem server hem de client tarafında aynı dosya olmalıdır.

greet.proto

bu dosyadan çıkarılması gereken sonuç ; Greeter isimli bir servisimiz var ve bu servisin içerisinde SayHello isimli metot, HelloRequest tipinde bir nesne alırken return olarak HelloReply isimli bir nesne dönderecektir.

HelloRequest ve HelloReply isimli nesnelerin tanımlamalarını .proto dosyasında yapmamız gerekir. Nesnelerin property’lerini tanımlarken verdiğimiz uniq sayılar önemlidir. Binary stream ile veri alışverişini gerçekleştiren bu servisler için nesnenin kaçıncı sırada olduğu bu nesnenin ne zaman aktarılacağını belirtir.

GreeterService.cs

proto dosyasındaki tanımlarımızı yaptıktan sonra servis olarak belirtmemiz gerekmektedir. Şimdi .proto dosyasını kopyalayalım ve console application oluşturarak projenin içerisine dahil edelim.

Solution Explorer

Not : .proto dosyasını taşıdıktan sonra .csproj içerisinde proto dosyasının türünü client olarak değiştirmeyi unutmayın.

Console application içerisindeki Program.cs dosyasını aşağıdaki gibi değiştirebilirsiniz.

Program.cs

gRPC default olarak 5001 portundan haberleşecektir.

5001 portuna bağlanan bir channel oluşturup bu channel üzerinden greeterService içerisinde bulunan SayHello isimli metodu çalıştırıyoruz.

İşte sonuç;

Not: Client ve server uygulamaları aynı solution içerisinde olduğu için uygulamanızı çalıştırmadan önce ayarlarınızı multiple startup project olarak güncelleyin.

gRPC ile araştırmalarım ve uygulamalarım devam ediyor, yeni bilgiler öğrendikçe sizlerle paylaşacağım.

Umarım faydalı olur.

Solution Developer — I want to change the world, give me the source code.

Solution Developer — I want to change the world, give me the source code.