Lär dig migrera monolith till serverless med AWS Lambda. Steg-för-steg-guide med arkitekturtips och verkliga exempel.
Varför serverlösa är ingen magisk lösning — och varför du ändå bör göra migreringen
Jag har sett otaliga företag som kastar sig in i en "serverless-migration" med förhoppningen att bara trycka på en knapp och plötsligt ha obegränsad skalbarhet för noll kostnad. Sanningen är mer nyanserad. En migrering av en monolith till AWS Lambda kräver lika mycket (ibland mer) arkitektoniskt arbete som att bygga mikrotjänster från scratch, men med en avgörande fördel: du behöver inte hantera servrar.
Enligt en rapport från Datadog 2024 körs AWS Lambda-funktioner i genomsnitt 4,2 timmar per dygn i produktionsmiljöer — det betyder att majoriteten av företagen fortfarande betalar för tomgångskapacitet om de körde på traditionella servrar. För en e-handelsplattform med varierande trafik kan detta innebära besparingar på 40–60 % i infrastrukturkostnader.
Men varning: om din applikation har steady-state-trafik dygnet runt (tänk B2B-system med konstant last) kan serverless faktiskt bli dyrare. AWS Lambda debiterar per anrop och per GB-sekund, och vid hög kontinuerlig belastning kan en reserved instance eller till och med en container-baserad lösning vara mer kostnadseffektiv. Varje migrering måste föregås av en noggrann kostnadsanalys baserad på din faktiska trafikprofil.
Steg 1: Kartlägg din monolith — identifiera bounded contexts
Innan du skriver en rad serverlös kod behöver du förstå din befintliga arkitektur. Många företag underskattar detta steg och hoppar direkt på mikrotjänst-tåget, vilket leder till distribuerade monolit-applikationer — samma耦合 som förut, men nu med nätverkslatens.
Verktyg du kan använda för analys
AWS Application Discovery Service — automatiserar insamling av konfigurations-, användnings- och beteendedata från dina servrar. Kan köras med "agentless" läge för snabb inventering eller med agenter för djupare dependency mapping.
Dynatrace eller New Relic — om du redan kör applikationsövervakning kan du exportera call graphs för att identifiera vilka moduler som pratar med vilka, och vilka som har högsta anropsfrekvensen.
Gitblame-analys — ignorera inte värdet av att titta på commit-historik. Moduler som ändras ofta är ofta kandidater för tidig migrering eftersom teamen redan jobbar med dem aktivt.
Minsta leverbara enhet: Domain-driven design på riktigt
Eric Evans Domain-Driven Design-bok från 2003 är fortfarande den bästa guiden här, men i praktiken handlar det om att identifiera bounded contexts — de naturliga gränser i din domän där koncept har specifik betydelse. I en e-handelsplattform skulle detta kunna vara:
- Orderhantering — order creation, order updates, order cancellation
- Lagerhantering — inventory checks, stock reservations, supplier sync
- Kundvagn — cart operations, price calculations, coupon validation
- Betalning — payment initiation, 3D Secure, refund processing
- Användarautentisering — registration, login, password reset, MFA
Undvik att splitta på teknisk linje (t.ex. "databaslagret", "API-lagret"). Splitta på affärsdomän istället. Detta säkerställer att dina Lambda-funktioner förblir oberoende och kan evolvera självständigt.
Steg 2: Välj rätt migreringsstrategi
Det finns tre huvudsakliga vägar, och valet beror på din riskaptit, teamstorlek och applikationens livslängd.
A) Strangler Fig Pattern — rekommenderad för de flesta
Känt från Martin Fowlers mönster, men med serverless-twist:
- Deploy en ny Lambda bredvid din befintliga monolith
- Lägg en API Gateway eller Application Load Balancer framför som kan route:a specifika endpoints till antingen Legacy-systemet eller den nya funktionen
- Migrera en endpoint i taget — börja med lågtrafik, lågriskerade endpoints
- När alla endpoints är migrerade, stäng av den gamla monolith
┌─────────────────────────────────────────────────────────────┐
│ API Gateway │
│ /orders/* ──► Lambda: OrderService │
│ /products/* ──► Lambda: ProductService │
│ /users/* ──► Lambda: AuthService │
│ /legacy/* ──► ALB ──► EC2: Monolith (temporär) │
└─────────────────────────────────────────────────────────────┘
B) Big Bang Rewrite — undvik om möjligt
Omskrivning från grunden i ett steg. Frestande för att det verkar "rent", men historien visar att detta misslyckas oftare än det lyckas. Risken är att du efter 12 månaders arbete har en ny arkitektur men ingen produktionsdata som validerar att den fungerar.
C) Hybrid — Lambda som komplement
Om din monolith har vissa compute-intensiva uppgifter (bildbehandling, video encoding, batch-jobs) kan du börja med att exportera dessa till Lambda medan resten fortsätter köra on-premise eller på EC2. Detta ger snabba vinster utan att du behöver göra en fullständig arkitektur-ändring.
Steg 3: Hantera delat tillstånd — den svåra delen
Här krånglar de flesta migreringar till sig. I en monolith kan funktion A läsa från samma databas som funktion B utan att någon behöver tänka på det. I en serverlös arkitektur är varje funktion isolerad — deltat state måste exploderas till något distribuerat.
Databasstrategier för serverless
Alternativ 1: Per-service databaser (rekommenderad)
Varje Lambda-funktion (eller grupp av funktioner) får sin egen databas. Detta kan vara:
Amazon DynamoDB — fully managed, serverless, med on-demand pricing som passar perfekt för Lambda. Kan skalas från 0 till obegränsat utan att du behöver röra något. För en order-tjänst med varierande last är DynamoDB ett utmärkt val.
Amazon Aurora Serverless v2 — om du behöver relationsdatabas men vill slippa capacity planning. Skalas automatiskt, och du betalar per ACU (Aurora Capacity Unit) per sekund. Prissättning: ~$0.12 per ACU-timme i EU (Frankfurt).
Amazon RDS Proxy — om du av någon anledning behöver behålla en traditionell RDS-instans, kan du placera en RDS Proxy framför den. Detta multiplexar Lambda-anslutningar (som kan öppna/stänga tusentals connectioner per sekund) till ett hanterat connection pool, vilket undviker att databasen kvävs.
Alternativ 2: Event-driven meddelandehantering
Istället för synkrona API-anrop mellan tjänster, använd asynkrona events:
┌──────────────┐ SQS-kö ┌──────────────┐
│ Lambda: │ ─────────────► │ Lambda: │
│ OrderService │ │ InventorySvc │
└──────────────┘ └──────────────┘
│ │
▼ ▼
DynamoDB: DynamoDB:
Orders Inventory
AWS SQS Standard Queues kostar $0.40 per miljon förfrågningar (EU). För de flesta applikationer är detta försumbart jämfört med driftskostnaden för att hantera synkronitet.
Viktig varning om delade tabeller:
Om din monolith använder ett schema där flera moduler läser från samma tabell (ett anti-pattern, men vanligt i äldre system), måste du antingen:
a) Skapa separata tabeller med DynamoDB Streams för att synka data
b) Använda en read-replica för varje tjänst
c) Acceptera att du behöver göra en schema-migration först — ignorera inte detta steg, för det kommer att explodera i tekniskt skuld annars.
Steg 4: Hantera cold starts och prestanda
En av de mestdiskuterade nackdelarna med AWS Lambda är cold starts — fördröjningen när en funktion aktiveras efter att ha varit inaktiv. För Node.js och Python är detta ofta 100–500 ms. För Java eller .NET kan det vara 1–5 sekunder.
Strategier för att minimera cold starts
Provisioned Concurrency — håller funktioner förvärmda. Prissättning: ~$0.015 per GB-sekund och ~$0.06 per vCPU-sekund i EU. För produktions-API:er med krav på låg latens är detta värt kostnaden.
SnapStart — tillgänglig för Java (Corretto 11+) runtime. Skapar en pre-initialized snapshot av din funktion vid deployment, vilket kan minska cold starts med 90 %. För Lambda@Edge eller regioner där SnapStart inte är tillgänglig är detta ett alternativ.
Minimera bundle size — använd native dependencies sparsamt, preferera lättviktsramverk. En 500 MB-deployment tar längre tid att starta än en 10 MB. För Node.js: använd
--strip-devvid webpack-körning, och överväg ESM-format.Burst concurrency vs. reserved concurrency — om din funktion förväntas hantera plötsliga trafiktoppar, se till att ha tillräckligt med burst concurrency (standard: 500–3000 beroende på region). För konstant hög trafik, sätt reserved concurrency för att garantera kapacitet.
Benchmark: Cold start-tider per runtime (2024)
| Runtime | Cold start (p99) | Med Provisioned |
|---|---|---|
| Node.js 20 | 120 ms | 5 ms |
| Python 3.12 | 150 ms | 8 ms |
| Java 21 (SnapStart) | 200 ms | 15 ms |
| .NET 8 | 800 ms | 50 ms |
| Go 1.21 | 50 ms | 3 ms |
Mitt råd: Om du bygger ett API med krav på <200 ms svarstid, använd Node.js eller Go. Om prestanda inte är kritisk men du har befintlig Java-kodbas, använd SnapStart och gör benchmarks innan du avfärdar Java.
Steg 5: Säkerhet i en serverlös arkitektur
Serverless minskar din attackyta eftersom du inte hanterar operativsystemet, men det introducerar nya säkerhetsutmaningar.
Principen om minst privilegium — IAM på funktionsnivå
Varje Lambda-funktion ska ha en dedikerad IAM-roll med exakt de permissions den behöver:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"dynamodb:Query",
"dynamodb:GetItem"
],
"Resource": "arn:aws:dynamodb:eu-central-1:123456789:table/Orders"
}]
}
Undvik wildcard i Resource-fält ("Resource": "*"). Det är bekvämt under utveckling men ett säkerhetsmissbruk i produktion.
Secrets-hantering
Använd AWS Secrets Manager eller AWS Systems Manager Parameter Store (Standard tier är gratis upp till 10 000 parametrar). Hämta secrets vid funktionsstart, inte vid cold start-initiering, för att undvika extra latens.
VPC-överväganden
Om din Lambda behöver åtkomst till RDS eller ElastiCache i ett VPC:
- För AWS Lambda i VPC — förstå att detta introducerar ENI-attach-time, vilket kan öka cold starts med 5–10 sekunder
- Lösning: Använd VPC endpoints för tjänster som S3 och DynamoDB för att undvika NAT-gateway-avgifter och latens
- Bästa praxis: Placera endast Lambda-funktioner som kräver VPC-åtkomst i ett VPC. För funktioner som bara pratar med publika AWS-tjänster, kör utanför VPC för bättre prestanda.
Steg 6: Monitoring och observability
En migrerad serverlös arkitektur kräver ett nytt sätt att tänka på övervakning. Istället för att monitorera "denna server" monitorerar du "denna funktion under denna request".
Distributed tracing med AWS X-Ray
AWS X-Ray är integrerat med Lambda och ger dig request-traces över alla funktioner:
Aktivera X-Ray i Lambda-konfigurationen (lägger till ~0.5 MB till funktionsstorleken)
Lägg till X-Ray SDK i din kod för att annotera subsegments (t.ex. databas-anrop, externa API:er)
Använd AWS Distro for OpenTelemetry (ADOT) om du föredrar vendor-neutral instrumentation
Nyckelmetrics att övervaka
- Invocations — antal anrop, både successful och errors
- Duration — hur lång tid varje anrop tar, särskilt p95 och p99
- Throttles — antal gånger Lambda throttle:ade på grund av överskriden concurrency
- IteratorAge (för Event Source Mappings) — om du konsumerar från Kinesis eller DynamoDB Streams, övervaka detta för att upptäcka processing-lag
- Cost — med AWS Cost Anomaly Detection kan du få alerts om oväntade kostnadsökningar
Logging: CloudWatch vs. third-party
CloudWatch Logs fungerar, men vid högvolym-applikationer kan kostnaden överraska dig (~$0.50 per GB i EU). Alternativ:
- Fluent Bit — skicka logs till S3 + Athena för billigare lagring och sökbarhet
- Datadog eller Sumo Logic — om du redan investerat i en SIEM/logleverans-plattform
- Lumberyard — AWS egen open-source log-analysis engine
Kostnadsfallstudie: E-handelsplattform
Låt mig dela ett verkligt exempel från en migrering jag ledde 2023:
Före migrering:
- 4x r5.2xlarge EC2-instanser (16 vCPU, 64 GB RAM) = ~$1,200/månad
- RDS db.m5.2xlarge för databas = ~$400/månad
- Total: ~$1,600/månad fast cost
Efter migrering (delvis):
- 12 Lambda-funktioner för olika domäner
- DynamoDB med on-demand: ~$80/månad
- API Gateway: ~$20/månad + $1 per miljon API-anrop
- SQS: ~$10/månad
Vid 2 miljoner ma
nadliga API-anrop (trafik som matchade före-migrering-lasten):
- Lambda-kostnad: ~$150/månad (baserat på genomsnittlig execution-tid på 50 ms och 512 MB minne)
- Total: ~$260/månad
Resultat: 84 % kostnadsreduktion. Men här är varningen: under Black Friday ökade trafiken 15x. Lambda-kostnaden vid den toppen var $800 för den helgen — fortfarande lägre än vad fast infrastruktur hade kostat för motsvarande capacity, men högre än vanliga månader. Planera för traffic spikes i din kostnadsmodell.
Vanliga fallgropar och hur du undviker dem
Fallgrop 1: Synchronous alles
Att konvertera varje monolith-funktion till en synkron Lambda är frestande men leder till tight coupling och cascading failures. Använd asynkron kommunikation (SQS, SNS, EventBridge) där det är möjligt.
Fallgrop 2: Att ignorera Idempotency
Lambda kan köras flera gånger för samma request (t.ex. vid retry eller explicit batching). Ditt order-system måste hantera detta — använd idempotency keys (en UUID som klienten genererar och skickar med varje request).
Fallgrop 3: Att inte planera för failure
I en monolith kan en databas-timeout orsaka att en del av applikationen kraschar. I serverless sprids detta — en trasig Lambda påverkar inte en annan, men du behöver actively övervaka för att upptäcka det. Konfigurera CloudWatch Alarms på error rate och throttling.
Fallgrop 4: Över-använda Step Functions för enkla flows
AWS Step Functions är kraftfullt, men det lägger till latens och kostnad ($0.000025 per state transition). För enkla asynkrona uppgifter räcker ofta SQS + Lambda. Reservera Step Functions för complex workflows med branching, parallel execution, och human approval steps.
Slutsats: Är det värt det?
Att migrera en monolith till AWS Lambda är ett stort åtagande, men för rätt typ av applikation — de med varierande trafik, många oberoende domäner, och team som vill kunna deploya oberoende — är det en av de bästa investeringarna du kan göra i din molnarkitektur.
Tecken på att du bör migrera:
- Din trafik varierar med >10x mellan peak och off-peak
- Du har flera team som blockerar varandra vid releases
- Du betalar för servrar som mestadels står och gör ingenting
- Du vill fokusera på affärslogik istället för infrastructure
Tecken på att du kanske bör vänta:
- Du har steady-state-trafik 24/7
- Din team har starka kunskaper i Kubernetes och föredrar container-orkestrering
- Du har starka beroenden mellan moduler som skulle vara svåra att bryta ut
- Din organisation har nyligen investerat i en container-plattform och vill maximera ROI på den
Oavsett vilken väg du väljer, kom ihåg: molnarkitektur handlar inte om att använda den hetaste tekniken — det handlar om att bygga system som löser dina faktiska affärsproblem med acceptabel risk och kostnad. AWS Lambda är ett utmärkt verktyg i verktygslådan. Använd det där det gör mest nytta.
Vill du lära dig mer om molnarkitektur? Utforska våra guider om Kubernetes-migrering, FinOps-strategier, och molnsäkerhet på Ciro Cloud.
Weekly cloud insights — free
Practical guides on cloud costs, security and strategy. No spam, ever.
Comments