AWS ile Edge Computing: CloudFront Functions vs Lambda@Edge
Global uygulamalar için AWS edge computing çözümlerini seçme ve uygulama üzerine pratik örnekler ve maliyet optimizasyonu stratejileri içeren kapsamlı teknik rehber.
Edge computing, kod yürütmeyi merkezi data center’lardan kullanıcılara yakın konumlara taşıyor. AWS CloudFront dünya çapında geniş bir edge ağı işletiyor ve bu ağa kod yerleştirmek için iki yol sunuyor: CloudFront Functions ve Lambda@Edge. Varsayılan tercih CloudFront Functions olmalı: header işleri, redirect’ler ve cache key normalizasyonu burada çok daha düşük maliyetle çözülüyor. Lambda@Edge ise ancak request network erişimi, request body veya origin tarafındaki event’ler gerektirdiğinde bu maliyeti hak ediyor.
Edge Kodunun Çalıştığı Noktalar#
Her iki servis de request’i origin yerine edge’de karşılayarak latency’yi düşürüyor, ancak request yaşam döngüsünde farklı noktalarda duruyor ve farklı sınırlar taşıyorlar.
CloudFront Functions, network erişimi olmayan kısıtlı bir JavaScript runtime’ı çalıştırıyor; cache key normalizasyonu ve header manipülasyonu gibi yüksek hacimli dönüşümler için ölçeklendirilmiş. Lambda@Edge ise tam bir Node.js veya Python süreci çalıştırıyor; harici API çağrılarını, request body incelemesini ve origin tarafındaki logic’i mümkün kılan da bu.
Execution Point’leri#
CloudFront, edge function’ların çalışabileceği dört execution point sağlıyor:
- Viewer Request: CloudFront request’i aldıktan sonra, cache’i kontrol etmeden önce
- Viewer Response: Viewer’a response dönmeden önce
- Origin Request: Origin’e forward etmeden önce (sadece cache miss) - Sadece Lambda@Edge
- Origin Response: Origin’den response alındıktan sonra - Sadece Lambda@Edge
Servis Karşılaştırması#
Aşağıdaki satırlar, hangi işin hangi servise ait olduğunu belirleyen kısıtlar.
Özellik Karşılaştırması#
| Özellik | CloudFront Functions | Lambda@Edge |
|---|---|---|
| Execution Location | CloudFront edge location’ları | CloudFront edge location’ları |
| Runtime | Sadece JavaScript | Node.js 22.x, Python 3.13 |
| Execution Time | < 1 milisaniye | 5s (viewer), 30s (origin) |
| Memory | 2 MB | 128 MB - 10 GB |
| Max Package Size | 10 KB | 1 MB (viewer), 50 MB (origin) |
| Network Access | Hayır | Evet |
| Event Type’ları | Viewer request/response | Tüm 4 event type |
| Request Body Access | Hayır | Evet (origin event’lerde) |
| Response Size | 40 KB | 1 MB |
| Fiyatlandırma (1M başına) | $0.10 invocation | $0.60 invocation + compute |
| Cold Start | Yok | Var |
| KeyValueStore | Evet | Hayır |
Maliyet Etkisi#
Aylık 10 milyar request için maliyet farkı önemli:
- CloudFront Functions: 10,000M × $0.10 = $1,000
- Lambda@Edge: 10,000M × $0.60 + compute = $6,000-$8,000
CloudFront Functions basit kullanım senaryolarında 5-8x daha ucuz.
Karar Çerçevesi#
CloudFront Functions Üretim Ortamında#
CloudFront Functions, CloudFront edge location’larında sub-milisaniye latency ile çalışıyor. Network erişimi gerektirmeyen yüksek hacimli, basit operasyonlar için ideal.
Cache Key’ler ve Security Header’ları#
Query parameter’ları normalize ederek cache hit ratio’yu optimize etmek, origin load’u önemli ölçüde azaltabilir.
// Cache key normalizasyonu için CloudFront Function
function handler(event) {
var request = event.request;
var querystring = request.querystring;
// Device indicator'larını standart formata normalize et
if (querystring.device) {
var deviceValue = querystring.device.value.toLowerCase();
if (deviceValue === 'm' || deviceValue === 'mobile') {
querystring.device.value = 'mobile';
} else if (deviceValue === 'd' || deviceValue === 'desktop') {
querystring.device.value = 'desktop';
}
}
// Query parameter'ları alfabetik sırala - tutarlı cache key için
var sortedQuerystring = {};
Object.keys(querystring)
.sort()
.forEach(function(key) {
sortedQuerystring[key] = querystring[key];
});
request.querystring = sortedQuerystring;
// Accept-Encoding header'ını normalize et
if (request.headers['accept-encoding']) {
var acceptEncoding = request.headers['accept-encoding'].value;
if (acceptEncoding.includes('br')) {
request.headers['accept-encoding'].value = 'br,gzip';
} else if (acceptEncoding.includes('gzip')) {
request.headers['accept-encoding'].value = 'gzip';
}
}
return request;
}
Normalizasyon olmadan ?device=m&size=l ile ?size=l&device=mobile tek bir object için iki ayrı cache kaydı oluyor. Bu varyantları tek kayda indirmek hit ratio’yu yükseltiyor ve karşılık gelen request’leri origin’e hiç göndermiyor.
Security header’lar da viewer response aşamasında aynı deseni izliyor:
// Security header'ları için CloudFront Function (viewer response)
function handler(event) {
var response = event.response;
var headers = response.headers;
// Strict-Transport-Security (HSTS)
headers['strict-transport-security'] = {
value: 'max-age=31536000; includeSubDomains; preload'
};
// Content-Security-Policy (CSP)
headers['content-security-policy'] = {
value: "default-src 'self'; img-src 'self' https: data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
};
// X-Content-Type-Options
headers['x-content-type-options'] = {
value: 'nosniff'
};
// X-Frame-Options
headers['x-frame-options'] = {
value: 'DENY'
};
// X-XSS-Protection
headers['x-xss-protection'] = {
value: '1; mode=block'
};
// Referrer-Policy
headers['referrer-policy'] = {
value: 'strict-origin-when-cross-origin'
};
// Permissions-Policy
headers['permissions-policy'] = {
value: 'geolocation=(), microphone=(), camera=()'
};
return response;
}
Aylık 5 milyar request için bu CloudFront Functions ile $500’a mal olurken Lambda@Edge ile $3,000+ tutabiliyor.
KeyValueStore ile A/B Testing#
CloudFront Functions, yeniden deploy olmadan dinamik konfigürasyon için KeyValueStore’u destekliyor.
// A/B testing için KeyValueStore kullanan CloudFront Function
import cf from 'cloudfront';
const kvsId = 'a1b2c3d4-5678-90ab-cdef-example12345';
const kvsHandle = cf.kvs(kvsId);
async function handler(event) {
var request = event.request;
var uri = request.uri;
// Kullanıcının zaten experiment ataması var mı kontrol et
var cookies = request.cookies;
var experimentCookie = cookies['experiment_variant'];
var variant;
if (experimentCookie) {
variant = experimentCookie.value;
} else {
// Experiment konfigürasyonunu KeyValueStore'dan al
var experimentConfig = await kvsHandle.get('experiment_homepage');
var config = JSON.parse(experimentConfig);
// Traffic split'e göre variant ata
var random = Math.random() * 100;
if (random < config.variantA_percentage) {
variant = 'A';
} else if (random < (config.variantA_percentage + config.variantB_percentage)) {
variant = 'B';
} else {
variant = 'C';
}
// Gelecekteki request'ler için cookie set et
request.cookies['experiment_variant'] = { value: variant };
}
// URL'i variant'a göre yeniden yaz
if (uri === '/') {
request.uri = `/variants/home-${variant.toLowerCase()}.html`;
}
return request;
}
Tip
KeyValueStore güncellemeleri birkaç dakika içinde yayılıyor. Development sırasında versioning kullan ve production değişiklikleri için gradual rollout uygula.
Origin Tarafındaki Logic İçin Lambda@Edge#
Lambda@Edge, network erişimi, harici API’ler veya origin tarafındaki logic gerektiren operasyonları ele alıyor. Trade-off olarak daha yüksek maliyet ve critical path üzerinde olası bir cold start var.
Geo-Targeting ve Lokalizasyon#
CloudFront, Lambda@Edge’in intelligent routing için kullanabileceği coğrafi header’lar sağlıyor.
// Geo-targeting için Lambda@Edge function (viewer request)
'use strict';
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
// CloudFront geo header'ları sağlıyor
const country = headers['cloudfront-viewer-country']
? headers['cloudfront-viewer-country'][0].value
: 'US';
// Ülkeleri dil tercihlerine map et
const countryToLocale = {
'DE': '/de',
'AT': '/de',
'CH': '/de',
'TR': '/tr',
'FR': '/fr',
'ES': '/es',
'IT': '/it',
'US': '/en',
'GB': '/en',
'CA': '/en'
};
// Sadece root path'i redirect et
if (request.uri === '/') {
const locale = countryToLocale[country] || '/en';
// Kullanıcının locale tercihi cookie'si var mı kontrol et
const cookies = headers.cookie || [];
let localePreference = null;
for (let cookie of cookies) {
const matches = cookie.value.match(/locale=([^;]+)/);
if (matches) {
localePreference = matches[1];
break;
}
}
// Lokalize edilmiş path'e redirect et
const targetUri = localePreference || locale;
const response = {
status: '302',
statusDescription: 'Found',
headers: {
'location': [{
key: 'Location',
value: targetUri
}],
'cache-control': [{
key: 'Cache-Control',
value: 'max-age=3600'
}]
}
};
callback(null, response);
} else {
callback(null, request);
}
};
JWT Authentication#
JWT token’ları edge’de doğrulamak, unauthorized request’lerin origin’e ulaşmasını önlüyor.
// JWT validation için Lambda@Edge function (viewer request)
'use strict';
const jwt = require('jsonwebtoken');
// Production'da AWS Secrets Manager'dan çek
const JWT_SECRET = process.env.JWT_SECRET;
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
// Protected path'ler
const protectedPaths = ['/api/', '/dashboard/', '/admin/'];
const isProtected = protectedPaths.some(path => request.uri.startsWith(path));
if (!isProtected) {
callback(null, request);
return;
}
// Authorization header'ını çıkar
const authHeader = headers.authorization || headers.Authorization;
if (!authHeader || authHeader.length === 0) {
callback(null, unauthorizedResponse('Missing authorization header'));
return;
}
const token = authHeader[0].value.replace('Bearer ', '');
try {
// JWT token'ı doğrula
const decoded = jwt.verify(token, JWT_SECRET, {
algorithms: ['HS256'],
maxAge: '24h'
});
// Origin için custom header'lara kullanıcı bilgisi ekle
request.headers['x-user-id'] = [{
key: 'X-User-Id',
value: decoded.userId
}];
request.headers['x-user-email'] = [{
key: 'X-User-Email',
value: decoded.email
}];
callback(null, request);
} catch (error) {
console.error('JWT validation failed:', error.message);
callback(null, unauthorizedResponse('Invalid or expired token'));
}
};
function unauthorizedResponse(message) {
return {
status: '401',
statusDescription: 'Unauthorized',
headers: {
'www-authenticate': [{
key: 'WWW-Authenticate',
value: 'Bearer realm="Access to protected resources"'
}],
'content-type': [{
key: 'Content-Type',
value: 'application/json'
}]
},
body: JSON.stringify({
error: message
})
};
}
Tip
Lambda@Edge function’larında asla secret’ları hardcode etme. API call’larını ve cold start etkisini minimize etmek için caching ile AWS Secrets Manager kullan.
Origin Selection ve Failover#
Health check’lerle dinamik origin routing, dayanıklı mimariler sağlıyor.
// Origin selection için Lambda@Edge function (origin request)
'use strict';
const https = require('https');
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
// Primary ve secondary origin'ler
const origins = {
primary: {
domainName: 'api-primary.example.com',
port: 443,
protocol: 'https',
path: '/v1'
},
secondary: {
domainName: 'api-secondary.example.com',
port: 443,
protocol: 'https',
path: '/v1'
}
};
let selectedOrigin = origins.primary;
// Custom header'a göre route et
const routingHeader = request.headers['x-origin-override'];
if (routingHeader && routingHeader[0].value === 'secondary') {
selectedOrigin = origins.secondary;
}
// Path'e göre route et
if (request.uri.startsWith('/legacy/')) {
selectedOrigin = origins.secondary;
}
// Primary origin'i health check yap
try {
const isHealthy = await checkOriginHealth(selectedOrigin.domainName);
if (!isHealthy) {
console.log(`Primary origin ${selectedOrigin.domainName} unhealthy, failing over`);
selectedOrigin = origins.secondary;
}
} catch (error) {
console.error('Health check failed:', error);
selectedOrigin = origins.secondary;
}
// Request'i seçilen origin ile güncelle
request.origin = {
custom: {
domainName: selectedOrigin.domainName,
port: selectedOrigin.port,
protocol: selectedOrigin.protocol,
path: selectedOrigin.path,
sslProtocols: ['TLSv1.2'],
readTimeout: 30,
keepaliveTimeout: 5,
customHeaders: {}
}
};
callback(null, request);
};
function checkOriginHealth(domainName) {
return new Promise((resolve) => {
const options = {
hostname: domainName,
port: 443,
path: '/health',
method: 'GET',
timeout: 2000
};
const req = https.request(options, (res) => {
resolve(res.statusCode === 200);
});
req.on('error', () => resolve(false));
req.on('timeout', () => {
req.destroy();
resolve(false);
});
req.end();
});
}
Performans Optimizasyonu#
Lambda@Edge Cold Start’larını Azaltmak#
Cold start’lar, function’lar viewer request fazında çalıştığında kullanıcı deneyimini doğrudan etkiliyor. En doğrudan etkili yöntem package size: dependency’leri handler dışında initialize ederek warm invocation’ların setup maliyetini tamamen atlamasını sağla.
// KÖTÜ: Handler içinde initialize et
exports.handler = async (event) => {
const AWS = require('aws-sdk'); // Yavaş!
const dynamodb = new AWS.DynamoDB.DocumentClient();
// ...
};
// İYİ: Handler dışında initialize et
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event) => {
// Warm invocation'larda initialization'ı yeniden kullanır
};
Memory allocation da önemli. Daha fazla memory, daha fazla CPU demek ve bu da cold start süresini azaltıyor. Orta düzeyde dependency’leri olan Lambda@Edge function’lar için 512 MB genellikle ideal nokta.
Dependency’ler etkiyi katlıyor. Ağır kütüphaneleri daha hafif alternatiflerle değiştir:
moment.js→date-fnsveya nativeDate- Tam AWS SDK → bireysel service client’ları
- Büyük image processing kütüphaneleri → minimal implementasyon’lar
Cold start, function’ın cevap verebilmek için yüklemesi gereken her şeyle birlikte büyüyor. Bağımlılığı olmayan bir function neredeyse fark edilmiyor, AWS SDK’yı bundle etmek ölçülebilir bir gecikme ekliyor, Sharp gibi native modüller ise en kötü durum. Bir aralık varsaymak yerine kendi function’larını CloudWatch’ta ölç.
CloudFront Functions Optimizasyonu#
Kodu Minimal Tut: 10 KB limiti tüm kodu içeriyor. Hardcode değerler yerine konfigürasyon verisi için KeyValueStore kullan.
KeyValueStore’dan Yararlan: Function yeniden deploy’u önlemek için konfigürasyon verisini offload et. KeyValueStore sub-milisaniye okuma ile 5 MB storage sağlıyor.
Maliyet Analizi ve Optimizasyon#
Detaylı Maliyet Hesaplama#
Senaryo: Aylık 5 milyar request, 50ms ortalama süre, 128 MB memory
CloudFront Functions:
5,000M invocation × $0.10 = $500
Toplam: $500/ay
Lambda@Edge:
Request charge'ları: 5,000M × $0.60 = $3,000
Compute: 5,000M × 0.05s × 0.125GB × $0.00005001 = $1,563
Toplam: $4,563/ay
Tasarruf: CloudFront Functions kullanarak $4,063/ay (%89 azalma)
Maliyet Optimizasyon Stratejileri#
Lambda@Edge Memory’yi Optimize Et: CloudWatch metrikleri kullanarak memory allocation’ı doğru boyutlandır. Daha fazla memory, execution süresini azaltarak daha yüksek memory maliyetlerini dengeleyebilir.
Invocation Frekansını Azalt: Edge function invocation’larını minimize etmek için CloudFront cache policy’lerini etkili kullan. Her cache’lenen response bir function invocation’dan kaçınır.
Gerçek Kullanımı İzle: Maliyet threshold’ları için CloudWatch alarm’ları kur:
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
const lambdaEdgeCostAlarm = new cloudwatch.Alarm(this, 'LambdaEdgeCostAlarm', {
metric: new cloudwatch.Metric({
namespace: 'AWS/Lambda',
metricName: 'Invocations',
dimensionsMap: {
FunctionName: edgeFunction.functionName,
},
statistic: 'Sum',
period: cdk.Duration.days(1),
}),
threshold: 1_000_000_000, // günde 1 milyar invocation
evaluationPeriods: 1,
alarmDescription: 'Lambda@Edge invocation budget threshold aşıldı',
});
Debugging ve Logging Zorlukları#
Lambda@Edge logları function’ın çalıştığı AWS bölgesinde oluşuyor, bu da debugging’i karmaşık hale getiriyor.
Logları Bölgeler Arasında Bulmak#
CloudFront Response Header’larını Kontrol Et:
curl -I https://your-distribution.cloudfront.net/path
# Ara: x-amz-cf-pop: IAD89-P1
# IAD = us-east-1 region
Havaalanı Kodu-Region Eşlemesi:
- IAD (Dulles) → us-east-1
- SFO (San Francisco) → us-west-1
- DUB (Dublin) → eu-west-1
- NRT (Tokyo) → ap-northeast-1
- SYD (Sydney) → ap-southeast-2
Structured Logging Yaklaşımı#
// Structured logging ile Lambda@Edge function
'use strict';
exports.handler = async (event, context) => {
const request = event.Records[0].cf.request;
const requestId = context.requestId;
// Kolay parse için structured log
const logContext = {
requestId,
uri: request.uri,
method: request.method,
country: request.headers['cloudfront-viewer-country']?.[0]?.value,
timestamp: new Date().toISOString(),
};
console.log('REQUEST_START', JSON.stringify(logContext));
try {
// Logic buraya
console.log('PROCESSING', JSON.stringify({ ...logContext, step: 'validation' }));
return request;
} catch (error) {
console.error('ERROR', JSON.stringify({
...logContext,
error: error.message,
stack: error.stack,
}));
throw error;
} finally {
console.log('REQUEST_END', JSON.stringify(logContext));
}
};
Structured log’ları sorgulamak için CloudWatch Logs Insights kullan:
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 100
Edge Function Hatalarını Çözmek#
Response Size Aşımı (502 Hataları)#
1 MB’ı aşan bir response, CloudFront’un 502 dönmesine neden olur. Dönmeden önce boyutunu kontrol et:
const responseBody = JSON.stringify(data);
const sizeInBytes = Buffer.byteLength(responseBody, 'utf8');
if (sizeInBytes > 1048576) { // 1 MB = 1048576 byte
console.error(`Response size ${sizeInBytes} 1MB limitini aşıyor`);
// Bunun yerine S3 object referansı dön
return {
status: '200',
body: JSON.stringify({
url: `https://s3.amazonaws.com/bucket/response-${requestId}.json`
})
};
}
Viewer Request Timeout’ları#
Problem: Viewer request Lambda@Edge function timeout veriyor.
Promise.race timeout’u uygular:
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), 4000)
);
const result = await Promise.race([
fetchExternalData(),
timeoutPromise
]);
Cache Key Verimsizliği#
Cache hit ratio düşük ve origin request’leri yüksek. CloudFront cache key’i hesaplamadan önce query parameter’ları normalize et:
function normalizeQueryString(querystring) {
// Tracking parameter'larını kaldır
const trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'fbclid', 'gclid'];
trackingParams.forEach(param => delete querystring[param]);
// Kalan parameter'ları sırala
const sorted = {};
Object.keys(querystring).sort().forEach(key => {
sorted[key] = querystring[key];
});
return sorted;
}
AWS CDK Deployment Pattern#
CloudFront’u edge function’larla deploy etmek için eksiksiz CDK stack:
// Edge function'larla CloudFront için AWS CDK stack
import * as cdk from 'aws-cdk-lib';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
import * as path from 'path';
export class EdgeComputingStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
// ÖNEMLİ: Lambda@Edge us-east-1'de deploy edilmeli
super(scope, id, { ...props, env: { region: 'us-east-1' } });
// Origin için S3 bucket
const bucket = new s3.Bucket(this, 'OriginBucket', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
});
// Cache key normalizasyonu için CloudFront Function
const cacheKeyFunction = new cloudfront.Function(this, 'CacheKeyNormalization', {
code: cloudfront.FunctionCode.fromFile({
filePath: path.join(__dirname, '../functions/cache-key-normalization.js'),
}),
runtime: cloudfront.FunctionRuntime.JS_2_0,
comment: 'Daha iyi hit ratio için cache key normalize et',
});
// Security header'ları için CloudFront Function
const securityHeadersFunction = new cloudfront.Function(this, 'SecurityHeaders', {
code: cloudfront.FunctionCode.fromFile({
filePath: path.join(__dirname, '../functions/security-headers.js'),
}),
runtime: cloudfront.FunctionRuntime.JS_2_0,
comment: 'Her response için security header ekle',
});
// JWT authentication için Lambda@Edge function
const jwtAuthFunction = new cloudfront.experimental.EdgeFunction(
this,
'JwtAuthFunction',
{
runtime: lambda.Runtime.NODEJS_22_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/jwt-auth')),
timeout: cdk.Duration.seconds(5),
memorySize: 128,
}
);
// Optimize caching için cache policy
const cachePolicy = new cloudfront.CachePolicy(this, 'OptimizedCachePolicy', {
cachePolicyName: 'EdgeComputingOptimized',
comment: 'Normalize edilmiş cache key ile optimize policy',
defaultTtl: cdk.Duration.hours(24),
maxTtl: cdk.Duration.days(365),
minTtl: cdk.Duration.seconds(1),
enableAcceptEncodingGzip: true,
enableAcceptEncodingBrotli: true,
headerBehavior: cloudfront.CacheHeaderBehavior.allowList(
'CloudFront-Viewer-Country',
'CloudFront-Viewer-Country-Region'
),
queryStringBehavior: cloudfront.CacheQueryStringBehavior.allowList(
'w', 'h', 'q', 'format'
),
});
// CloudFront distribution
const distribution = new cloudfront.Distribution(this, 'Distribution', {
defaultBehavior: {
origin: new origins.S3Origin(bucket),
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
cachePolicy,
functionAssociations: [
{
function: cacheKeyFunction,
eventType: cloudfront.FunctionEventType.VIEWER_REQUEST,
},
{
function: securityHeadersFunction,
eventType: cloudfront.FunctionEventType.VIEWER_RESPONSE,
},
],
edgeLambdas: [
{
functionVersion: jwtAuthFunction.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
},
],
},
enableLogging: true,
logIncludesCookies: true,
});
// Output'lar
new cdk.CfnOutput(this, 'DistributionDomainName', {
value: distribution.distributionDomainName,
});
new cdk.CfnOutput(this, 'DistributionId', {
value: distribution.distributionId,
});
}
}
Warning
Lambda@Edge function’ları CloudFront distribution’ınızın nerede deploy edildiğine bakılmaksızın her zaman us-east-1 bölgesinde oluşturulmalı.
Lambda@Edge’e Ne Zaman Geçmeli#
İki kesin sınır her iki yöndeki geçişlerin çoğunu belirliyor: CloudFront Functions’taki 10 KB kod sınırı ve Lambda@Edge’deki 1 MB response sınırı.
İşleyen bir sıra şu: CloudFront managed cache policy ile başla, cache key’i şekillendirmen gerektiğinde bir CloudFront Function ekle, Lambda@Edge’i ancak bu sınırlardan biri zorladığında devreye sok. Hangi servis path’e girerse girsin her request’in üzerinde duruyor; bu yüzden hata durumunda orijinal request’i olduğu gibi dön ve error rate’i takipte tut.
Kaynaklar#
- CloudFront Functions ile Edge’de Özelleştirme (yeni sekmede açılır) - Hafif viewer-request ve viewer-response fonksiyonları için resmi rehber
- Lambda@Edge ile Edge’de Özelleştirme (yeni sekmede açılır) - CloudFront edge konumlarında tam Node.js/Python çalıştırma
- CloudFront Functions ve Lambda@Edge Arasındaki Farklar (yeni sekmede açılır) - Özellik karşılaştırması, çalışma zamanı sınırları ve maliyet dengesi
- Lambda@Edge Olay Yapısı (yeni sekmede açılır) - Dört CloudFront tetikleme noktası için istek ve yanıt olay nesneleri
- Lambda@Edge Kısıtlamaları (yeni sekmede açılır) - 1 MB yanıt boyutu ve us-east-1 dağıtım gereksinimi dahil sert sınırlar
- Lambda@Edge Örnek Fonksiyonları (yeni sekmede açılır) - Kimlik doğrulama, yönlendirme ve başlık düzenleme için referans implementasyonlar
- Edge Fonksiyon Logları - Amazon CloudFront (yeni sekmede açılır) - Dağıtık edge fonksiyon loglaması için CloudWatch Logs yapılandırması
İlgili yazılar
Dev, staging ve production ortamlarında Lambda Layer versiyonlarını AWS CDK ile yönetmek için pratik yaklaşımlar: otomatik pipeline ve rollback dahil.
aws · lambda · aws-cdk +4
AWS CDK, Lambda ve GitHub Actions kullanarak otomatik preview ortamları oluşturmayı öğrenin - sorunsuz PR test ve inceleme süreçleri için
aws-cdk · serverless · ci-cd +5
Multi-environment deployment, ölçekte performans optimizasyonu, maliyet yönetimi ve sağlam incident response pattern'ları ile monitoring.
aws-cdk · lambda · dynamodb +6
AWS Lambda performance tuning: memory-CPU modeli, Power Tuning ile benchmarking, maliyet analizi ve adaptive allocation pattern'ları.
lambda · serverless · performance +2
İç servis katmanı kurmadan önce kurup kurmayacağınıza karar verin. Katmanın çağrı başına maliyeti, VPC Lattice'in kazandığı hacim ve direct invoke'un hâlâ kazandığı an.
aws · aws-cdk · lambda +4