Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Serverless for mere mortals
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Nikolay Sverchkov
April 22, 2019
Programming
1.1k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Serverless for mere mortals
Nikolay Sverchkov
April 22, 2019
More Decks by Nikolay Sverchkov
See All by Nikolay Sverchkov
Authorization in the GraphQL era
ssnickolay
0
1.2k
Rails 6: ActiveRecord
ssnickolay
0
56
Serverless Is Ruby Future
ssnickolay
0
960
Anything new Rails 6?
ssnickolay
1
1.6k
Evolution of Rails application architecture: 14 years in production
ssnickolay
3
1.5k
A Healthy Monolith
ssnickolay
0
1.7k
Elixir. There and Back Again
ssnickolay
0
920
Other Decks in Programming
See All in Programming
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
110
Kotlinの15年とServer-Side Kotlin
n_takehata
1
170
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
160
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
170
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
210
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.5k
Jetpack Compose Mechanisms
skydoves
3
870
AI-Powered Domain-Driven Design
ziobrando
0
310
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
210
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
150
残高管理から台帳サービスへの進化
artoy
1
210
Simple Storage Service(S3) is not simple
iwatsukayura
0
330
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
516
110k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
280
ラッコキーワード サービス紹介資料
rakko
4
5.5M
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3.1k
Making the Leap to Tech Lead
cromwellryan
135
10k
The Curse of the Amulet
leimatthew05
3
16k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
500
What does AI have to do with Human Rights?
axbom
PRO
1
2.5k
Accessibility Awareness
sabderemane
1
260
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
480
Transcript
SERVERLESS FOR MERE MORTALS NIKOLAY SVERCHKOV @ssnickolay
None
evilmartians.com
None
SERVERLESS FOR MERE MORTALS
OR
HOW I REDUCED COSTS BY 250 TIMES USING SERVERLESS
PAST
IN-HOUSE SERVER A LONG TIME AGO
A LONG TIME AGO MAINTAINABILITY IN-HOUSE SERVER
DEDICATED SERVER NOT SO LONG AGO ovh.com
DEDICATED SERVER NOT SO LONG AGO SCALABILITY
CLOUDS NOT SO LONG AGO
CLOUDS NOT SO LONG AGO
CLOUDS NOT SO LONG AGO
CLOUDS NOT SO LONG AGO ? CPU ? RAM ?
DISK
http://bit.ly/2X9qnp5
None
?
KANYE WEST
None
~66.500 RUB
LOAD 0 25 50 75 100 0 1 2 3
4 5 6 7
LOAD 0 25 50 75 100 0 1 2 3
4 5 6 7
CAPACITY PLANNING
None
CLOUDS NOT SO LONG AGO CAPACITY PLANNING
MORE ABSTRACTION! move away from server assessment models
None
2014
HOW IT WORKS
; ; ; AWS Lambda 1. SLEEP SOURCE_CODE.ZIP S3
AWS Lambda 1. SLEEP 2. EVENT
AWS Lambda 1. SLEEP 2. EVENT 3. HANDLE
function(event, context) { console.log(event.key1); return “Success”; }
AWS Lambda 1. SLEEP 2. EVENT 3. HANDLE 4. RESPONSE
; ; ; AWS Lambda 1. SLEEP 2. EVENT 3.
HANDLE 4. RESPONSE 5. -> 1
HTTP ❤ EVENT
BLOG + STATIC PAGES RAILS 3; DO; NGINX ASSETS PIPELINE
User Lambda Markdown -> HTML
User S3 Lambda Assets Markdown -> HTML CloudFront
User S3 Lambda Assets Markdown -> HTML + CloudFront
NOTE 1: THE RIGHT SOLUTION (JAMstack) +
NOTE 2: CAUTION OPEN FLAME
NOTE 2: CAUTION OPEN FLAME
CAUTION OPEN FLAME
⏱ DEC 2018 % +
DEC 2018 MARCH 2019 % +
VS http://bit.ly/2Dd7R7X
SERVERLESS
SERVERLESS $ serverless create !--template aws-go !!==> serverless.yml
SERVERLESS $ serverless deploy $ serverless rollback !--timestamp timestamp $
serverless invoke -f functionName $ serverless logs -f functionName $ serverless create !--template aws-go !!==> serverless.yml
SERVERLESS $ serverless deploy $ serverless rollback !--timestamp timestamp $
serverless invoke -f functionName $ serverless logs -f functionName $ serverless ???? $ serverless create !--template aws-go !!==> serverless.yml
SAM(-CLI) https://github.com/lambci/docker-lambda Docker images and test runners that replicate the
live AWS Lambda environment
TEMPLATES https://github.com/serverless/examples
serverless.yml functions: post: !<<: *default handler: bin/post events: - http:
path: blog/{slug} method: get
post.go package main import ( "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func Handler(ctx
context.Context, request Request) (events.APIGatewayProxyResponse, error) { !// put code here } func main() { lambda.Start(Handler) }
post.go func Handler(_, request Request) (_, _) { var buf
bytes.Buffer var slug = request.PathParameters["slug"] … }
post.go func Handler(_, request Request) (_, _) { var buf
bytes.Buffer var slug = request.PathParameters["slug"] post !:= lib.NewPost(slug, lambdaF.Config) if err !:= post.Render(&buf, lambdaF.Renderer); err !!= nil { return events.APIGatewayProxyResponse{StatusCode: 404}, err } … }
post.go func Handler(_, request Request) (_, _) { var buf
bytes.Buffer var slug = request.PathParameters["slug"] post !:= lib.NewPost(slug, lambdaF.Config) if err !:= post.Render(&buf, lambdaF.Renderer); err !!= nil { return events.APIGatewayProxyResponse{StatusCode: 404}, err } return lambdaF.Render(&buf) }
REDUCED x250 0.02$ vs 5$
+VAT = 6$!!! REDUCED x300
SERVERLESS UNDER THE MICROSCOPE
LOG $ serverless invoke -f index -l
LOG $ serverless invoke -f index -l START RequestId: <UUID>
Version: $LATEST END RequestId: <UUID> REPORT RequestId: <UUID> Duration: 1.48 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 31 MB
LOG $ serverless invoke -f index -l START RequestId: <UUID>
Version: $LATEST END RequestId: <UUID> REPORT RequestId: <UUID> Duration: 1.48 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 31 MB
LOG $ serverless invoke -f index -l START RequestId: <UUID>
Version: $LATEST END RequestId: <UUID> REPORT RequestId: <UUID> Duration: 1.48 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 31 MB
WHAT ABOUT CPU?
AWS Lambda allocates CPU power proportional to the memory… (с)
Amazon Docs
AWS Lambda allocates CPU power proportional to the memory… For
example, if you allocate 256 MB memory, your Lambda function will receive twice the CPU share than if you allocated only 128 MB. (с) Amazon Docs
https://aws.amazon.com/lambda/pricing/
6$ / PRICE(100ms) = 28.8M!
MEMORY / CST http://bit.ly/2UZ7xDL Completely Fair Scheduler (CFS)
FREE!
CST https://amzn.to/2Ix2t2O
COST !!<=> LANGUAGE
$ wrk -t10 -c400 -d20s -R40000 http://endpoint.url http://github.com/ssnickolay/dump2019
$ wrk -t10 -c400 -d20s -R40000 $ curl http://endpoint.url/[ruby/go] !=>
{“success”: true} http://github.com/ssnickolay/dump2019
0 250 500 750 1000 0 1 2 4 5
MAX AVG AVG ~80ms BATTLE (128 MB)
0 250 500 750 1000 0 1 2 4 5
MAX AVG AVG ~80ms 31712 requests in 20.01s Requests/sec: 1584.83 BATTLE (128 MB)
0 250 500 750 1000 0 1 2 4 5
0 250 500 750 1000 0 1 2 4 5 MAX AVG AVG ~1.8ms AVG ~80ms 31712 requests in 20.01s Requests/sec: 1584.83 50347 requests in 20.00s Requests/sec: 2517.30 BATTLE (128 MB)
0 250 500 750 1000 0 1 2 4 5
0 250 500 750 1000 0 1 2 4 5 MAX AVG AVG ~1.8ms AVG ~80ms 31712 requests in 20.01s Requests/sec: 1584.83 50347 requests in 20.00s Requests/sec: 2517.30 W IN BATTLE (128 MB)
0 250 500 750 1000 0 1 2 4 5
0 250 500 750 1000 0 1 2 4 5 MAX AVG AVG ~1.8ms AVG ~80ms 31712 requests in 20.01s Requests/sec: 1584.83 50347 requests in 20.00s Requests/sec: 2517.30 W IN + BATTLE (128 MB)
0 250 500 750 1000 0 1 2 4 5
0 250 500 750 1000 0 1 2 4 5 MAX AVG AVG ~1.8ms AVG ~80ms 31712 requests in 20.01s Requests/sec: 1584.83 50347 requests in 20.00s Requests/sec: 2517.30 BATTLE (128 MB)
BATTLE (128 MB) AVG ~1.8ms AVG ~80ms “Billed Duration: 100
ms” (c) Lambda Log
COST !!<=> PACKAGE SIZE
5.4MB 140KB COST !!<=> PACKAGE SIZE MIN SIZE
Go + WRK2 Milliseconds (AVG) 1,7 1,775 1,85 1,925 2
Megabytes 6 25 150 220
5.4MB 140KB COST !!<=> PACKAGE SIZE
http://rubyonjets.com/
COST !!<=> DEPENDENCIES
MINIMIZE THE COMPLEXITY OF YOUR DEPENDENCIES
MINIMIZE THE COMPLEXITY OF YOUR DEPENDENCIES
MINIMIZE THE COMPLEXITY OF YOUR DEPENDENCIES
WAIT A MINUTE
https://stackoverflow.com/q/54110697
When you write your Lambda function code, do not assume
that AWS Lambda automatically reuses the execution context for subsequent function invocations…. (c) AWS Docs AWS LAMBDA EXECUTION CONTEXT
func Fibonacci(n uint) uint { if n !<= 1 {
return n } return Fibonacci(n-1) + Fibonacci(n-2) } OPTION 1
func Fibonacci(n uint) uint { if n !<= 1 {
return n } return Fibonacci(n-1) + Fibonacci(n-2) } func main() { lambda.Start(Handler) } OPTION 1
func Fibonacci(n uint) uint { if n !<= 1 {
return n } return Fibonacci(n-1) + Fibonacci(n-2) } !// Handler is our lambda handler invoked by !// the `lambda.Start` function call func Handler(ctx context.Context) (Response, error) { Fib !:= Fibonacci(33) !// noise here resp !:= Response{ Body: Fib } … } func main() { lambda.Start(Handler) } OPTION 1
Milliseconds (AVG) 0 250 500 750 1000 1 2 3
4 Golang (128MB + Fib) ~ 400ms Option1
var Fib uint func Fibonacci(n uint) uint {…} func Handler(ctx
context.Context) (Response, error) { … } func init() { Fib = Fibonacci(33) !// noise here } func main() {…} OPTION 2
Milliseconds (AVG) 0 250 500 750 1000 1 2 3
4 Golang (128MB + Fib) ~ 400ms Option1 Option2
COST SPEED ⏫
0 15000 30000 45000 60000 0 1 2 4 5
50347 requests in 20.00s Requests/sec: 2517.30 LOAD !!<=> $$$
0 15000 30000 45000 60000 0 1 2 4 5
50347 requests in 20.00s Requests/sec: 2517.30 PROTECTION 1: X-API-KEY
0 15000 30000 45000 60000 0 1 2 4 5
PROTECTION 2: AWS SHIELD 50347 requests in 20.00s Requests/sec: 2517.30
0 15000 30000 45000 60000 0 1 2 4 5
50347 requests in 20.00s Requests/sec: 2517.30 62808 requests in 20.01s Non-2xx or 3xx responses: 62127 1 1000 CONCURRENCY PROTECTION 3: THROTTLING
PREDICTABLY
PREDICTABLY
PREDICTABLY
RECIPE
1. TAKE SERVERLESS
1. TAKE SERVERLESS 2. FOLLOW RULES
1. TAKE SERVERLESS 2. FOLLOW RULES 3. ????
1. TAKE SERVERLESS 2. FOLLOW RULES 3. ???? 4. PROFIT
WHAT ABOUT PRODUCTION?
WHAT ABOUT PRODUCTION? Tung Nguyen
@ssnickolay Nikolay Sverchkov @ssnickolay THANK YOU! @evilmartians http://evl.ms/blog http://evl.ms/telegram