How much do you know about Dapr | Distributed runtime

Intro

The official Dapr team has recently officially released Dapr v1.0 (2021.1.17) . Dapr has been officially available for production and can be deployed to a self-hosted environment or Kubernetes cluster. For the vast majority of developers, they must have only heard about Dapr, but I don't know what it is (What), what kind of problem (Why&How) can be solved (Why&How), and what application scenarios (Where) are there. This article will try to briefly sort out Dapr and try to answer the above questions.

What's Dapr

Distributed Application Runtime. An event-driven, portable runtime for building microservices on cloud and edge
. An event-driven, portable runtime is used to build microservices on the cloud and edge computing.

The above is an introduction to Dapr on Dapr's official GitHub repository . The text is short, but the tone is big, because it not only covers all current technology hotspots: distributed, cloud, and microservices, but also advertises itself as: distributed application runtime . We are more or less aware of distributed applications, and we have heard a lot of runtimes, such as common language runtimes: Java runtime, .NET runtime, Go runtime, etc. What is runtime? In short: runtime is the execution environment on which the program runs. Take the .NET program runtime CLR as an example. It provides a managed code execution environment for .NET applications. It is responsible for the memory management, thread management, security management, remote management, even compilation, etc. of the application during the entire execution period.

The distributed application runtime is to provide the execution environment on which the distributed application runs. What environment dependencies do you need to run distributed applications? To answer this question, we must first think about the challenges of developing distributed applications? If the challenge is clear, the answer will be found.

From stand-alone to distributed, it is the pursuit of faster and higher performance, but it also brings more uncertainty. For example, you are not sure when the computer is abnormal, when the disk is damaged, you are not sure about the delay of network communication, and you are not sure whether the message is consumed normally. These uncertainties constitute a challenge for distributed applications, in short:

  1. Heterogeneous machines and networks: stability issues
  2. Common node failures: reliability issues
  3. Unreliable networks: consistency issues

Facing these challenges, the industry has proposed many distributed theories and protocols, such as CAP theorem, BASE theory, and consistency protocol 2PC/3PC/ZAB to ensure the normal operation of the system. Although the problem seems to have a solution, the complexity of the application has increased. In addition to fulfilling business requirements, applications must also take into account non-business requirements. It integrates the core functions of distributed systems such as service discovery, load balancing, failover, dynamic expansion, data slicing, and call link monitoring, which is very powerful for applications. Intrusiveness , this is a common practice in the microservice framework represented by Spring Cloud.

How to solve intrusive problems? This problem has a new solution as the container orchestration technology matures. Kubernetes can solve problems at the container layer without intruding into the application layer. For example, K8S Service has the capabilities of service discovery and load balancing, and HPA has the ability to dynamically expand. With the rapid development of K8S, the concept of cloud native has become more and more popular. How to make good use of the base capabilities provided by K8S to sink more distributed capabilities and return application development to business? Among them, the Sidecar mode proposed by Service Mesh solves the problem of network communication in the microservice architecture . Sidecar is mainly used to deal with a series of non-business requirements such as service discovery, load balancing, request fusing, etc. The application dynamically inserts Sidecar during deployment, and the communication between services is proxied through Sidecar to complete the takeover of network communication between services.

At this point, with the help of Service Mesh, microservice development has gradually returned to the business itself, allowing more developers to see a glimmer of light. It's enough? Let's take a look at the four major requirements of distributed applications mentioned in the Multi-Runtime Microservices Architecture article by Bilgin Ibryam :

Four major needs of distributed applications

 

As can be seen from the above figure, in addition to Networking, Lifecycle, State, and Binding are also one of the problems to be solved by distributed applications. Network problems can be solved by Service Mesh such as Istio. How to solve the other three? Do you want to apply self-developed integration again? Obviously it does not meet the requirements of the application to return to the business itself. At this time, Dapr comes on the scene. The distributed application runtime proposed by Dapr fulfills the above four requirements and sinks it as the operating environment of distributed applications.

In short: Dapr encapsulates and sinks distributed capabilities as a runtime to simplify the technical complexity of distributed application development.

How Dapr Works

So how does Dapr simplify the development of distributed applications? Let's take a look at the main features of Dapr.

Any language, any framework, anywhere

 

A picture is worth a thousand words: Dapr exposes encapsulated distributed capability application calls in a language-independent manner such as HTTP/gRPC API, thereby supporting development and integration in any language or framework. Currently, SDKs for Go, Node, Python, .NET, Java, C++, PHP, Rust, and Javascript have been officially provided to simplify the integration of Dapr.

Among them, Dapr's core building block (Building Block) is used to provide a variety of different distributed capabilities, let's take a look at them separately.

Building Block

 1. Service-to-service invocation (service invocation)
refers to cross-service method invocation, which everyone will definitely think, this is simple, it's just that the service exposes the API. Yes, but not exactly. For example, nodeapp exposes an API: http://10.0.0.2:8000/neworderIn the traditional way, direct HTTP POST API access is enough, but in Dapr, it provides an interface specification for method calls between services, which need to
POST/GET/PUT/DELETE http://localhost:<daprPort>/v1.0/invoke/<appId>/method/<method-name>be accessed in accordance with the format. Assuming that pythonapp needs to access the method of nodeapp, it needs to POST a request to it http://localhost:3500/v1.0/invoke/nodeapp/method/neworder. You may be wondering why this is unnecessary? What is the significance of this move? The purpose is very simple, it is to realize the control of network communication between services to complete services such as service discovery, flow control, retry fuse, secure access, etc., and the related network control functions are integrated in Dapr's Sidecar to be transparent to applications Integrated in the way. The overall service invocation process is shown in the following figure:

Inter-service call

 

PS: If you are familiar with Istio, you need to pay attention that although both are controlled by the Sidecar network, there is a difference between the two. Dapr is in API mode, and Istio is in proxy mode (without changing the HTTP request URI).

2. State management (state management) in the
development of microservices, the topic that cannot be avoided is the problem of state sharing and concurrency consistency between services. For state sharing, you might say that it is OK for each service to connect to the same Redis instance. Yes, but we have to consider the issue of potential update conflicts. Dapr uses a more friendly HTTP API to store and read the state, and supports concurrency control through ETags, and supports setting concurrency and consistency behavior through options.

  • storage:POST http://localhost:<daprPort>/v1.0/state/<storename>
  • Read:GET http://localhost:<daprPort>/v1.0/state/<storename>/<key>
  • delete:DELETE http://localhost:<daprPort>/v1.0/state/<storename>/<key>

The following is an example of saving state:

  • concurrencyUsed to specify concurrency options: first-write-wins/last-write-wins (subject to the first write/last write), the default is the last write.
  • consistencyUsed to specify consistency options: strong/eventual (strong consistency/eventual consistency), the default is eventual consistency.
curl -X POST http://localhost:3500/v1.0/state/starwars \
  -H "Content-Type: application/json" \
  -d '[
        {
          "key": "weapon",
          "value": "DeathStar",
          "etag": "xxxxx",
          "options": {
            "concurrency": "first-write",
            "consistency": "strong"
          }
        }
      ]'

Currently, Azure CosmosDB, Azure SQL Server, PostgreSQL, AWS DynamoDB, Redis are supported as state storage media.

3. Publish and subscribe (message publishing and subscription)
publish and subscribe model, which is a cliché, mainly used for microservices to communicate with each other based on messages. You may also say that this should also be mentioned, I will just build RabbitMQ/RocketMQ. Yes, but I still want to say that Dapr provides a consistent message publishing and subscribing API without having to pay attention to which Message Broker is used, thereby decoupling it from the underlying infrastructure.

  • release:POST http://localhost:<daprPort>/v1.0/publish/<pubsubname>/<topic>[?<metadata>]
  • Get subscribeable topics:GET http://localhost:<appPort>/dapr/subscribe
  • subscription:POST http://localhost:<appPort>/<path>

Publish and subscribe

 

4. Resource bindings and triggers (Resource bindings and event triggers)
Dapr's Bindings are very similar to Azure Functions, which are built on the basis of an event-driven architecture. By establishing the binding of triggers and resources, events can be received and sent from any external source (such as databases, queues, file systems, etc.) without resorting to message queues to achieve flexible business scenarios. Dapr's Bindings are divided into two types:

  1. Input Bindings: When an event from an external resource occurs, with the help of input binding, your application can POST http://localhost:<appPort>/<name>receive an event from an external resource through a specific API: it can be used to process specific logic.
  2. Output Bindings: Output bindings allow you to call external resources. For example, in an order processing scenario, after the order is successfully created, the order information can be POST/PUT http://localhost:<daprPort>/v1.0/bindings/<name>output to a specific Kafka queue through Dapr's binding API .

Resource binding and event triggering

 

5.
The Actor model in Actors Dapr has been passed down in the same vein as Orleans' Virtual Actor. I wrote an article about Orleans | .NET Core distributed framework . Simply put: Actor model = state + behavior + message. An application/service is composed of multiple Actors. Each Actor is an independent operating unit with an isolated operating space. In the isolated space, it has independent states and behaviors without external intervention. Actors pass through Messages are exchanged, and at the same time, each Actor can only be executed by a single thread, which not only effectively avoids data sharing and concurrency problems, but also ensures the scalability of the application.

The Actor model greatly simplifies the complexity of concurrent programming. Dapr provides many functions in the Actor runtime, including concurrency control, state management, life cycle management such as activation/deactivation of Actors and Timer (timer) used to wake up Actors And Reminder. These functions are also provided through API .

  • Call the Actor method:POST/GET/PUT/DELETE http://localhost:3500/v1.0/actors/<actorType>/<actorId>/method/<method>
  • Create Timer:POST/PUT http://localhost:3500/v1.0/actors/<actorType>/<actorId>/timers/<name>
  • Create Reminder:POST/PUT http://localhost:3500/v1.0/actors/<actorType>/<actorId>/reminders/<name>

6. Observability (telemetry)
Dapr records indicators, logs, links to debug and monitor the running status of Dapr and user applications. Dapr supports distributed tracing. It uses W3C tracing context standards and open telemetry technology to easily diagnose network calls between services in the production environment and send them to different monitoring tools, such as Prometheus.

7. Secrets (security)
Dapr provides Secret management, but unlike the Secret in K8S, it supports integration with public cloud and local Secret storage for application retrieval.

What Can We Do With Dapr

Knowing what Dapr is and the features it provides, the application scenarios of Dapr are clear at a glance. That is , Slogan on the homepage of the official website : Simplify cloud-native application development--Focus on your application's core logic and keep your code simple and portable.
Simplify the development of cloud-native applications, ensure that applications focus on business, and ensure that the code is simple and portable.

Therefore, when considering the technical selection of cloud-native application development, feel free to give it a try. Currently, it has also been adopted by Alibaba Cloud in China.

Last

At the time when cloud native is in full swing, the official release of Dapr V1.0 has pointed out the development direction of microservices in the cloud native era for developers. I believe Dapr will surely occupy a place in the future selection of microservice architecture!

 

The article is reproduced: https://www.cnblogs.com/sheng-jie/p/how-much-you-know-about-dapr.html

Guess you like

Origin blog.csdn.net/ChaITSimpleLove/article/details/113928291