AWS Lambda Functions-S3-CloudWatch’un Birlikte Kullanımı

Oktay Dağdelen
8 min readApr 5, 2020
Add →  New Project → print(‘ Hello Serverless World ! ’ )

www.haberanahtari.com sitesini yaparken neden Amazon Web Services Lambda , S3 ve CloudWatch’ı kullanma gereği duyduğumu adım adım anlatmadan önce gelin birlikte siteyi hızlıca inceleyelim…

www.haberanahtari.com bir çok farklı haber kaynağına tek bir yerden ulaşabilmenizi sağlar.

Yerli ve yabancı yüzlerce habere kolayca erişebilirsiniz.

Şimdi gelelim www.haberanahtari.com ‘un Backend tarafına !

Lambda Function Kullanımı

Serverless, yazılım geliştirme ve geliştirilen yazılımın yönetimi konusunda Sunucu ( Server ) kavramına olan bağımlılıkları azaltmayı hedefleyen bir mimari yaklaşımdır. Serverless, uygulamalar sunucuda çalıştırılmayacak anlamına gelmez.

Serverless’in değinmek istediği nokta, sadece kodunuza/fonksiyonunuzu odaklanmanızdır. Gerekli olan Container, Inftrastructure, Scaling gibi tüm operasyonel işlerin dış kaynaklar tarafından planlanması ve uygulanmasıdır.

AWS Lambda da Serverless uygulamalar geliştirebileceğiniz popüler bir bulut servisidir.

Şimdi AWS Console ’a bilgilerimizle giriş yaptıktan sonra Services bölümündeki Compute’nin altında Lambda’ya tıklıyoruz.

Açılan sayfada Create Function ’a tıklıyoruz.

Bir sonraki adım servisin adını ve kodun yazılacak olduğu yazılım dilinin seçiminde.

Lambda Servisleri .Net, Java, Go, Python, Node.js, Ruby gibi bir çok yazılım diline destek vermektedir.

www.haberanahtari.com ’un backend tarafını Python 3.8 ile yazdığım için aşağıdaki gibi devam ettim.

Bir kaç saniye geçtikten sonra Örnek Lambda function’ınız hazır durumda. Function Code altında 3 farklı şekilde kodunu çalıştırabilirsiniz.

1- Kendiniz kod yazarak (Edit code inline)

2- Yapıya uygun 10 MB’dan küçük zip’lenmiş kodunuzu yükleyerek ( Upload a .zip file )

3- Kodlarınızı Amazon S3'ün altına atıp, Url bilgisini paylaşarak. ( Upload a file from Amazon S3 )

Yazdığınız kod’da external paketlere ihtiyaç duyuyorsanız, paketi indirip, projenizin bulunduğu dizine atmanız gerekecektir.

Örneğin; www.haberanahtari.com için Python’da ihtiyaç duyduğum kütüphanelerden bir tanesi feedparser 5.2.1 versiyonu’ydu ve aşağıdaki gibi ekleyerek ilgili dizinde feedparser.py’ı elde etmiş oldum.

AWS Lambda ile Neler Yapılabilir ? Ben Neler Yaptım ?

AWS Lambda ile yapılabileceklerinizin en yaygın olanları şekilde;

  • Amazon API Gateway kullanarak HTTP isteklerinin atılabileceği endpoint’ler oluşturabilir
  • Amazon S3(Simple Storage Service) ’de file/folder barındırabilir ve üzerinde değişiklikler yapabilir
  • Amazon DynamoDB ’de veri tabanı operasyonları gerçekleştirebilir
  • Amazon Step Functions ile birden fazla sürecini yöneten iş akışları oluşturulabilir

Haber Anahtarı’nda yukarıdaki maddelerden ilk ikisini sırasıyla nasıl kullandığımı bölümlere ayırarak anlatmak istiyorum.

1- Lambda with API Gateway ile HTTP request’leri atabileceğim endpoint’lerin oluşturulması

2- Neden API Gateway’den vazgeçip, S3 (Simple Storage Service) içerisinde verilerimi static bir json file’da tutmayı tercih ettim ?

1- Lambda with API Gateway ile HTTP request’leri atabileceğim endpoint’lerin oluşturulması

Haber Anahtarı için haber sitelerinden veri toplayan, analiz eden, resim, yayınlanma tarihi ve bunun gibi bir çok bilgileri parse etmemi sağlayan Python kodunu Lambda function’ında yazdıktan sonra;

Designer kısmında Add Trigger → API Gateway diyerek ilerliyoruz.

API : Create an API
API type: REST API
Security : IAM

olacak şekilde ayarlayıp Add ’e tıklayarak devam edelim.

Bir kaç saniyenin ardından API Gateway’imiz ve API endpoint’imiz hazır.

Verilen endpointe gittiğimizde aşağıdaki gibi hata alacağız;

{ "message" :"Missing Authentication Token" }

Bunun sebebi API Gateway oluşurken gelen default Lambda_Proxy katmanı ve herhangi bir HTTP request’in tanımlanıp deploy edilmemesidir.

Şimdi haberanahtari-lambda-services-API ’ye tıklayarak açılan sayfadan Resources’ların altından Any’i seçerek Actions butonundan Delete Method ile Lambda_Proxy katmanını kaldırmış oluyoruz.

Aynı yerden Create Method → Get ’i seçerek ilerliyor ve bilgileri doldurup Save’e tıklıyoruz.

Bu kısımda dikkat edilmesi gereken kısım Integration type’ın Lambda Function olarak seçilmesi ve Lambda Function kısmında seçenekler arasından oluşturduğumuz function’ın seçilmesidir.

Bir sonraki adım yaptığımız API Gateway’i deploy etmek.

Actions → Deploy API diyerek devem ediyoruz.

İstenilen bilgileri kendi case’imize göre doldurup Deploy’a tıklıyoruz.

Deploy’un tamamlanmasının ardından Invoke URL kısmında görüldüğü gibi Get Request’i atabileceğimiz URL’imiz hazır durumda.

URL’imizi tarayıcıdan veya Postman üzerinden test ettiğimizde verilerimizin geldiğini göreceğiz ve artık UI tarafında API Fetch yapabiliriz durumdayız.

Not : Cors Problemi yaşarsanız, Lambda Function kodunuzda request header’ınızı aşağıdaki gibi düzenleyebilirsiniz.

return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps(result)
}

2- Neden API Gateway’den neden vazgeçip, S3 (Simple Storage Service) içerisinde verilerimi static bir json file’da tutmayı tercih ettim ?

UI ( User Interface ) kısmını React ile yaptığım www.haberanahtari.com ’da AWS Lambda Function API Gateway ile oluşturduğum endpoint ile verileri alıyor ve sayfayı çizmeye başlıyordum.

Fakat bu veriyi elde etme yöntemi bir takım problemlere yol açtı;

  • Verinin büyüklüğünden dolayı API Fetch süresi 5–6 saniyelerdeydi ve Loading Spinner’ı ile kullanıcıyı bu kadar süre bekletmek göz ardı edilemez bir sorundu. Kullanıcılar siteniz açılmadan çıkmak isteyeceklerdir.
  • Her bir request’te tekrardan API Fetch işleminin gerçekleşmesi ve tekrardan 5–6 saniye beklenmesi ( Bu sorun veriyi belirli bir süre cache’leyerek de çözülebilir )
  • Kullanıcı sayısının artması durumunda request sayısının da çoğalması ve ücretlendirmenin değişmesi (Ayda 1 Milyon Request ücretsiz ).

Verilerimin anlık değişmemesi ve static bir web sitesi oluşturduğum için API Gateway çözümü yerine Lambda Functions’daki kodumu verileri json olarak kaydedip S3 ’e news.json olarak kaydedecek şekilde düzenledim.

Bunu yaparken Python’da Amazon Web Services ile ilgili bir çok işlemi gerçekleştirebildiğimiz Boto3 kütüphanesi’ni kullandım ve kodumu şu şekilde güncelledim.

Yukarıda görüldüğü gibi S3'de “haberanahtari-data” bucket’ına “news.json” dosyasını yazdıracağız.

Şimdi sırada haberanahtari-data adında bucket oluşturulmasında…

Amazon S3 Kullanımı

Amazonun kendi tabiriyle S3 ;

Amazon S3, İnternet’te her yerden, her boyutta veri almak ve depolamak için oluşturulmuş bir nesne depolama hizmetidir. Çok düşük maliyetler karşılığında son derece dayanıklı, yüksek oranda erişilebilir ve sınırsız olarak ölçeklenebilir veri depolama altyapısı sunan basit bir depolama hizmetidir.

Services bölümündeki Storage’ın altında S3 tıklıyoruz.

Açılan sayfadan Create Bucket’i seçiyoruz ve sonrasında Bucket name ve Region seçimi geliyor.

Bulunduğum bölgeye en yakın yer olan EU (Ireland ) eu-west-1 ’i tercih ettim.

Ayrıca herhangi bir block policy ile karşılaşmamak için Block all public access seçeneğini kaldırıp yeniden Create Bucket diyerek devam ediyoruz.

Bucket’ı oluşturduk sonra Get, Put, Delete işlemlerini yapabilmek için yetki vermemiz gerekiyor.

Permissions → Bucket Policy kısmını aşağıdaki gibi doldurup kaydediyoruz.

  • Bucket Policy json ;
{
"Version": "2008-10-17",
"Id": "PolicyForPublicWebsiteContent",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::haberanahtari-data/*"
}
]
}

Artık bucket’ımız hazır ve Lambda Function’daki kodumuzun çalışması durumunda buraya news.json dosyasını atmasını bekliyoruz.

API endpoint’imizi tekrardan çalıştırıp kodumuzun doğru çalışıp çalışmadığını görebiliriz fakat artık herhangi bir API Gateway endpoint’ine ihtiyacımız yok, çünkü kodumuzun her atılan istekte çalışmasını istemiyor, Amazon S3 adresindeki static olan news.json’dan beslenmesini istiyoruz.

Peki, kodumuzu bir kere çalıştırıp S3 bucket’ında news.json dosyasını ürettik. Fakat yeni bir challange’ımız var;

  • Birinin S3 bucket’ındaki news.json’ı belirli aralıklarla güncellemesi yani Lambda Function’ımızı çalıştırması gerekiyor ki kullanıcılar hep aynı veriyi görmesin.

+Bu automic job için kim gönüllü olmak ister ?

Amazon CloudWatch : Ben ! Log’ları da görmek ister misin ?

Amazon CloudWatch Kullanımı

CloudWatch ile uygulamalarınızı izleyebilir, belirli periyotlarla otomatik olarak ( Schedule ) çalıştırabilir, performans değişikliklerine yanıt verebilir, kaynak kullanımını optimize edebilir, anormal davranışları anlayabilir ve alarmlar kurup sizi uyarmasını sağlayabilirsiniz.

Daha fazla bilgi için Amazon’un kendi sitesinden ulaşabilirsiniz.

Haber Anahtarı için CloudWatch kullanmamın sebebi oluşturduğum Lambda Function’ını 10 dakika da bir çalıştırmasıdır. Her 10 dakikada 1 kere tetiklenecek olan Lambda Function’ımız S3 bucket’ına yeni verilerimizi news.json dosyasının üzerine yazarak kaydedecek.

Services bölümündeki Management & Governance’ın altında CloudWatch’a tıklıyoruz.

Açılan sayfada Rules’a tıklıyoruz.

Sonrasında Create Rule diyerek devam ediyoruz.

Step 1 : Create Rule adımına geldiğimizde;

Event Source : Schedule ( Fixed rate of 10 Minutes ) 
Add Target : Event --> Lambda Function ( kodumuzun çalıştığı )

seçip Configure details diyerek devam ediyoruz.

Step 2 : Configure rule details adımına geldiğimizde Rule Name ve Description kısımlarını doldurum State : Enabled işaretledikten sonra Create Rule diyerek haberanahtari-CW-Job ’ı başlatmış oluyoruz.

CloudWatch panelinde oluşturduğumuz Rule gözükecektir.

LogGroups’a geldiğimizde aşağıdaki gibi oluşan CloudWatch Rule’a ait logları görüyor olacağız.

CloudWatch belirli miktarda log kaydını oluşturduktan sonra bir sonrakini yeni bir log dosyası olarak oluşturur, son oluşan log kaydına gittiğimizde kodumuzun çalışıp çalışmadığını anlayabiliriz.

Hatırlayalım : Lambda Function’daki kodumuz şöyle bitiyordu;

print('1: creating resources to S3 ')s3 = boto3.resource('s3')
obj = s3.Object('haberanahtari-data','news.json')
print('2: data created as news.json ')obj.put(Body=json.dumps(result))print('3: data written to S3 ')

CloudWatch Log’larına baktığımızda Lambda function’umuz her 10 dakikada 1 kere çalışıp, news.json’dosyasını yoksa oluşturup, var ise güncellediğini görüyoruz.

CloudWatch loglarını kontrol ettikten sonra son adımımız S3 bucket’ımızda news.json dosyasını kontrol etmek. Artık S3 bucket’larımıza nasıl gideceğimizi biliyorsunuz :)

Görüldüğü gibi haberanahtari-data bucket’ımızda news.json dosyası oluşmuş ve en son 00:17:38 ( GMT+0300 olmadan ) ‘de güncellenmiş durumda. Operasyon başarıyla tamamlandı !

Artık UI tarafında Axios Fetch Url’imizi S3 Bucket’ımızdaki news.json’a tıkladığımızda gördüğümüz Object Url değeri olarak değiştirebilir.

Ne Elde Ettim ?

  • API Gateway ile her request’te 5–6 saniyelik bekleme süresini S3 bucket’ında static file olarak saklayıp oradan fetch ederek 0.02 saniyeye kadar düşmesini sağlamak. Ciddi bir performans kazancı öyle değil mi !
  • İhtiyaca göre periyodu (10 dakika → 5 dakika gibi) değiştirip, verinin çeşitliliğini yönetmek.
  • Kullanıcı sayısının yoğunluğu ile doğru oranda değişkenlik gösteren request sayısı’nın ücretlendirilmesinden ( AWS Billing ) kurtulmak. ( 10 dakika 1 kere için request sayısı; 1 günde = 1440 | 1 ayda = 43200 ile sınırlandırılmış oluyor )

Bu yazımda sizlere Haber Anahtarı projesi geliştirme senaryosunda AWS Lambda Function, AWS S3 ve AWS CloudWatch kullanma deneyimimden bahsetmeye çalıştım.

Bir sonraki yazımda Haber Anahtarı UI tarafının canlıya alım işlemleri için

  • AWS S3 ile nasıl cost-effective web sitesi yayınladım
  • AWS Route 53 ile farklı firmadan aldığım Domain adresini Amazonda host ettiğim siteye nasıl yönlendirdim

konularına değineceğim. Takipte Kalın :)

-Oktay

--

--