Blogs

Building Event Driven Microservices at the Cloud or the Edge Using Dapr

By Chandrasekar Ganapathy posted 12-01-2022 12:00

  

Why distributed applications are difficult to build 

Microservice architecture is one of the best solutions for realizing distributed application architecture.  However, despite doing microservices for the past eight years, it is still complex to build due to the following reasons: 

  1. Service invocation is still different for different platforms. 
  2. State management is still not mature and stateless services do not solve enterprise problems.   
  3. Service-to-service communication using messaging, which is much more ubiquitous, varies based on the message broker’s adoption. 
  4. Observability within the services is still subject to the developer’s discretion for adoption and not a standard. While OpenTelemetry is laying out standards, it still needs to be adopted. 
  5. Integrating with different vendors using different SDKs/programming languages requires effort and is difficult to change once implemented

While service mesh platforms like Istio and Linkerd alleviate some of these concerns, they do it at the network level, and deal with networking concerns, and do not do much at the higher levels of abstraction. State management, integration, etc. are not a concern of service meshes.   

What if we could: 

  • Solve this problem through a platform that abstracted everything through a pluggable components architecture that simplified the plumbing with external platforms… 
  • Supporting popular development platforms through language specific SDKs… 
  • That also worked across different cloud providers at the cloud and the edge… 
  • Adhering to standard security communication protocols like HTTP/gRPC communications. 

 

Introducing Dapr, the Distributed Application Runtime  

Dapr, the Distributed Application Runtime, is an open source project maintained by Microsoft that provides a portable and event-driven runtime that addresses some of the keys concerns for building distributed microservices, such as: 

  1. Service invocation 
  2. State management 
  3. Pub/sub messaging 
  4. External resource bindings 
  5. Observability handling 
  6. Secret handling 
  7. Actor modelling 


These are treated as foundational, pluggable components that can work with external vendor platforms through configurations and dynamic binding.
 


What’s more, all of these are available for popular development languages such as SDKs across different cloud platforms.

 

Sample scenario

Let us illustrate the power of Dapr through a scenario. 

Say we want our application to manage state in a state store like Redis cache. In a normal scenario, we would write custom code that targets the Redis cache store for managing state using its SDK or library.  When we move from Redis cache to some other store (say it is necessary), we would need to change the code and then leverage the new SDK.

Using Dapr, our effort is minimal to none. As Dapr provides state management capabilities out-of-the-box and ships with several industry standard pre-built state store components, including Redis, our efforts are reduced from coding to merely configuring the target state store component and calling the Dapr state management building block API. With this, our service essentially delegates the state management to the Dapr runtime which has all the necessary code to wire to the target component and manage state without the service needing to use any of the Redis SDK library, or even direct reference to the underlying component. 

As Dapr supports several pre-built state stores, we can even change state stores from Redis to MySQL or Cassandra, with no code changes. 

Sounds like magic, eh?!

 

Dapr architecture

The secret sauce for Dapr magic is its building blocks, components, and how they get deployed.

 

Dapr building blocks

A Dapr building block is an HTTP or gRPC API representing a platform capability that can be called from the service code. The diagram below shows a view of the different building blocks and the table following provides the intent for each.





Dapr components

While building blocks provide the APIs to invoke the platform capability, the components provide the concrete implementation.

Components follow a pluggable architecture that support community driven vendor components out-of-box or as private components created by the practitioners for their needs.   To this extent, Dapr follows a pluggable architecture which allows customization. Currently there are over 100 components supported. This diagram provides few of them across the different categories.

 



Building blocks invoke Dapr components. The service code is only aware of the building block and has no dependencies on external SDKs or libraries. Dapr handles the plumbing of the building blocks to the components. Each building block is independent, and we can use one, some, or all of them in your application.



Dapr building blocks/components follow industry best practices including comprehensive observability following OpenTelemetry standards.

 

Dapr component specs
Each of the above components has a well-defined component spec to elicit the runtime on their usage. A sample component spec for Redis cache is provided below.



The above example uses secrets as plain text strings which is not the best practice. It is recommended to use the secret store for managing the secrets.  

 

Sidecar architecture

 

Dapr exposes its building blocks and components through a sidecar architecture as depicted below. A sidecar enables Dapr to run in a separate memory process alongside the service.

Sidecars provide isolation and encapsulation and aren’t part of the service, enabling each service to have its own runtime environment and be built on different programming platforms independent of sidecar.  

The sidecars expose the following APIs natively:

  • Building block APIs expose the platform capability.



  • Metadata API is for discoverability of the capability.
  • Health API is used for checking the health status of the sidecar using readiness and liveness approaches.

 

Hosting environments

Dapr has cross-platform support and can run in many different environments, including Kubernetes, VMs, or edge environments such as Azure IoT Edge.

Dapr can be hosted in self-hosted and container-hosted mode. A self-hosted mode involves deploying it into bare metal or VMs. In container-hosted mode, the orchestration is provided by a platform like Kubernetes. A sample deployment architecture is provided below.

Dapr requires Redis cache store and Zipkin as part of its platform for state management and telemetry. Also, any communication between the sidecars is always gRPC-based for maximum performance.

 

Security

Security is fundamental to Dapr; it provides the following to enforce security on its platform:

  1. Protect API endpoint using OAuth 2.0: Dapr leverages OAuth 2.0 flows for authoring access to APIs exposed. For any application that involves user interaction, it follows the Authorization Code grant flow with all the consent and for any Service to Service (S2S) calls, it uses the token-based authentication following the Client Credential grant flows.
  2. Encrypt communication between APIs using self-signed or x.509 certs: Dapr enables every communication within its transport layer encrypted using self-signed certificates or x.509 certificates issued by a CA.

 

Observability

Observability is natively built into Dapr runtime at both the control and the sidecar plane levels and these comply to industry standard practices like OpenTelemetry (OTEL) that can easily integrate with industry standard observability toolsets.

Following are some of the levels for observing the Dapr sidecar and control plane performance and health.

 

  1. Tracing: Dapr natively leverages Zipkin to provide distributed tracing at the calls level and to visualize call flows across services including pub/sub messaging subscriptions.
  2. Logs : Dapr generates logs of the sidecar operations, identifies, and categorizes issues for debugging, and leverages industry standard log collectors like Fluentd and Azure Monitor to forward them to log sinks for analytics and insights.
  3. Metrics: Provide deep insights on the behavior of the sidecar and the control plane. Metrics include:
  • APM aspects like application call latency, traffic failures, error rates of request, etc., at the sidecar level.
  • System level aspects like health of control plane, CPU usage, sidecar injection failures, etc., at the control plane level.

 

Resiliency

Dapr provides health checks and policies to configure retries, timeouts, and circuit breakers which constitute the resiliency of Dapr.

 

  1. Health Checks: Dapr sidecar, as seen earlier, exposes health check endpoints to check its readiness and liveness. Dapr can also be configured to probe the health of the application and react to changes in the app health, including stopping pub/sub subscriptions and short-circuiting service invocation calls.
  2. Policies: Policies are JSON specifications for resiliency configuration and include attributes like:
  • Timeouts
  • Retries
  • Circuit breaker

 

Every service within Dapr has a default specification which will be effective when not configured.

A sample circuit breaker policy is provided below.



Why Dapr?

To summarize why Dapr should be adopted:

 

  1. Dapr is the next best thing, if it gets universally adopted, it will have eliminated the need for developers to write platform code, and instead, focus on the business logic.
  2. Dapr will continue to embrace industry standard community platforms enabling better adoption and overall increased productivity.
  3. With a pluggable architecture, Dapr allows the practitioner to create new private services specific to their needs. Also, as the runtime runs independently of each building block, each dependency is smaller in footprint.
  4. Dapr will have enabled the dream of building multicloud apps with its adaptation to all cloud providers.
  5. Dapr is relatively new. The current version is 1.9.3 with the support available up to three previous versions.
  6. While it may be an opensource project, it has been maintained by Microsoft, and hence should be well adopted. All the other projects like .NET Core, VS Code, Typescript, Fluent UI, and PowerShell are well adopted in the industry.
  7. Dapr is fast despite the latency due to the sidecar as every communication between the sidecar proxies are always gRPC’d providing faster speeds.

Obviously, there are a lot of reasons to consider Dapr. Curious to hear your thoughts or experiences on the topic. Comment below and let me know.  


#ApplicationModernization
#CloudAdvisory
#CloudCostManagement
#CloudMigration
#CloudOperations
#CloudSecurity
0 comments
50 views

Permalink