The Serverless Way

79d9ba388d6b6cf4ec7310cad9fa8c8a?s=47 Rob Allen
October 10, 2018

The Serverless Way

Serverless applications feel different and you need know why! In this talk I will look at how to design your application the serverless way.

The session will discuss how serverless applications embrace cloud services and live in a world where there are many separate parts, each responsible to for one thing. I'll cover the architectural patterns we use to design a serverless application including handling their stateless nature, how to use multiple functions for a task and leveraging event processing to trigger further functions. I will then turning my attention to showing you how to put these into practice by looking at how they can be implemented in an Apache OpenWhisk application.

By the end of the session, you'll be well placed to design and build your own serverless apps that take full advantage of the decentralised world they live in.

Presented at PHP Minds, 11 October 2018

79d9ba388d6b6cf4ec7310cad9fa8c8a?s=128

Rob Allen

October 10, 2018
Tweet

Transcript

  1. The Serverless Way Rob Allen October 2018

  2. Deployment options 1. Physical servers 2. Virtual machines 3. Containers

    Rob Allen ~ @akrabat
  3. Container deployments 1. Platform (e.g. Kubernetes) 2. Application (e.g. Cloud

    Foundry) 3. Serverless (e.g. OpenWhisk) Rob Allen ~ @akrabat
  4. Serverless? The first thing to know about serverless computing is

    that "serverless" is a pretty bad name to call it. - Brandon Butler, Network World Rob Allen ~ @akrabat
  5. AKA: Functions as a Service • Code • Deployed to

    the cloud • Executed in response to an event • On-demand scaling • Pay for execution, not when idle Rob Allen ~ @akrabat
  6. Use-cases Synchronous Service is invoked and provides immediate response (HTTP

    requests: APIs, chat bots) Rob Allen ~ @akrabat
  7. Use-cases Synchronous Service is invoked and provides immediate response (HTTP

    requests: APIs, chat bots) Asynchronous Push a message which drives an action later (web hooks, timed events, database changes) Rob Allen ~ @akrabat
  8. Use-cases Synchronous Service is invoked and provides immediate response (HTTP

    requests: APIs, chat bots) Asynchronous Push a message which drives an action later (web hooks, timed events, database changes) Streaming Continuous data flow to be processed Rob Allen ~ @akrabat
  9. Benefits • No need to think about servers • Concentrate

    on application code • Pay only for what you use, when you use it • Language agnostic: • NodeJS, Python, Swift, Go, Java, C#, PHP, Ruby, etc Rob Allen ~ @akrabat
  10. Challenges • Start up latency • Time limit • State

    is external • DevOps is still a thing Rob Allen ~ @akrabat
  11. It's about value Rob Allen ~ @akrabat

  12. When should you use serverless? • Occasional server needs on

    a static site • Variable traffic levels • Additional compute without extending current platform • Responding to web hooks • Any web app that you want to be cheaper to run! Rob Allen ~ @akrabat
  13. Serverless providers Rob Allen ~ @akrabat

  14. Hello World AWS Lambda: def my_handler(event, context): name = event.get("name",

    "World") message = 'Hello {}!'.format(name) return {'message': message} Rob Allen ~ @akrabat
  15. Hello World Apache OpenWhisk: def main(args): name = args.get("name", "World")

    message = 'Hello {}!'.format(name) return {'message': message} Rob Allen ~ @akrabat
  16. Hello World Google Cloud Functions def hello_http(request): name = request.json.get("name",

    "World") message = 'Hello {}!'.format(name) return message Rob Allen ~ @akrabat
  17. Hello World Azure Cloud Functions import azure.functions as func def

    main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> str: name = req.params.json.get("name", "World") message = 'Hello {}!'.format(name) msg.set(message) return message Rob Allen ~ @akrabat
  18. The anatomy of an action def main(args): # Marshall inputs

    from event parameters name = args.get("name", "World") # Do the work message = 'Hello {}!'.format(name) # return result return {'message': message} Rob Allen ~ @akrabat
  19. Creating your action $ wsk action create hello hello.py ok:

    updated action hello Rob Allen ~ @akrabat
  20. Running your action $ wsk action create hello hello.py ok:

    updated action hello $ wsk action invoke hello --result --param name Rob Rob Allen ~ @akrabat
  21. Running your action $ wsk action create hello hello.py ok:

    updated action hello $ wsk action invoke hello --result --param name Rob { "message": "Hello Rob!" } Rob Allen ~ @akrabat
  22. Access from the web API Gateway provides: • API routing

    • Rate limiting • Authentication • Custom domains Rob Allen ~ @akrabat
  23. API Gateway Rob Allen ~ @akrabat

  24. API Gateway $ wsk api create /myapp /hello GET hello

    Rob Allen ~ @akrabat
  25. API Gateway $ wsk api create /myapp /hello GET hello

    ok: created API /myapp/hello GET for action /_/hello Rob Allen ~ @akrabat
  26. API Gateway $ wsk api create /myapp /hello GET hello

    ok: created API /myapp/hello GET for action /_/hello $ curl https://example.com/myapp/hello?name=Rob Rob Allen ~ @akrabat
  27. API Gateway $ wsk api create /myapp /hello GET hello

    ok: created API /myapp/hello GET for action /_/hello $ curl https://example.com/myapp/hello?name=Rob { "message": "Hello Rob!" } Rob Allen ~ @akrabat
  28. Invoking a function Rob Allen ~ @akrabat

  29. Architecture Rob Allen ~ @akrabat

  30. Monolith architecture Rob Allen ~ @akrabat

  31. Serverless architecture Rob Allen ~ @akrabat

  32. Serverless architecture pattern Rob Allen ~ @akrabat

  33. Functions are key Rob Allen ~ @akrabat

  34. Functions are the Unit of Deployment Rob Allen ~ @akrabat

  35. Functions are the Unit of Scale Rob Allen ~ @akrabat

  36. Functions are Stateless Rob Allen ~ @akrabat

  37. Functions have Structure Rob Allen ~ @akrabat

  38. Structure If it's non-trivial, software engineering principles apply! • Use

    multiple methods Rob Allen ~ @akrabat
  39. Structure If it's non-trivial, software engineering principles apply! • Use

    multiple methods • Use multiple files Rob Allen ~ @akrabat
  40. Structure If it's non-trivial, software engineering principles apply! • Use

    multiple methods • Use multiple files • Integrate reusable dependencies Rob Allen ~ @akrabat
  41. Separation Separate the action handler from your business logic Rob

    Allen ~ @akrabat
  42. Separation Separate the action handler from your business logic Rob

    Allen ~ @akrabat
  43. Example from Adobe CIF-Magento function postCoupon(args) { const validator =

    new InputValidator(args, ERROR_TYPE) .checkArguments().mandatoryParameter('id') if (validator.error) { return validator.buildErrorResponse(); } const cart = new MagentoCart(args, cartMapper.mapCart, 'guest-carts'); return cart.byId(args.id).addCoupon(args.code).then(function () { return cart.byId(args.id).get(); }).catch(error => { return cart.handleError(error); }); } Rob Allen ~ @akrabat
  44. Example from Adobe CIF-Magento function postCoupon(args) { const validator =

    new InputValidator(args, ERROR_TYPE) .checkArguments().mandatoryParameter('id') if (validator.error) { return validator.buildErrorResponse(); } const cart = new MagentoCart(args, cartMapper.mapCart, 'guest-carts'); return cart.byId(args.id).addCoupon(args.code).then(function () { return cart.byId(args.id).get(); }).catch(error => { return cart.handleError(error); }); } Rob Allen ~ @akrabat
  45. Example from Adobe CIF-Magento function postCoupon(args) { const validator =

    new InputValidator(args, ERROR_TYPE) .checkArguments().mandatoryParameter('id') if (validator.error) { return validator.buildErrorResponse(); } const cart = new MagentoCart(args, cartMapper.mapCart, 'guest-carts'); return cart.byId(args.id).addCoupon(args.code).then(function () { return cart.byId(args.id).get(); }).catch(error => { return cart.handleError(error); }); } Rob Allen ~ @akrabat
  46. Example from Adobe CIF-Magento function postCoupon(args) { const validator =

    new InputValidator(args, ERROR_TYPE) .checkArguments().mandatoryParameter('id') if (validator.error) { return validator.buildErrorResponse(); } const cart = new MagentoCart(args, cartMapper.mapCart, 'guest-carts'); return cart.byId(args.id).addCoupon(args.code).then(function () { return cart.byId(args.id).get(); }).catch(error => { return cart.handleError(error); }); } Rob Allen ~ @akrabat
  47. Serverless state machines Rob Allen ~ @akrabat

  48. Serverless state machines Rob Allen ~ @akrabat

  49. Rob Allen ~ @akrabat

  50. OpenWhisk Composition composer.sequence( composer.if( 'binday/authenticate', composer.if( 'binday/validate', composer.if( 'binday/is_intent_setday', 'binday/set_bin_day',

    'binday/get_next_bin_day' ), 'binday/send_failure' ), 'binday/send_failure' ), 'binday/format_output_for_alexa' ) Rob Allen ~ @akrabat
  51. Tips & tricks • Make troubleshooting easier: • Ability to

    disable event triggers • Identifiers that run throughout functions for a single "operation" • Don't forget HTTP circuit breakers - retry with a back-off algorithm • Tune memory settings for each function - affects price (& performance) Rob Allen ~ @akrabat
  52. To sum up Rob Allen ~ @akrabat

  53. Thank you! Rob Allen ~ @akrabat