AWS Serverless Kuyruklama Sistemi Geliştirme

26.03.2022 | dakika okuma
1. Giriş

Bu yazı konusu, serverless yaklaşımı ile kuyruklama sistemi nasıl geliştirilir olacak. Bulut sağlayıcısı olarak AWS’yi kullanacağız. Dil olarak .NET Core'u tercih edeceğiz.

Bu bölümde senaryoyu ortaya koyacağım ve çıktının ne olacağı konusunda ön bilgilendirme yapacağım.

RESTful API endpoint’lerimiz aşağıdaki gibi olacak.

[POST] api/comments
[GET] api/comments

Aşağıdaki AWS hizmetlerini kullanacağız.

API Gateway : RESTful API için ihtiyacımız olan endpoint’leri sağlayacak.
Lambda : GET ve POST işlemleri için fonksiyon yazmamızı sağlayacak.
SQS : Kuyruklama sistemi sağlayacak. POST işleminde yorum metinlerini daha sonra işlenmek üzere kuyruğa göndereceğiz.
Comprehend : Makine öğrenmesi sistemi sağlayacak. Girilen yorum metinlerinin dillerini algılamak için kullanacağız.
DynamoDB : NoSQL çözümü sağlayacak. POST işleminde verileri DynamoDB’ye yazacağız.
S3 : Her deployment sonrasında kodumuzun versiyonlanarak saklanmasına imkan verecek.
CloudFormation : Yukarıda belirttiğim tüm hizmetleri otomatik olarak oluşturmamıza ve yönetmemize imkan sağlayacak.

Proje tamamlandığında AWS üzerindeki mimari aşağıdaki gibi olacak.

Serverless Kuyruklama Mimarisi
Serverless

API'den POST metodu ile yorum metnini alacağız. Bu yorumu DynamoDB'ye kaydedeceğiz ve sonucu döneceğiz. Yorum metninin dilini otomatik olarak algılamak uzun sürebileceği için yorum metnini kuyruğa göndereceğiz. Kuyruktaki mesajları dinleyen lambda fonksiyonumuz dili algılamak için Comprehend servisini kullanacak. Sonuç alındıktan sonra DynamoDB'deki satır güncellenecek. API'den GET metodu ile yorum metinlerinin son halini döneceğiz.

2. Geliştirme Ortamının Hazırlanması

Bu bölümde geliştirme ortamımızı ayarlayacağız. AWS Serverless RESTful API Geliştirme yazımdaki 2. bölümü aynen uygulayabilirsiniz. Permission bölümünde aşağıdaki yetkileri de dahil etmeniz gerekli.

    • AmazonSQSFullAccess
    • ComprehendFullAccess
3. API Projesinin Hazırlanması

Bu bölümde en basit haliyle projeyi oluşturup deployment yapacağız. Henüz DynamoDB’ye ve SQS'e kayıt atmayacağız. Endpoint’lere istek atıp yanıt alacağız.

Aşağıdaki komut satırı ile proje dizinimizi oluşturalım.

    mkdir serverless-sqs
cd serverless-sqs
code .

İki tane ayrı proje oluşturacağız. Birisi API projesi diğeri kuyruktaki mesajları dinleyen Consumer projesi. VS Code'dan terminalden aşağıdaki komut satırı ilk önce api klasörü oluşturalım ve içerisine girelim.

    mkdir api
cd api

Aşağıdaki komut satırı ile serverless projemizi oluşturalım.

    serverless create --template aws-csharp --name comments-api

Handler.cs isimli dosya göreceksiniz. Bu uygulamanın giriş noktasıdır. Bizim GET ve POST olmak üzere iki tane fonksiyona ihtiyacımız olacak. Bu Nodejs'de mümkün iken .NET Core'da zahmetli. Manuel olarak çıktılarda düzeltme yapmamız gerekli ki bu hoşlanacağımız bir şey olmaz. :) O yüzden lambda'ya istek geldiğinde ASP.NET Core API ayağa kalkacak şekilde düzenleme yapacağız. Bu sayede istekleri proxy yardımı ile controller'daki action'lara yönlendireceğiz.

Önce temizlikle başlayalım. Handler.cs dosyasını silelim. Serverless projesi oluşturduğumuzda yüklenen paketleri aşağıdaki komut satırları ile silelim.

    dotnet remove package Amazon.Lambda.Core
dotnet remove package Amazon.Lambda.Serialization.Json

Proje içerisindeki build.cmd ve build.sh dosyalarındaki "hello.zip" kısmını "api-handler.zip" olarak değiştirelim. Projeyi derlediğimizde düzgün isimli bir artifact oluşsun. :) Birazdan bu artifact'in nasıl kullanılacağını serverless.yml'de belirteceğiz.

ASP.NET Core API ayağa kaldıracağımız için bazı paketleri yüklememiz gerekli. Aşağıdaki komut satırları ile paketleri yükleyelim.

    dotnet add package Microsoft.AspNetCore.App -v 2.1.4
dotnet add package Amazon.Lambda.AspNetCoreServer
dotnet add package AWSSDK.Extensions.NETCore.Setup

Startup.cs isminde dosya oluşturalım ve aşağıdaki kodu yapıştıralım.

Şimdi lambda'nın giriş noktasını ayarlayalım. LambdaEntryPoint.cs isminde bir dosya oluşturalım ve aşağıdaki kodu yapıştıralım.

Proje içerisinde serverless.yml dosyasını aşağıdaki kod ile değiştirelim.

16. satırda uygulamanın giriş noktasını LambdaEntryPoint dosyası olarak belirtiyoruz.
19. satırda API Gateway'de proxy endpoint oluşturuyoruz. Bu şekilde API Gateway'e gelen istekleri direkt olarak projede eşleşen Controller'lara aktarıyoruz.
23. satırda uygulamayı deployment yapılırken ihtiyacımız olan artifact'in yolunu belirtiyoruz.

Artık Controller'ımızı oluşturabiliriz. Controller isminde klasör oluşturalım ve içerisine CommentsController.cs isminde bir dosya oluşturalım. Aşağıdaki kodu yapıştıralım.

Models isminde klasör oluşturalım ve içerisine CommentsPostRequest.cs isminde bir dosya oluşturalım. Aşağıdaki kodu yapıştıralım.

Aşağıdaki komut satırı ile kodumuzu derleyelim.

    build
Serverless API derleme çıktısı
Derleme çıktısı

Aşağıdaki komut satırı ile aws’ye ilk deployment’ımızı yapalım.

    serverless deploy

Deployment işlemi bittikten sonra konsolda 1 tane endpoint ve 1 tane API Key yazacak.

Serverless deployment çıktısı
Deployment çıktısı
Bu endpoint’e istek atarak sonucu görebilirsiniz. Header’lara “x-api-key” eklemeniz ve değer olarak konsolda belirtilen API Key’i girmelisiniz.

Bu işlemin sonucunda AWS’de neler olmuş bakalım.

Cloud Formation’da stack oluştu.

Serverless API CloudFormation
CloudFormation

Kodumuz S3‘e atıldı.

Serverless API S3
S3

Endpoint’ler için API Gateway oluştu.

Serverless API Gateway
API Gateway

Lambda fonksiyonumuz oluştu.

Serverless API Lambda
Lambda
4. API Projesine DynamoDB'nin ve SQS'in Entegre Edilmesi

Bu bölümde API'den gelen POST isteğinde yorum metnini DynamoDB'ye yazacağız ve SQS'deki kuyruğa mesaj bırakacağız. GET isteğinde ise DynamoDB'den yorum metinlerini döneceğiz.

Aşağıdaki komut satırları ile ihtiyacımız olan paketleri yükleyelim.

    dotnet add package AWSSDK.DynamoDBv2
dotnet add package AWSSDK.SQS

serverless.yml dosyasını aşağıdaki şekilde güncelleyelim.

43. satırda DynamoDB'ye oluşturacak resource'u tanımlıyoruz.
46. satırda tabloya isim veriyoruz.
66. satırda oluşturduğumuz DynamoDB'nin ARN'sini export ediyoruz. 72. satırda ise tablonun ismini export ediyoruz. Bu export ettiğimiz ARN'yi ve tablo ismini consumer projesine import ederek DynamoDB'yi kullanacağız.
11. satırda oluşturduğumuz tablonun ismini environment variable olarak atıyoruz.
23. satırda lambda'ya oluşturduğumuz DynamoDB'ye tam erişim yetkisi veriyoruz.

40. satırda SQS'i oluşturacak resource'u tanımlıyoruz.
43. satırda kuyruğa isim veriyoruz.
78. satırda oluşturduğumuz SQS'in ARN'sini export ediyoruz. Bu export ettiğimiz ARN'yi consumer projesine import ederek SQS'i kullanacağız.
13. satırda oluşturduğumuz tablonun ismini environment variable olarak atıyoruz.
18. satırda lambda'ya oluşturduğumuz SQS'e tam erişim yetkisi veriyoruz.

Startup.cs dosyasını aşağıdaki şekilde güncelleyelim.

12. ve 13. satırda DynamoDB ve SQS client'larını IOC Container'a kaydediyoruz.

Models klasörü altına CommentsGetResponse.cs adında dosya oluşturalım ve aşağıdaki kodu yapıştıralım.

Models klasörü altına CommentsQueueRequest.cs adında dosya oluşturalım ve aşağıdaki kodu yapıştıralım.

CommentsController.cs dosyasını aşağıdaki kod ile güncelleyelim.

39. satırda DynamoDB'den yorum metinlerini dönüyoruz.
61. satırda DynamoDB'ye yorum metnini kaydediyoruz.
76. satırda SQS'de oluşturduğumuz kuyruğa işlenmek üzere mesaj gönderiyoruz.

Aşağıdaki komut satırı ile kodumuzu derleyelim.

    build
Serverless consumer derleme çıktısı
Derleme çıktısı

Aşağıdaki komut satırı ile kodumuzu deployment'ımızı yapalım.

    serverless deploy
Serverless consumer deployment çıktısı
Deployment çıktısı

POST isteği yapalım.

Serverless POSTMAN POST
POST

GET isteği yapalım.

Serverless POSTMAN GET
GET

Bu işlemin sonucunda AWS’de neler olmuş bakalım.

DynamoDB’de tablo oluştu ve POST isteği ile tabloya kayıt atıldı.

Serverless API DynamoDB
DynamoDB

SQS'de kuyruk oluştu ve POST isteği ile kuyruğa mesaj atıldı.

Serverless API SQS
SQS
5. Consumer Projesinin Hazırlanması

Bu bölümde SQS'deki kuyruğa gönderdiğimiz mesajları işleyecek olan consumer projesini yazacağız. VS Code’dan terminalden aşağıdaki komut satırını çalıştırarak consumer klasörü oluşturalım ve içerisine girelim.

    mkdir consumer
cd consumer

Aşağıdaki komut satırı ile serverless projemizi oluşturalım.

    serverless create --template aws-csharp --name comments-consumer

Yine önce temizlikle başlayalım. Handler.cs isimli dosyayı silelim.

Proje içerisindeki build.cmd ve build.sh dosyalarındaki “hello.zip” kısmını “consumer-handler.zip” olarak değiştirelim. Projeyi derlediğimizde düzgün isimli bir artifact oluşsun. 🙂 Birazdan bu artifact‘in nasıl kullanılacağını serverless.yml’de belirteceğiz.

SQS'deki kuyruktaki mesajları dinleyebilmek için SQSEvents, yorum metninin dilini bulabilmek için Comprehend ve NoSQL için DynamoDB paketlerinin kurulması gerekli. Aşağıdaki komut satırları ile paketleri yükleyelim.

    dotnet add package Amazon.Lambda.SQSEvents
dotnet add package AWSSDK.Comprehend
dotnet add package AWSSDK.DynamoDBv2

Models klasörü oluşturalım ve içerisine CommentsQueueRequest.cs isminde dosya oluşturalım, aşağıdaki kodu yapıştıralım.

ConsumerHandler.cs isimli bir dosya oluşturalım ve aşağıdaki kodu yapıştıralım.

21. satırda SQS'deki mesajı alıyoruz. Biz örneğimizde mesajları tek tek alacağımız için sıfırıncı indeksdeki değeri almamız yeterli. Örneğin mesajları onar onar şekilde alacak olsaydık döngüye sokmamız gerekecekti.
32. satırda Comprehend servisinden yorum metninin dil sorgulamasını yapıyoruz.
48. satırda ise DynamoDB'deki satırı güncelliyoruz.

Mesaj işlenirken hata oluşursa kuyruktaki mesaj tekrar işlenmek üzere handle edilir. Örneğin 35. satırda hata oluşursa bu mesaj tekrar işlenmek üzere yeniden handle edilir.

Proje içerisinde serverless.yml dosyasını aşağıdaki kod ile değiştirelim.

9. satırda api projesinde export ettiğimiz DynamoDB tablosunun ismini import ediyoruz.
13. satırda oluşturduğumuz SQS'e tam erişim yetkisi veriyoruz.
18. satırda Comprehend servisindeki dil bulma işlevine erişim yetkisi veriyoruz.
23. ve 24. satırda DynamoDB'ye erişim yetkisi veriyoruz.
35. satırda SQS'deki kuyruğa trigger bağlıyoruz.
38. satırda mesajların tek tek lambda'ya iletilmesi gerektiğini belirtiyoruz.

Aşağıdaki komut satırı ile kodumuzu derleyelim.

    build
Serverless consumer derleme çıktısı
Derleme çıktısı

Aşağıdaki komut satırı ile deployment‘ımızı yapalım.

    serverless deploy
Serverless consumer deployment çıktısı
Deployment çıktısı

Bu işlemin sonucunda AWS’de neler olmuş bakalım.

Cloud Formation’da stack oluştu.

Serverless Consumer CloudFormation
CloudFormation

Kodumuz S3'e atıldı.

Serverless Consumer S3
S3

Lambda fonksiyonumuz oluştu.

Serverless Consumer Lambda
Lambda

Bir önceki bölümde POST isteği yaparak SQS'deki kuyruğa mesaj bırakmıştık. O mesaj artık işlendi. GET isteği yaptığınızda yorum metninin dilinin kaydedildiğini göreceksiniz.

Serverless POSTMAN GET
GET

POST istekleri yaparak denemeye devam edebilirsiniz.

Projenin son haline Github’dan erişebilirsiniz.

ahmetkucukoglu/serverless-queuing

C#
3
1

Kolay gelsin.

Yazıyı Paylaş

Yorum bırak

Yanıtla

Yanıtlamayı iptal et
Bu site reCAPTCHA tarafından korunmaktadır ve Google Gizlilik Politikası ve Hizmet Şartları geçerlidir. Yorumunuz başarılı şekilde gönderildi reCaptcha doğrulanamadı
Muhabbetle ASP.NET Core ile geliştirildi.