AWS Lambda Tetikleyiciler ve Olay Kaynakları: Kapsamlı Rehber

Sunucusuz mimariyle ilk tanıştığımda, “bu tetikleyici olaylar nasıl çalışıyor?” sorusu kafamı çok meşgul etmişti. Lambda fonksiyonları yazmak güzel, ama asıl güç onları doğru olay kaynaklarıyla birleştirmekten geliyor. Bu yazıda AWS Lambda’nın tetikleyici mekanizmalarını, farklı olay kaynaklarını ve bunları gerçek dünya senaryolarında nasıl kullanacağınızı elimden geldiğince pratik bir şekilde aktaracağım.

Lambda Tetikleyicileri Neden Bu Kadar Önemli?

Lambda fonksiyonlarını tek başına düşünmek yanlış bir yaklaşım. Bir fonksiyon, ancak tetiklendiğinde değer üretir. Tetikleyiciler, Lambda’yı AWS ekosisteminin geri kalanıyla bütünleştiren yapıştırıcı görevi görür. S3’e bir dosya yüklendiğinde, bir API isteği geldiğinde, bir kuyruk dolduğunda ya da bir zamanlayıcı tetiklendiğinde Lambda devreye girer.

Tetikleyiciler iki temel modelde çalışır:

  • Push modeli: Olay kaynağı Lambda’yı doğrudan çağırır (S3, SNS, API Gateway bu modeli kullanır)
  • Pull modeli: Lambda, olay kaynağını kendisi polling yaparak izler (SQS, DynamoDB Streams, Kinesis bu modeli kullanır)

Bu ayrımı anlamak, hata ayıklama ve izin yönetimi açısından kritik önem taşır.

S3 Tetikleyicisi: En Yaygın Kullanım Senaryosu

S3 olayları, Lambda tetikleyicileri arasında en sık kullanılanların başında gelir. Dosya yükleme, silme veya kopyalama işlemlerinde fonksiyonu otomatik olarak çalıştırabilirsiniz.

Aşağıdaki örnek, bir S3 bucket’ına yüklenen görüntüleri otomatik olarak küçülten bir Lambda fonksiyonunu gösteriyor:

# Lambda fonksiyonu oluşturma
aws lambda create-function 
  --function-name image-resizer 
  --runtime python3.11 
  --role arn:aws:iam::123456789012:role/lambda-s3-role 
  --handler handler.lambda_handler 
  --zip-file fileb://function.zip 
  --timeout 30 
  --memory-size 512

# S3 bucket'ına olay bildirimi ekleme
aws s3api put-bucket-notification-configuration 
  --bucket my-upload-bucket 
  --notification-configuration '{
    "LambdaFunctionConfigurations": [
      {
        "LambdaFunctionArn": "arn:aws:lambda:eu-west-1:123456789012:function:image-resizer",
        "Events": ["s3:ObjectCreated:*"],
        "Filter": {
          "Key": {
            "FilterRules": [
              {"Name": "prefix", "Value": "uploads/"},
              {"Name": "suffix", "Value": ".jpg"}
            ]
          }
        }
      }
    ]
  }'

Burada dikkat etmeniz gereken iki önemli nokta var. Birincisi, filter kuralları ile gereksiz tetiklenmeleri önleyebilirsiniz. Her dosya yükleme işleminde fonksiyonun çalışmasını istemiyorsanız prefix ve suffix filtrelerini kullanın. İkincisi, S3 olayları asenkron olarak işlenir, yani Lambda invocation’da hata olursa event source tarafında retry mekanizması devreye girer.

Lambda tarafındaki Python handler örneği:

# handler.py içeriğini test etmek için test eventi oluşturma
aws lambda invoke 
  --function-name image-resizer 
  --payload '{
    "Records": [
      {
        "eventSource": "aws:s3",
        "s3": {
          "bucket": {"name": "my-upload-bucket"},
          "object": {"key": "uploads/test-image.jpg", "size": 1024}
        }
      }
    ]
  }' 
  --cli-binary-format raw-in-base64-out 
  output.json

cat output.json

API Gateway: HTTP Tetikleyicisi

REST API veya HTTP API endpoint’lerini Lambda’ya bağlamak, modern uygulama geliştirmenin temel taşlarından biri haline geldi. API Gateway ile Lambda arasındaki entegrasyon, tam anlamıyla sunucusuz bir backend oluşturmanıza olanak tanır.

# HTTP API oluşturma (REST API'ye göre daha ucuz ve hızlı)
aws apigatewayv2 create-api 
  --name my-serverless-api 
  --protocol-type HTTP 
  --target arn:aws:lambda:eu-west-1:123456789012:function:my-api-handler

# Lambda'ya API Gateway invoke izni verme
aws lambda add-permission 
  --function-name my-api-handler 
  --statement-id apigateway-invoke 
  --action lambda:InvokeFunction 
  --principal apigateway.amazonaws.com 
  --source-arn "arn:aws:execute-api:eu-west-1:123456789012:abc123/*"

API Gateway ile çalışırken sık karşılaşılan bir sorun, cold start gecikmesidir. Production ortamında Provisioned Concurrency kullanarak bu sorunu minimize edebilirsiniz:

# Provisioned Concurrency yapılandırması
aws lambda put-provisioned-concurrency-config 
  --function-name my-api-handler 
  --qualifier prod 
  --provisioned-concurrent-executions 5

Gerçek dünya senaryosunda bir e-ticaret sitesi düşünün. Ürün arama endpoint’i saniyede yüzlerce istek alıyor olabilir. Bu durumda Provisioned Concurrency ile 5 fonksiyonu sıcak tutarak ilk istek gecikmesini ortadan kaldırırsınız.

SQS Tetikleyicisi: Mesaj Kuyruğu Entegrasyonu

SQS (Simple Queue Service) ve Lambda entegrasyonu, pull modeli ile çalışır. Lambda Service, sizin adınıza SQS kuyruğunu polling yapar ve mesajları batch halinde fonksiyonunuza iletir.

# SQS kuyruğu oluşturma
aws sqs create-queue 
  --queue-name order-processing-queue 
  --attributes '{
    "VisibilityTimeout": "300",
    "MessageRetentionPeriod": "86400"
  }'

# Lambda için SQS event source mapping oluşturma
aws lambda create-event-source-mapping 
  --function-name order-processor 
  --event-source-arn arn:aws:sqs:eu-west-1:123456789012:order-processing-queue 
  --batch-size 10 
  --maximum-batching-window-in-seconds 30 
  --function-response-types ReportBatchItemFailures

Burada ReportBatchItemFailures parametresi çok kritik. Bu özelliği etkinleştirdiğinizde, batch içindeki başarısız mesajları tek tek raporlayabilir ve sadece o mesajları yeniden işleyebilirsiniz. Yoksa tüm batch başarısız sayılır ve hepsi tekrar kuyruğa döner.

SQS ile Lambda kullanırken dikkat edilmesi gereken birkaç nokta:

  • Visibility Timeout: Lambda fonksiyonunuzun timeout değerinin en az 6 katı olmalıdır
  • Batch size: 1 ile 10.000 arasında ayarlanabilir (standard queue için)
  • Dead Letter Queue: Sürekli başarısız olan mesajlar için DLQ yapılandırın
# DLQ yapılandırması
aws sqs create-queue --queue-name order-processing-dlq

aws sqs set-queue-attributes 
  --queue-url https://sqs.eu-west-1.amazonaws.com/123456789012/order-processing-queue 
  --attributes '{
    "RedrivePolicy": "{"deadLetterTargetArn":"arn:aws:sqs:eu-west-1:123456789012:order-processing-dlq","maxReceiveCount":"3"}"
  }'

EventBridge: Modern Zamanlayıcı ve Olay Yönlendirme

EventBridge, eski CloudWatch Events’ın yerini alan ve çok daha güçlü bir olay yönlendirme servisidir. Hem cron zamanlaması hem de AWS servisleri arasında olay yönlendirme için kullanabilirsiniz.

Zamanlanmış Tetikleyiciler

Gece yarısı veritabanı temizleme işlemleri, saatlik rapor üretimi gibi cron benzeri görevler için EventBridge mükemmel bir seçenektir:

# EventBridge rule oluşturma - her gece 02:00'da çalıştır
aws events put-rule 
  --name nightly-cleanup 
  --schedule-expression "cron(0 2 * * ? *)" 
  --state ENABLED 
  --description "Nightly database cleanup job"

# Lambda'yı rule'un hedefi olarak ekleme
aws events put-targets 
  --rule nightly-cleanup 
  --targets '[
    {
      "Id": "cleanup-function",
      "Arn": "arn:aws:lambda:eu-west-1:123456789012:function:db-cleanup",
      "Input": "{"action": "cleanup", "days": 30}"
    }
  ]'

# Lambda'ya EventBridge invoke izni
aws lambda add-permission 
  --function-name db-cleanup 
  --statement-id eventbridge-invoke 
  --action lambda:InvokeFunction 
  --principal events.amazonaws.com 
  --source-arn arn:aws:events:eu-west-1:123456789012:rule/nightly-cleanup

Event Pattern Matching

EventBridge’in gerçek gücü, karmaşık olay desenlerini eşleştirebilmesinde yatıyor. Örneğin, sadece belirli AWS hesabındaki EC2 instance durumu değişikliklerini yakalamak istiyorsanız:

# EC2 instance durumu değişikliklerini izleyen rule
aws events put-rule 
  --name ec2-state-monitor 
  --event-pattern '{
    "source": ["aws.ec2"],
    "detail-type": ["EC2 Instance State-change Notification"],
    "detail": {
      "state": ["stopped", "terminated"]
    }
  }' 
  --state ENABLED

DynamoDB Streams: Gerçek Zamanlı Veri Değişiklik İzleme

DynamoDB Streams, tablo üzerindeki her değişikliği (insert, update, delete) yakalayarak Lambda’ya iletebilir. Bu özellik, event sourcing ve change data capture senaryoları için idealdir.

# DynamoDB tablosunda stream etkinleştirme
aws dynamodb update-table 
  --table-name users 
  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

# Stream ARN'ını alma
STREAM_ARN=$(aws dynamodb describe-table 
  --table-name users 
  --query 'Table.LatestStreamArn' 
  --output text)

# Lambda event source mapping oluşturma
aws lambda create-event-source-mapping 
  --function-name user-sync-handler 
  --event-source-arn $STREAM_ARN 
  --starting-position LATEST 
  --batch-size 100 
  --bisect-batch-on-function-error 
  --maximum-retry-attempts 3

Burada bisect-batch-on-function-error parametresi önemli bir özellik. Hata durumunda batch’i ikiye bölerek hangi kaydın sorun çıkardığını otomatik olarak bulur. Bu, özellikle büyük batch boyutlarında debugging sürecini ciddi ölçüde kısaltır.

Gerçek bir kullanım senaryosu olarak düşünelim: Kullanıcı profillerinin DynamoDB’de tutulduğu ve her değişikliğin Elasticsearch’e senkronize edilmesi gerektiği bir sistem. DynamoDB Streams ile Lambda bu senkronizasyonu tamamen otomatik hale getirebilirsiniz.

SNS Tetikleyicisi: Pub/Sub Mimarisi

SNS (Simple Notification Service), çok sayıda subscriber’a mesaj iletmek için kullanılır ve Lambda ile kombinlendiğinde güçlü fan-out senaryoları oluşturabilirsiniz.

# SNS topic oluşturma
aws sns create-topic --name user-events

# Lambda'yı SNS topic'ine subscribe etme
aws sns subscribe 
  --topic-arn arn:aws:sns:eu-west-1:123456789012:user-events 
  --protocol lambda 
  --notification-endpoint arn:aws:lambda:eu-west-1:123456789012:function:user-event-handler

# Lambda'ya SNS invoke izni
aws lambda add-permission 
  --function-name user-event-handler 
  --statement-id sns-invoke 
  --action lambda:InvokeFunction 
  --principal sns.amazonaws.com 
  --source-arn arn:aws:sns:eu-west-1:123456789012:user-events

SNS ile Lambda arasındaki önemli bir fark şu: SNS, Lambda’yı asenkron olarak çağırır ve başarısız invocation’lar için otomatik retry yapar. Ancak mesaj delivery garantisi istiyorsanız SNS yerine SQS kullanmayı düşünebilirsiniz ya da SNS-SQS-Lambda zinciri kurabilirsiniz.

Kinesis Data Streams: Yüksek Hacimli Veri İşleme

Kinesis, gerçek zamanlı log analizi, clickstream verisi işleme veya IoT cihaz verilerini toplamak için kullanılır. Lambda ile entegrasyonu SQS’e benzer şekilde pull modeli üzerinden çalışır.

# Kinesis stream oluşturma
aws kinesis create-stream 
  --stream-name application-logs 
  --shard-count 4

# Lambda event source mapping
aws lambda create-event-source-mapping 
  --function-name log-processor 
  --event-source-arn arn:aws:kinesis:eu-west-1:123456789012:stream/application-logs 
  --starting-position LATEST 
  --batch-size 200 
  --parallelization-factor 5 
  --bisect-batch-on-function-error 
  --destination-config '{
    "OnFailure": {
      "Destination": "arn:aws:sqs:eu-west-1:123456789012:kinesis-failure-queue"
    }
  }'

parallelization-factor parametresi burada kritik bir performans düğmesi. Her shard için paralel olarak çalışacak Lambda invocation sayısını belirler. 1 ile 10 arasında değer alır. Yüksek hacimli stream’lerde bu değeri artırarak işleme kapasitesini önemli ölçüde genişletebilirsiniz.

Lambda Destination: Olay Sonrası Yönlendirme

Lambda Destination, fonksiyon tamamlandıktan sonra başarı veya hata durumuna göre olayı farklı hedeflere yönlendirmenizi sağlar. Bu özellik asenkron invocation’lar için çok kullanışlıdır.

# Lambda Destination yapılandırması
aws lambda put-function-event-invoke-config 
  --function-name order-processor 
  --maximum-retry-attempts 2 
  --maximum-event-age-in-seconds 3600 
  --destination-config '{
    "OnSuccess": {
      "Destination": "arn:aws:sqs:eu-west-1:123456789012:success-queue"
    },
    "OnFailure": {
      "Destination": "arn:aws:sns:eu-west-1:123456789012:failure-alerts"
    }
  }'

Bu yapılandırmayla, başarılı işlemler SQS kuyruğuna düşerken başarısız olanlar SNS üzerinden bildirim gönderir. Geleneksel try-catch bloklarına kıyasla çok daha temiz bir hata yönetimi sunar.

Tetikleyici Sorunlarını Giderme

Gerçek dünyada en çok karşılaştığım sorunlar ve çözümleri:

IAM İzin Hataları: Lambda’nın olay kaynağını okuyabilmesi ya da olay kaynağının Lambda’yı çağırabilmesi için doğru izinler şarttır.

# Lambda execution role'una SQS okuma izni ekleme
aws iam attach-role-policy 
  --role-name lambda-execution-role 
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole

# Event source mapping durumunu kontrol etme
aws lambda list-event-source-mappings 
  --function-name order-processor 
  --query 'EventSourceMappings[*].{Source:EventSourceArn,State:State,LastModified:LastModified}'

Mapping Durumu Sorunları: Event source mapping bazen “Disabled” veya “Problem” durumuna düşebilir. Bunu monitor etmek için CloudWatch alarmı kurmanızı tavsiye ederim.

# CloudWatch alarm ile mapping sorunlarını izleme
aws cloudwatch put-metric-alarm 
  --alarm-name lambda-iterator-age 
  --metric-name IteratorAge 
  --namespace AWS/Lambda 
  --statistic Maximum 
  --period 300 
  --threshold 600000 
  --comparison-operator GreaterThanThreshold 
  --dimensions Name=FunctionName,Value=order-processor 
  --evaluation-periods 2 
  --alarm-actions arn:aws:sns:eu-west-1:123456789012:ops-alerts

IteratorAge metriği, Kinesis veya DynamoDB Streams kullanırken işleme gecikmesini ölçer. Bu değer yükseliyorsa Lambda’nın stream’i yetişemediğini gösterir. Shard sayısını artırmak veya parallelization factor’ü yükseltmek çözüm olabilir.

Maliyet Optimizasyonu Pratikleri

Tetikleyicileri yanlış yapılandırmak, beklenmedik maliyetlere yol açabilir. Öğrendiğim birkaç pratik kural:

  • SQS Batch Size: Batch boyutunu mümkün olduğunca artırın. 1 yerine 100 mesajlık batch kullanmak, invocation maliyetini ciddi ölçüde düşürür
  • Filtering: EventBridge ve SQS event filtering kullanarak Lambda’ya ulaşan gereksiz olayları kaynak tarafında eleyin
  • Kinesis Shard Sayısı: Kapasiteden fazla shard açmak boşuna maliyet yaratır, IteratorAge metriğini izleyerek optimize edin
  • S3 Event Filtering: Prefix ve suffix filtreleri kullanmadan tüm bucket olaylarını Lambda’ya yönlendirmeyin
# SQS event filtering örneği - sadece belirli sipariş tiplerini işle
aws lambda update-event-source-mapping 
  --uuid <mapping-uuid> 
  --filter-criteria '{
    "Filters": [
      {
        "Pattern": "{"body": {"orderType": ["EXPRESS", "PRIORITY"]}}"
      }
    ]
  }'

Sonuç

AWS Lambda tetikleyicileri ve olay kaynakları, serverless mimarinin can damarını oluşturuyor. S3’ten Kinesis’e, API Gateway’den DynamoDB Streams’e kadar her olay kaynağı farklı bir kullanım senaryosuna hitap ediyor. Push ve pull modellerini iyi anlamak, IAM izinlerini doğru yapılandırmak ve batch boyutları ile retry politikalarını dikkatli seçmek, hem güvenilir hem de maliyet etkin sistemler kurmanın temelini oluşturuyor.

Başlangıçta bu kadar seçenek bunaltıcı gelebilir. Benim önerim, küçük başlayın: S3 veya EventBridge ile basit bir kullanım senaryosu deneyin. Sonra SQS ve DynamoDB Streams’e geçin. Her servisin kendi nüansları var ve bunları ancak pratikte, gerçek bir sistemde çalışarak özümseyebilirsiniz. CloudWatch metriklerini ve Lambda Insights’ı baştan yapılandırmayı da ihmal etmeyin; ilerleyen dönemde sorun giderirken bunların değerini çok daha iyi anlayacaksınız.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir