In this long read we take a look at Dapr, a new, enticing and highly portable event-driven runtime to simplify building resilient and scalable microservices for cloud and edge applications. This long read is sampled from Davide Bedin’s book Practical Microservices with Dapr and .NET.
Over the last decade, there has been a huge shift away from heavily coded monolithic applications to finer, self-contained microservices. Dapr – short for Distributed Application Runtime – is a new, open source project by Microsoft that provides an event-driven runtime to support the essential features you need to build microservices, including service invocation, state management, and publish/subscribe messaging. It offers platform-agnostic features for running your applications on public cloud, on-premises, and even on edge devices.
Here we outline the core concepts of Dapr’s architecture, to help you understand what it is and why it’s such an exciting technology.
Event-driven processes play an important role in microservices, as applications can be designed to react efficiently to events from external systems or other parts of the solution. Those applications can also produce events, to inform other services of new facts or to continue processing elsewhere or at a later stage.
Microservices offer a vast array of benefits, but these are balanced by increased complexities in team and product management. Usually a significant burden is placed on the developer and the team in order to get started.
What if you could leverage a runtime to help you get through the common patterns you will likely need to adopt and ease your operations? With Dapr you can!
Still in development, Dapr builds on the experience gained by Microsoft of developing hyper-scale cloud-native applications. It has been inspired by the design of Orleans and Service Fabric, which in turn enable many Microsoft Azure cloud services to operate resiliently and at large scale.
Dapr’s architectural building blocks
Dapr’s architectural building blocks
Dapr is portable: it can run locally on your dev machine in self-hosted mode, it can be deployed to the edge, and it can run on Kubernetes. Moreover, portability extends beyond the hosting environment, for while Dapr is an initiative started by Microsoft, it can also run on Kubernetes on-premise or in the cloud: Microsoft Azure, Amazon AWS, Google GCP, or any other cloud vendor.
As shown above, the Dapr runtime operates in sidecar processes, lifting most of the complexity from the application to a separate environment and greatly simplifying development and operations. These sidecar processes are run locally in your development environment or as containers in a pod on Kubernetes.
It is not necessary to adopt the Dapr SDK in your application: a call to a Dapr service can be as simple as an http call to an endpoint such as http://localhost:3500/v1.0/invoke//method/. Nevertheless, using the SDK provides many benefits if you are writing a Dapr Service or leveraging the Dapr Actor model.
What Dapr is not
To appreciate what Dapr is, it can be helpful to think about what Dapr is not.
Dapr’s goal is not to force the developer to embrace a programming model with strict rules and constraints. On the contrary, while the application developer is freed by Dapr of the many complexities of a microservice architecture, the developer is not mandated on how to write the application.
Dapr is not a service mesh. While many similarities can be found in the general objectives of Dapr and service meshes, Dapr provides these benefits at the application level while service mesh operates on the infrastructure. For instance, Dapr applies a retry logic in its interaction with state stores and services, but it is the developer’s responsibility to decide how to handle the error Dapr might return in case there is a conflict or an intermittent issue. (Dapr is meant to be integrated with, service meshes such as Istio.)
Note: Dapr provides the same benefits to Python (for example) developers as it does to .NET Core developers, providing SDKs for Dapr and Dapr Actor, working on MacOS and with Kubernetes as the deployment target.
Dapr building blocks
Dapr has been designed from the ground up as a set of pluggable building blocks: developers can create an application counting on the support of many facilities while the operators can adapt the applications to the hosting environment by simply intervening in the configuration.
The following is a complete list of the tools and components of Dapr:
- Dapr CLI: Cross-platform command line tool to configure, manage and monitor the Dapr environment. It is also the tool to locally debug Dapr applications
- Dapr API: The API which defines how an application can interact with the Dapr runtime in order to leverage its building blocks
- Dapr runtime: This is the core of Dapr, which implements the API. If you are curious you can take a look at how it is developed in Go at Dapr’s repository https://github.com/dapr/dapr.
- Dapr host: On your development machine the host runs as a standalone process; in Kubernetes it is a sidecar container in your application’s pod.
- Dapr operator: Specific to Kubernetes mode, the operator manages bindings and configurations.
- Dapr sidecar injector: Once instructed via configuration in Kubernetes mode, it takes care of injecting the Dapr sidecar into your application pod.
- Dapr placement service: This service has the objective to distribute (or to place) the Actor instances across the Dapr pods.
- Dapr Sentry: A built-in certificate authority to issue and manage certificates used by Dapr to provide transparent mTLS.
Dapr provides several building blocks which microservice application developers can adopt selectively, based on their need.
- Service Invocation: TService-to-service invocation enables your code to call other services located in the same hosting environment, while taking care of the retry policy.
- State Management: This is to efficiently manage the application state as a simple key/value pair, relieving your stateful or stateless services from the need to support different backends. Dapr provides many state stores which include Redis, Azure CosmosDB, Azure SQL Server, PostgreSQL which can be plugged via configuration.
- Publish and Subscribe Messaging: The publish/subscribe pattern enables decoupled communication between microservices by exchanging messages, counting on the presence of a service bus which can route messages between producers and consumers.
- Resource Bindings: This is where the event-driven nature of Dapr shines: with bindings your application can be triggered by an SMS sent via Twilio (just to name a popular service in this area).
- Actors: The actor pattern aims to simplify highly concurrent scenarios by splitting the overall requests load towards a large number of computation units (the actors) which take care of the job in their smaller but independent scope, by processing requests to a single actor one at a time. Here Dapr provides great benefits.
- Observability: Dapr enables the developer and operator to observe the behavior of the systems services and applications without having to instrument them.
- Secrets:: It is a common requirement and a healthy practice to keep secrets at safe distance from the code, if only to prevent unintended access in a development environment to the connection string intended for the production environment. Dapr enables you to store secrets, and to reference these from other Dapr components, in Kubernetes or Azure KeyVault, among many options.
Dapr facilitates the development of microservice-based applications by providing support for key application features. It offers developers an approach to the design of microservices applications, the means to build them, and the runtime to operate them. The modular architecture of components and building blocks, and the sidecar approach, make implementing necessary microservices functionality far more straightforward. That Dapr does all this in a platform-agnostic way is the icing on the cake.
Use the new, enticing and highly portable event-driven runtime to simplify building resilient and scalable microservices for cloud and edge applications
○ Build resilient, stateless, and stateful microservice applications that run on the cloud and edge
○Solve common distributed systems such as low latency and scaling using any language and framework
○ Use real-time and proactive monitoring tools to support a reliable and highly available system
Create a robust microservices infrastructure using Kubernetes, and learn how to communicate with your microservices.
○ Create a robust microservices infrastructure using Kubernetes, and learn how to communicate with your microservices
○ Understand all of the different resources that make up ‘Kubernetes’
○ Learn what CI and CD are, what the differences are, and ways to implement them successfully