Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Serverless for mere mortals

Serverless for mere mortals

Nikolay Sverchkov

April 22, 2019
Tweet

More Decks by Nikolay Sverchkov

Other Decks in Programming

Transcript

  1. OR

  2. ?

  3. ; ; ; AWS Lambda 1. SLEEP 2. EVENT 3.

    HANDLE 4. RESPONSE 5. -> 1
  4. SERVERLESS $ serverless deploy $ serverless rollback !--timestamp timestamp $

    serverless invoke -f functionName $ serverless logs -f functionName $ serverless create !--template aws-go !!==> serverless.yml
  5. SERVERLESS $ serverless deploy $ serverless rollback !--timestamp timestamp $

    serverless invoke -f functionName $ serverless logs -f functionName $ serverless ???? $ serverless create !--template aws-go !!==> serverless.yml
  6. 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) }
  7. post.go func Handler(_, request Request) (_, _) { var buf

    bytes.Buffer var slug = request.PathParameters["slug"] … }
  8. 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 } … }
  9. 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) }
  10. 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
  11. 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
  12. 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
  13. 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
  14. $ wrk -t10 -c400 -d20s -R40000 $ curl http://endpoint.url/[ruby/go] !=>

    {“success”: true} http://github.com/ssnickolay/dump2019
  15. 0 250 500 750 1000 0 1 2 4 5

    MAX AVG AVG ~80ms BATTLE (128 MB)
  16. 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)
  17. 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)
  18. 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)
  19. 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)
  20. 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)
  21. 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
  22. func Fibonacci(n uint) uint { if n !<= 1 {

    return n } return Fibonacci(n-1) + Fibonacci(n-2) } OPTION 1
  23. func Fibonacci(n uint) uint { if n !<= 1 {

    return n } return Fibonacci(n-1) + Fibonacci(n-2) } func main() { lambda.Start(Handler) } OPTION 1
  24. 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
  25. Milliseconds (AVG) 0 250 500 750 1000 1 2 3

    4 Golang (128MB + Fib) ~ 400ms Option1
  26. 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
  27. Milliseconds (AVG) 0 250 500 750 1000 1 2 3

    4 Golang (128MB + Fib) ~ 400ms Option1 Option2
  28. 0 15000 30000 45000 60000 0 1 2 4 5

    50347 requests in 20.00s Requests/sec: 2517.30 LOAD !!<=> $$$
  29. 0 15000 30000 45000 60000 0 1 2 4 5

    50347 requests in 20.00s Requests/sec: 2517.30 PROTECTION 1: X-API-KEY
  30. 0 15000 30000 45000 60000 0 1 2 4 5

    PROTECTION 2: AWS SHIELD 50347 requests in 20.00s Requests/sec: 2517.30
  31. 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