Today, every one of us wants to get things done fast. The fact of the matter is Serverless is a fantastic platform for doing things fast. Because, with Serverless, you really don’t have time to waste in terms of delivering your business value. Turns out you can with the right cloud services. In this talk we’ll create a microservice using Azure Functions and also get introduced to bigger picture of serverless computing.
I presented this session in Global Azure Bootcamp 2019 in Dublin. #GlobalAzure #AzureFunctions #Serverless
2. About Me
• 15 years of Programming
• Use .NET to earn bread and butter
• Worked on very large scale systems in e-
Commerce , Banking and Insurance
• In spare time
• python, Go-Lang, OSS
• Loads of TED Talks
5. Independent modules Isolated points of failure
Autonomous scalability
Microservices
Tech flexibility
Faster value delivery
6. Serverless – Great fit for Microservices
• Problems of traditional microservices
• Scaling of compute resources
• Operations dependency
• Pay per hosting nodes
• Services discovery and
• managing services integration
• Serverless solution
• Automatic scaling based on workload
• No infrastructure management
• Pay per execution (micro-billing)
• Event-Driven programming model
• (triggers + bindings), instant scale
13. Functions Secret Sauce…
• Triggers are ways to start executing Azure function code
• Bindings are declarative way of binding data to Azure function
• All triggers have input data
• Data coming from services become input values for function code
• To output data to another service use the return value of the
function.
15. Scaling happens at the Function App level
Usually, each Function App
represents a different
microservice
Each Function App would
be an API with grouped
endpoints
(one function per endpoint)
Flexibility choosing the
language for each
microservice – one per
Function App
19. Migrate from VMs → serverless
Thermostat intelligence
is a clear differentiator
Ready for sudden vertical growth
in the consumer market—charged
for usage as they scale
20K+ IoT devices simulated
Event driven architecture works well for
IoT
Customer Success Story
GLAS®Smart Thermostat by Johnson Controls
20. Device to Cloud
Cloud to Device
IoT Hub for messaging
and managing devices
Event Hubs for routing
and throttling
Functions as
microservices
SignalR for device
messaging
25. What is Durable Functions?
• Advanced feature for writing long-running orchestrations as a single
C# function. No JSON schemas. No designer.
• New orchestrator functions can synchronously or asynchronously call
other functions.
• Automatic checkpointing, enabling “long running” functions.
• Solves a variety of complex, transactional coding problems in
serverless apps.
• Built on the open source Durable Task Framework.
27. Pattern #1: Function chaining - Today
Problems:
• No visualization to show relationship between functions and queues.
• Middle queues are an implementation detail – conceptual overhead.
• Error handling adds a lot more complexity.
F1 F2 F3 F4
28. Pattern #1: Function chaining - Better
// calls functions in sequence
public static async Task<object> Run(DurableOrchestrationContext ctx)
{
try
{
var x = await ctx.CallFunctionAsync("F1");
var y = await ctx.CallFunctionAsync("F2", x);
var z = await ctx.CallFunctionAsync("F3", y);
return await ctx.CallFunctionAsync("F4", z);
}
catch (Exception)
{
// global error handling/compensation goes here
}
}
29. Pattern #2: Fan-out/Fan-in - Today
Problems:
• Fanning-out is easy, but fanning-in is significantly more complicated
• Functions offers no help with this scenario today
• All the same problems of the previous pattern
F1
F2
F3
30. Pattern #2: Fan-out/Fan-in - Easy
public static async Task Run(DurableOrchestrationContext ctx)
{
var parallelTasks = new List<Task<int>>();
// get a list of N work items to process in parallel
object[] workBatch = await ctx.CallFunctionAsync<object[]>("F1");
for (int i = 0; i < workBatch.Length; i++)
{
Task<int> task = ctx.CallFunctionAsync<int>("F2", workBatch[i]);
parallelTasks.Add(task);
}
await Task.WhenAll(parallelTasks);
// aggregate all N outputs and send result to F3
int sum = parallelTasks.Sum(t => t.Result);
await ctx.CallFunctionAsync("F3", sum);
}
31. Pattern #3: HTTP Async Response
Problems:
• Execution state needs to be explicitly stored and managed.
• Execution state and trigger state must be kept in sync manually.
• Start and GetStatus is often boilerplate code that is not related to the business problem.
Start DoWork
GetStatus
33. Pattern #4: Actors
Problems:
• Functions are stateless and short-lived.
• Read/write access to external state needs to be carefully synchronized.
• Functions do not support the singleton pattern today.
34. Pattern #4: Actors (Eternal Orchestrations)
public static async Task Run(DurableOrchestrationContext ctx)
{
int counterState = ctx.GetInput<int>();
string operation = await ctx.WaitForExternalEvent<string>("operation");
if (operation == "incr")
{
counterState++;
}
else if (operation == "decr")
{
counterState--;
}
ctx.ContinueAsNew(counterState);
}
35. Pattern #5: Human Interaction w/Timeout
RequestApproval
Escalate
ProcessApproval
Problems:
• Can’t easily coordinate a timeout with an approval request notification.
• Need a mechanism to reliably cancel either the approval handling or the
timeout depending on the outcome.
37. Important Orchestrator Limitations
• Orchestrator code is replayed on every rehydration to restore all local
state (local variables, etc).
• Function calls are never replayed – the outputs are remembered.
• This requires the orchestrator code to be deterministic.
• Rule #1: Never write logic that depends on random numbers,
DateTime.Now, Guid.NewGuid(), etc.
• Rule #2: Never do I/O directly in the orchestrator function.
• Rule #3: Do not write infinite loops
• Rule #4: Use the built-in workarounds for rules #1, #2, and #3
38. Takeaways
• Serverless – Glue of Cloud
• Sub-Second Billing
• Instant Scaling
• Focus on your code – Let Azure do the heavy lifting for you.
CallFunctionAsync uses queues under the covers, thus they can be scaled out to multiple VMs.
Logic Apps and Microsoft Flow have built-in support for this pattern.
Note that specifics URL routes are subject to change (and have already changed since this deck was originally written).
Note that orchestrators are single-threaded, so there is no need to worry about concurrency. Orchestration instances are also implicitly singletons, so they only run on one VM at a time.
We will expose a mechanism for sending named events to an orchestrator from outside the orchestration context – e.g. REST API and/or output binding.