Deployment options
1. Physical servers
2. Virtual machines
3. Containers
Rob Allen ~ @akrabat
Slide 3
Slide 3 text
Container deployments
1. Platform (e.g. Kubernetes)
2. Application (e.g. Cloud Foundry)
3. Serverless (e.g. OpenWhisk)
Rob Allen ~ @akrabat
Slide 4
Slide 4 text
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
Slide 5
Slide 5 text
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
Slide 6
Slide 6 text
Use-cases
Synchronous
Service is invoked and provides immediate response
(HTTP requests: APIs, chat bots)
Rob Allen ~ @akrabat
Slide 7
Slide 7 text
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
Slide 8
Slide 8 text
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
Slide 9
Slide 9 text
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
Slide 10
Slide 10 text
Challenges
• Start up latency
• Time limit
• State is external
• DevOps is still a thing
Rob Allen ~ @akrabat
Slide 11
Slide 11 text
It's about value
Rob Allen ~ @akrabat
Slide 12
Slide 12 text
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
Slide 13
Slide 13 text
Serverless providers
Rob Allen ~ @akrabat
Slide 14
Slide 14 text
Hello World
AWS Lambda:
def my_handler(event, context):
name = event.get("name", "World")
message = 'Hello {}!'.format(name)
return {'message': message}
Rob Allen ~ @akrabat
Slide 15
Slide 15 text
Hello World
Apache OpenWhisk:
def main(args):
name = args.get("name", "World")
message = 'Hello {}!'.format(name)
return {'message': message}
Rob Allen ~ @akrabat
Slide 16
Slide 16 text
Hello World
Google Cloud Functions
def hello_http(request):
name = request.json.get("name", "World")
message = 'Hello {}!'.format(name)
return message
Rob Allen ~ @akrabat
Slide 17
Slide 17 text
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
Slide 18
Slide 18 text
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
Slide 19
Slide 19 text
Creating your action
$ wsk action create hello hello.py
ok: updated action hello
Rob Allen ~ @akrabat
Slide 20
Slide 20 text
Running your action
$ wsk action create hello hello.py
ok: updated action hello
$ wsk action invoke hello --result --param name Rob
Rob Allen ~ @akrabat
Slide 21
Slide 21 text
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
Slide 22
Slide 22 text
Access from the web
API Gateway provides:
• API routing
• Rate limiting
• Authentication
• Custom domains
Rob Allen ~ @akrabat
Slide 23
Slide 23 text
API Gateway
Rob Allen ~ @akrabat
Slide 24
Slide 24 text
API Gateway
$ wsk api create /myapp /hello GET hello
Rob Allen ~ @akrabat
Slide 25
Slide 25 text
API Gateway
$ wsk api create /myapp /hello GET hello
ok: created API /myapp/hello GET for action /_/hello
Rob Allen ~ @akrabat
Slide 26
Slide 26 text
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
Slide 27
Slide 27 text
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
Slide 28
Slide 28 text
Invoking a function
Rob Allen ~ @akrabat
Slide 29
Slide 29 text
Architecture
Rob Allen ~ @akrabat
Slide 30
Slide 30 text
Monolith architecture
Rob Allen ~ @akrabat
Slide 31
Slide 31 text
Serverless architecture
Rob Allen ~ @akrabat
Slide 32
Slide 32 text
Serverless architecture pattern
Rob Allen ~ @akrabat
Slide 33
Slide 33 text
Functions are
key
Rob Allen ~ @akrabat
Slide 34
Slide 34 text
Functions are the
Unit of Deployment
Rob Allen ~ @akrabat
Slide 35
Slide 35 text
Functions are the
Unit of Scale
Rob Allen ~ @akrabat
Slide 36
Slide 36 text
Functions are
Stateless
Rob Allen ~ @akrabat
Slide 37
Slide 37 text
Functions have
Structure
Rob Allen ~ @akrabat
Slide 38
Slide 38 text
Structure
If it's non-trivial, software engineering principles apply!
• Use multiple methods
Rob Allen ~ @akrabat
Slide 39
Slide 39 text
Structure
If it's non-trivial, software engineering principles apply!
• Use multiple methods
• Use multiple files
Rob Allen ~ @akrabat
Slide 40
Slide 40 text
Structure
If it's non-trivial, software engineering principles apply!
• Use multiple methods
• Use multiple files
• Integrate reusable dependencies
Rob Allen ~ @akrabat
Slide 41
Slide 41 text
Separation
Separate the action handler from your business logic
Rob Allen ~ @akrabat
Slide 42
Slide 42 text
Separation
Separate the action handler from your business logic
Rob Allen ~ @akrabat
Slide 43
Slide 43 text
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
Slide 44
Slide 44 text
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
Slide 45
Slide 45 text
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
Slide 46
Slide 46 text
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
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