gRPC Nedir ve Nasıl Uygulanır? — Microservice Mimarisi ile gRPC

Gökhan Ayrancıoğlu
Delivery Hero Tech Hub
6 min readMar 10, 2021

gRPC; Google’ın geliştirdiği Remote Procedure Call, yani başka bir servis ya da uzak sunucudaki bir metodu sanki kendi servisimizin metoduymuş gibi kullanabilmemizi sağlayan, client-server ilişkisindeki iletişimi kolay ve hızlıca sunan bir frameworktür.

RPC aslında eskiden beri varolan bir yöntemdir. Yani yeni bir konsept değildir ancak HTTP 2.0 ile birlikte Google iş birliği çerçevesinde oldukça kullanılabilir ve servisler arası iletişimde fayda sağlar hale gelmiştir. RPC: Client’ın direkt olarak servisteki bir fonksiyonu/metodu çalıştırması olarak genellenebilir. gRPC açık kaynak ve ücretsiz olarak Google’ın geliştirdiğin bir frameworktür ve Cloud Native Computing Foundation (CNCF) ekosisteminin bir parçasıdır.

High level olarak baktığımızda metotlar ve yöntemler gRPC için tanımlanır ve geri kalan her şeyi framework halleder.

Protocol Buffer (ProtoBuf) Nedir?

gRPC için kullanılan verinin binary olarak serialization yapan haberleşme protokolüdür. Servislerin metotlarını ve mesajları tanımlayıp, gRPC senin için kodları generate eder ve kolayca kullanımına sunar, bizim için geriye sadece implementasyonları gerçekleştirmek kalır.

Protocol Buffer ile gRPC

  • Dil bağımsızdır.
  • Herhangi bir dile kolayca entegre olabilir
  • Veriler binary şeklinde ve serialized konumdadır. HTTP 1.1'de ise açık metin olarak gönderilmektedir.
  • Aynı servis bağlantısı üzerinden birden çok paralel istek gönderebilmek için çoğullama (Multiplexing) desteği mevcuttur. HTTP 1.1’de bir seferde bir istek / yanıt sınırlaması mevcuttur.
  • Bidirectional full-duplex yani aynı anda client isteklerini ve server yanıtlarını gönderip alabilmek için çift yönlü iletişim desteği sunar.
  • Streaming özelliği ile birlikte büyük-veri alışverişlerine uygundur.

gRPC Yapısı ve Akışı

gRPC’nin yapılandırma akışı

gRPC, Interface Definition Language (IDL) kullanarak bir servis contractlarını tanımlamayı destekler. Bunu haberleşmede kullanılacak objeleri, metotları ve içeriklerini tanımlamak olarak değerlendirebilirsiniz. Böylece servis tanımının bir parçası olarak, uzaktan çağrılabilecek yöntemleri ve parametrelerin veri yapısını ve dönüş türlerini belirtebilirsiniz.

gRPC’nin Özellikleri ve Avantajları

gRPC performanslıdır: gRPC mesajları, verimli bir binary mesaj formatı olan Protobuf kullanılarak seriliaze eder. Bu binary ve küçük boyutlu serialized mesajlar HTTP 2.0’ın hızıyla birleşince, oldukça performanslı bir iletişim altyapısı sağlanmış olur. (Multiplexing) Tek bir TCP bağlantısı üzerinden birden çok HTTP 2.0 isteğinin çoklanması büyük bir avantaj sağlar.

gRPC sizin için proto’dan kodları generate eder: Tüm gRPC frameworkleri kod üretimi için destek sağlar. gRPC servislerinin, metotlarının ve mesajlarının interfacelerini/contractlarını tanımlayan şey .proto dosyasıdır. Bu dosyadan gRPC frameworkleri ile ihtiyaç duyulan classlar, metotlar ve mesajlar üretilmektedir. Aynı proto hem client hem server içinde kullanılabilir. Farklı diller için kullanılsalar bile o dile ait kodlar tek bir proto dosyası üzerinden genarete edilebilir.

Spesifikasyonları vardır ve belirsizliği ortada kaldırır: gRPC için sepecificationlar belirlidir ve proto dosyaları üzerinden tüm süreç keskin bir şekilde tanımlanıp yürütülebilir. Böylece karmaşanın önüne geçilmektedir.

Streaming: gRPC HTTP 2.0 üzerinde çalışır ve HTTP 2.0'ın tüm stream özelliklerini destekler:

  • Unary: Client’ın servera tek bir istek gönderdiği ve tek bir yanıt aldığı en basit RPC türüdür.
  • Server’dan Client’a Streaming: Bir client’ın istek attıktan sonra isteğine yanıt olarak serverın stream başlatması ve istek atılan tüm mesajların client’a aktarılmasını içermektedir.
  • Client‘dan Server’a Streaming: Client bir stream açarak tüm mesajları server’a gönderir, mesaj gönderimi bitince server tek bir mesaj halinde cevap döner.
  • Bi-directional streaming: Çift yönlü streaming özelliği; client ve server birbirlerine tek bir mesaj ya da stream açabilir. İki streamde birbirinden bağımsız işler. Client ve server mesajları herhangi bir sırayla okuyabilir ve yazabilir.

Deadlines/Timeouts

Clientlar üzerinde bir gRPC isteğin tamamlanabilmesi için en fazla ne kadar süre beklemek istediklerini tanımlayabilmektedir. Aynı zamanda server belirli bir RPC’nin zaman aşımına uğrayıp uğramadığını veya RPC’yi tamamlamak için ne kadar süre kaldığını sorgulayabilir. Timeoutlar ile birlikte oluşabilecek yığılma ve aşırı kaynak tüketiminin önüne geçilebilir.

RPC Cancelling/ İstek İptali

Client veya server herhangi bir zamanda bir RPC’yi iptal edebilir. İptal, RPC’yi derhal sonlandırır, böylece daha fazla iş yapılmaz.

gRPC’nin Dezavantajları

  • Browser desteğinin az olması: gRPC’yi direkt olarak browserlar üzerindeki çağrılar için kullanamamaktayız. Bu da özellikle web uygulamarında direkt olarak kullanımın önüne geçmektedir. Bu nedenle dışarıdan gelen çağrılar için hala en iyi çözüm REST olarak kabul edilmektedir.
  • Okunabilirliği zor: HTTP API istekleri metin/text olarak gönderilir ve insanlar tarafından kolayca okunabilir ve oluşturulabilir. gRPC mesajları, varsayılan olarak Protobuf ile kodlanır. Örnekte de görebileceğiniz gibi clear text ya da Json’a göre daha karmaşıktır.
  • Implementasyonu daha zor: gRPC entegrasyonu Rest API’a göre biraz daha zaman alabiliyor.

gRPC’nin Implementasyonu

gRPC Client/Server örneği

Örnekte görüldüğü gibi gRPC bir projenin ödeme adımındaki microservisleri içermektedir. Oluşturulan iletişim metot ve modelleri (contract) Banking servisinde kullanılacak olan gRPC IDL’ları payment.proto üzerinde tanımlanmaktadır. Yani gRPC entegrasyonunda ilk olarak kullanılacak metot ve modelleri proto dosyası üzerinden tanımlamak gerekmektedir. Örnekte ise banking servisi için bu tanımlar içermektedir ve aynı proto dosyası client ve server gibi davranan microserviceler için kullanılabilir. Proto dosyası kullanılarak gerekli bağımlılıklar ile direkt olarak gRPC modülleri istenilen dil için generate edilebilir. Örnek kodda gerekli bağımlılıklar gradle ile projeye dahil edilmiştir.

gRPC programlama dilinden bağımsız olduğundan servisler için farklı diller kullanabiliriz. Bu örnekte payment servisi kotlin ile oluşturulurken banking servisi ise Java ile oluşturulmuştur. GitHub’daki bu kaynak kodunu kullanarak örneği de inceleyebilirsiniz.

Servis sözleşmesi (contract) banking servisi için payment.proto olarak oluşturuldu ve örnekte gözlemlenebilir.

Servis sözleşmesi kolaylıkla anlaşılabilir, aynı zamanda client ve servis için de kullanılabilir. Dil farkından dolayı sadece option kısımlarının değiştirilmesi yeterlidir. Her proto değişimi için build alınması gerektiğini unutmayın. Proto üzerinden dilinize göre eklenen dependencyler ile proto kullanılarak programlama diline uygun kodlar generate edilmektedir.

Örnek verecek olursak yandaki package ve classlardan oluşan blok gRPC için compile’dan sonra otomatik olarak oluşmaktadır. Her operasyon için gRPC bir servis tanımlamasına ve bu tanımlardan oluşan kodlara sahiptir. Build alındıktan sonra gRPC için oluşturulan class ve objeler yazılan uygulama kodları için de direkt olarak kullanılabilir hale gelmektedir.

Microservice Mimarisi ile gRPC

Birçok uygulama uzak sunucularla olan iletişim için REST kullanıyor ve bu ideal bir senaryo gibi gözüküyor. İş servisler arası iletişime gelince REST haberleşme yerini gRPC‘ye bırakıyor.

Hepimizin bildiği gibi microservice tabanlı uygulamalar birden fazla servisten oluşuyor ve bu servisler farklı programlama dilleriyle geliştirilebilmektedir. Servisler arasındaki senkron iletişim için yoğunlukla Restful mimari ile API entegrasyonları kullanılmaktadır. Sürekli her iletişim ihtiyacı için yeni API’ler yazmak ve farklı entpointler hazırlamak karmaşıklığı artırmaktadır. Rest haberleşme çok fazla veri, çok farklı API entegrasyon, latency (gecikme) problemleri gibi sorunlarla karşı karşıya bırakmaktadır. Saydığımız tüm sorunların üstesinden gelebileceğimiz ve oldukça popülerleşen bir yöntem olarak gRPC kullanılabilir. Rest tabanlı JSON/XML iletişimine göre gRPC 7 ila 10 kat daha hızlı mesaj iletimi sağlıyor.

Birden fazla farklı dilden oluşan bir uygulamada gRPC, bu çok dilli mimariye oldukça uygunluk gösterir. Örneğin daha önceki örnekte belirttiğimiz gibi payment servisi iletişim için gRPC kullanılarak oluşturulan birçok başka servislerle iletişim kurabilir.

Microservice mimarisindeki iletişimde, gRPC'nin tüm microserviceler arası iletişim için kullanıldığını, dışa bakan iletişimin ise REST veya GraphQL ile sağlamak günümüz dünyasında çok daha elverişli gibi görünüyor. Dışarıyla konuşan servisler için REST kullanıldığında, uygulamaya ulaşacak olan clientlar, dışa dönük servisleri API olarak kullanabilirler.

TL,DR; too long, didn’t read

gRPC microservice dünyasında önemli bir yer almaya başlamıştır ve giderek yaygınlaşmaktadır. Büyük firmalar Google başta olmak üzere -Netflix dahil- bu teknolojiyi kullanmaktadır ve sayıları her geçen gün artmaktadır.

Sonuç olarak microservice mimarisiyle geliştirilen bir uygulamada, servisler arasındaki tüm senkron iletişimler için gRPC kullanabiliriz. Böylece gRPC’nin getirdiği tüm avantajları kullanarak hızlı ve esnek bir iç iletişim altyapısı sağlayabiliriz.

Github Java ve Kotlin Kod Örneği:

— Bana ulaşmak için: Twitter, Linkedin

— 1:1 görüşmeler için: Superpeer

https://gokhana.dev

Kaynakça

--

--

Gökhan Ayrancıoğlu
Delivery Hero Tech Hub

Software Engineer @Yemeksepeti • #Java • #Spring Boot • #Kotlin • #Spark • #Microservices • https://gokhana.dev