A summary,

The first chapter introduces what Dapr is, what problems Dapr can solve, the history of Dapr, the brief introduction of Dapr functions, and the installation of Dapr. This article focuses on the functions of Dapr and conducts in-depth functional combat. This article starts with three functions: Service-to-service Invocation and State management. All demo is presented in Java.

2. Demo project configuration

2.1 the resources configuration

<! -- application.properties --> server.port=8880<! -- logback.xml --> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d {HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
Copy the code

2.2 start the class

<! -- HelloWorldApplication -->package com.test.dapr.sample;

import com.test.dapr.sample.interfaces.http.DemoActorImpl;
import io.dapr.actors.runtime.ActorRuntime;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloWorldApplication {

    public static void main(String[] args) { SpringApplication.run(HelloWorldApplication.class, args); }}Copy the code

2.3 the basic class

<! -- Response -->package com.test.dapr.sample.interfaces.http;

import lombok.Data;
import lombok.ToString;
import java.io.Serializable;

@Data
@ToString
public class Response<T> implements Serializable {

    private boolean success;

    private T result;

    private String code;

    private String message;

    public static <T> Response<T> ok(T data) {
        Response resp = new Response();
        resp.setResult(data);
        resp.setSuccess(true);
        return resp;
    }
}

<!-- DaprConfig -->
package com.test.dapr.sample.config;

import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DaprConfig {

    private static final DaprClientBuilder BUILDER = new DaprClientBuilder();

    @Bean
    public DaprClient daprClient(a) {
        returnBUILDER.build(); }}Copy the code

2.4 Basic POM Configuration

<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0. 0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>dapr-helloworld</artifactId>
    <version>0.035.</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.03..RELEASE</version> <relativePath/> <! -- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <zcy-dependency-manage.version>3.0. 0-RELEASE</zcy-dependency-manage.version>
        <zcy-release-check-plugin.version>3.0. 0-RELEASE</zcy-release-check-plugin.version>
        <hutool.version>4.52.</hutool.version>
        <guava.version>18.0</guava.version>
        <commons-lang3.version>3.31.</commons-lang3.version>
        <fastjson.version>1.260.</fastjson.version>
        <zcy-common-api.version>1.0. 0-RELEASE</zcy-common-api.version>
        <protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
        <protobuf.input.directory>${project.basedir}/proto</protobuf.input.directory>
        <maven.deploy.skip>true</maven.deploy.skip>
        <spotbugs.fail>false</spotbugs.fail>
        <opentelemetry.version>0.14. 0</opentelemetry.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.122.</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>commons-cli</groupId>
            <artifactId>commons-cli</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.39. 0</version>
            <exclusions>
                <exclusion>
                    <artifactId>protobuf-java</artifactId>
                    <groupId>com.google.protobuf</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>error_prone_annotations</artifactId>
                    <groupId>com.google.errorprone</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <artifactId>protobuf-java</artifactId>
            <groupId>com.google.protobuf</groupId>
            <version>3.13. 0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.39. 0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-api</artifactId>
            <version>1.39. 0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.4. 0</version> </dependency> <! -- Dapr's core SDK with all features, Except Actors. --> <dependency> <groupId> IO. Dapr </groupId> <artifactId>dapr- SDK </artifactId> <version>1.3.1</version> </dependency> <! -- Dapr's SDK for Actors (optional)Dapr </groupId> <artifactId> Dapr-SDK-actors </artifactId> <version>1.3.1</version> </dependency> <! -- &lt; ! &ndash; Dapr's SDK integration with SpringBoot (optional). – > --> 
       
       
         IO. Dapr 
        
       
         dapr-sdK-springboot 
        
       
        1.3.1
        
       
       
       
        org.jetbrains.kotlin
        
       
        kotlin-stdlib
        < version > 1.3.50 < / version > < / dependency > < the dependency > < groupId > org. Jetbrains. Kotlin < / groupId > < artifactId > kotlin stdlib - common < / artifactId > < version > 1.3.50 < / version > < / dependency > < the dependency > < the groupId > com. Squareup. Okhttp3 < / groupId > < artifactId > okhttp < / artifactId > < version > 4.9.0 < / version > < exclusions > 
        
        
         kotlin-stdlib
         
        
         org.jetbrains.kotlin
         
        
        
        
         kotlin-stdlib-common
         
        
         org.jetbrains.kotlin
         
         
        
       
        
         
         
          org.springframework.boot
          < artifactId > spring - the boot - maven - plugin < / artifactId > < version >. 2.0.3 RELEASE < / version > < executions > < execution > 
         
          sprint-boot-application
          
          
          
           repackage
           
            
         
        
          . < groupId > org, apache maven plugins < / groupId > < artifactId > maven - compiler - plugin < / artifactId > < version > 3.7.0 < / version > 
          
          1.8 
          
           1.8
           
          
         
        
          . < groupId > org, apache maven plugins < / groupId > < artifactId > maven deploy - plugin < / artifactId > < version > 2.8.2 < / version > 
          
          
           true
           
          
         
         
         
          org.apache.maven.plugins
          
         
          maven-source-plugin
          
          
          
           true
           
          
          
           
           
            compile
            
            
            
             jar
             
            
           
          
         
        
       Copy the code

2.5 Packing Docker images

Use Dockfile file mode

FROM java:8-jre
WORKDIR /root
ADD ./dapr-helloworld-0.035..jar ./
ENTRYPOINT ["java"."-Xmx200m"."-jar"."Dapr - the helloworld - 0.0.35. Jar"]
Copy the code

The Maven plugin configuration is as follows:

<! -- docker-maven-plugin --> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.413.</version>
    <configuration>
        <imageName>xxx.xxx.com/xxx/${project.artifactId}</imageName>
        <baseImage>java:8-jre</baseImage>
        <workdir>/root</workdir>
        <entryPoint>["java"."-Xmx200m"."-jar"."${project.build.finalName}.jar"]</entryPoint>
        <resources>
            <resource>
                <targetPath>.</targetPath>
                <directory>${project.build.directory}</directory>
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
        <imageTags>
            <imageTag>${project.version}</imageTag>
        </imageTags>
    </configuration>
</plugin>
Copy the code

Docker is not introduced in detail, if you can’t use it, you can learn a wave by yourself. After packaging, push the image to the Docker repository

3. Service-to-service Invocation

Let’s revisit the previous path diagram:

3.1 Demo code

First, establish two services and Controller, set the serverport of the two services, demo1 is 8888, demo2 is 8880.

Not the Controller

<! -- HelloWorldController -->@RestController
public class HelloWorldController {
  
  @PostMapping("/helloWorld")
    public Response<String> helloWorld(a) {
        System.out.println("post-helloWorld");
        return Response.ok("post-helloWorld");
    }

    @GetMapping("/helloWorld")
    public Response<String> getHelloWorld(a) {
        System.out.println("get-helloWorld");
        return Response.ok("get-helloWorld"); }}Copy the code

Demo2 Controller

@RestController
public class HelloWorldController {

  	@Autowired
    private DaprClient daprClient;

		@PostMapping("/dapr-helloWorld")
    public Response<String> helloWorld(a) {
        System.out.println("helloWorld");
        return Response.ok("helloWorld");
    }
    
    @GetMapping("/dapr-helloWorld")
    public Response<String> getHelloWorld(@RequestHeader Map<String, String> headers) {
        System.out.println("getHelloWorld");
        HttpExtension httpExtension = new HttpExtension(DaprHttp.HttpMethods.GET, null, headers);

        InvokeMethodRequest request = new InvokeMethodRequest("nodeapp"."helloWorld")
                .setBody(null)
                .setHttpExtension(httpExtension);
        Response response = daprClient.invokeMethod(request, TypeRef.get(Response.class)).block();
// .subscriberContext(getReactorContext()).block();
        System.out.println("finish getHelloWorld");
        if(response ! =null) {
            return Response.ok(response.getResult().toString());
        }
        return null; }}Copy the code

3.2 YAML configuration of K8s

demo1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodeapp
  labels:
    app: http-demo
spec:
  selector:
    matchLabels:
      app: http-demo
  replicas: 1
  template:
    metadata:
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "nodeapp"
        dapr.io/app-port: "8888"
        dapr.io/app-protocol: "http"
#        dapr.io/log-as-json: "true"
        dapr.io/config: "zipkin-config"
#        dapr.io/app-config: "appconfig"
        dapr.io/sidecar-listen-addresses: 0.0. 0. 0
      labels:
        app: http-demo
    spec:
      containers:
        - name: http-demo
          image: xxxx.xxxx.com/xxxx/helloworld:0.03.
          ports:
            - containerPort: 8888
---
apiVersion: v1
kind: Service
metadata:
  name: http-demo
spec:
  type: NodePort
  selector:
    app: http-demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8888
      nodePort: 31111
Copy the code

demo2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: daprnodeapp
  labels:
    app: dapr-http-demo
spec:
  selector:
    matchLabels:
      app: dapr-http-demo
  replicas: 1
  template:
    metadata:
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "daprnodeapp"
        dapr.io/app-port: "8880"
#        dapr.io/log-as-json: "true"
        dapr.io/config: "zipkin-config"
#        dapr.io/app-config: "appconfig"
        dapr.io/sidecar-listen-addresses: 0.0. 0. 0
      labels:
        app: dapr-http-demo
    spec:
      containers:
        - name: dapr-http-demo
          image: xxxx.xxxx.com/xxxx/dapr-helloworld:0.035.
          ports:
            - containerPort: 8880
---
apiVersion: v1
kind: Service
metadata:
  name: dapr-http-demo
spec:
  type: NodePort
  selector:
    app: dapr-http-demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8880
      nodePort: 32222
Copy the code

3.3K8S start project

Run kubectl apply -f http-demo.yaml -n XXX to start demo1 project

Execute kubectl apply -f http-demo-dappl. yaml -n XXX to start demo2 project

3.4 Service Verification

1.HTTP: demo1 HTTP:/ / IP networks outside: 31111 / helloWorld

2.Kubectl get Pods -o wide -n XXX curl HTTP: kubectl get Pods -o wide -n XXX curl/ / not network IP: 3500 / v1.0 / invoke/nodeapp/method/helloWorld

3.After dapR is authenticated as a sidecard, the services of Demo1 are authenticated through Demo2. Demo2 Internet access (same as2) the curl HTTP:/ / demo2 Intranet IP: 3500 / v1.0 / invoke/daprnodeapp/method/dapr - the helloWorld

Copy the code

At this point, the call between DAPR services is complete. We can use the official lightweight SDK to make the call, of course, we can also make the call through HTTP.

Iv. State Management

There are only Redis and MongoDB versions available for state management. Let’s get familiar with this feature through Redis.

4.1 K8S install Redis

Kubectl create namespace redis-sys kubectl create namespace redis-sys

Kubectl create -f redis.yaml -n redis-sys

kind: Deployment
apiVersion: apps/v1
metadata:
  name: redis
  namespace: redis-sys
spec:
  replicas: 1
  selector:
    matchLabels:
      name: redis
  template:
    metadata:
      labels:
        name: redis
    spec:
      containers:
      - name: redis
        image: redis:5
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
          protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
  name: redis
  namespace: redis-sys
  labels:
    name: redis
spec:
 type: NodePort
 ports:
 - port: 6379
   targetPort: 6379
   nodePort: 30041
   name: redis-port
 selector:
   name: redis
Copy the code

4.2 Creating a state store

Kubectl create -f statestore.yaml to start http-demo project

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
  namespace: defaultRedis version: v1 Metadata: - name: redisHost value: redis Intranet IP address:6379
  - name: redisPassword
    value: ""
Copy the code

4.3 Service Verification

The accessed IP address is the Intranet IP address corresponding to HTTP-Demo

A single create

curl -X POST -H “Content-Type: application/json” -d ‘[{ “key”: “key1”, “value”: “Value1}] ‘” xx. Xx. Xx. Xx: 3500 / v1.0 / state /…

Create a batch

curl -X POST -H “Content-Type: application/json” -d ‘[{ “key”: “key1”, “value”: “value1”}, { “key”: “key2”, “value”: “Value2”}] ‘xx. Xx. Xx. Xx: 3500 / v1.0 / state /…

A single access

Curl xx, xx, xx, xx: 3500 / v1.0 / state /…

Batch to obtain

Curl -x POST – H “content-type: application/json” 3-d “{” keys” : [” key1 “, “key2”]} ‘xx, xx, xx, xx: 3500 / v1.0 / state /…

delete

The curl -x DELETE ‘xx. Xx. Xx. Xx: 3500 / v1.0 / state /… ‘

State transactional operations

Curl -x post-h “content-Type: application/json” -d ‘{“operations”: [{“operation”:”upsert”, “request”: {“key”: “Key1”, “value” : “newValue1″}}, {” operation “:” delete “, “request” : {” key “:” key2 “}}]} ‘xx. Xx. Xx. Xx: 3500 / v1.0 / state /…

Query: curl -x POST – H “content-type: application/json” 3-d “{” keys” : [” key1 “, “key2”]} ‘xx, xx, xx, xx: 3500 / v1.0 / state /…

Default mode: last-write-WINS, also first-write-WINS (optimistic locking)

Official support of middleware: www.bookstack.cn/read/dapr-1…

Five, the summary

The above provides a Java Demo related to Dapr, and other subsequent functions are based on the above Demo. This paper introduces inter-service invocation and state management, and other main functions of the official website will be introduced later.

Recommended reading

Dapr Combat (part 1)

DS version control core principles revealed

DS 2.0 era API operation posture

Process and optimization of a search performance

, recruiting

Zhengcaiyun Technology team (Zero) is a passionate, creative and executive team based in picturesque Hangzhou. The team has more than 300 r&d partners, including “old” soldiers from Alibaba, Huawei and NetEase, as well as newcomers from Zhejiang University, University of Science and Technology of China, Hangzhou Electric And other universities. Team in the day-to-day business development, but also in cloud native, chain blocks, artificial intelligence, low code platform system, middleware, data, material, engineering platform, the performance experience, visualization technology areas such as exploration and practice, to promote and fell to the ground a series of internal technical products, continue to explore new frontiers of technology. In addition, the team is involved in community building, Currently, There are Google Flutter, SciKit-Learn, Apache Dubbo, Apache Rocketmq, Apache Pulsar, CNCF Dapr, Apache DolphinScheduler, and Alibaba Seata and many other contributors to the excellent open source community. If you want to change something that’s been bothering you, want to start bothering you. If you want to change, you’ve been told you need more ideas, but you don’t have a solution. If you want change, you have the power to make it happen, but you don’t need it. If you want to change what you want to accomplish, you need a team to support you, but you don’t have the position to lead people. If you want to change the original savvy is good, but there is always a layer of fuzzy window…… If you believe in the power of believing, believing that ordinary people can achieve extraordinary things, believing that you can meet a better version of yourself. If you want to be a part of the process of growing a technology team with deep business understanding, sound technology systems, technology value creation, and impact spillover as your business takes off, I think we should talk. Any time, waiting for you to write something and send it to [email protected]

Wechat official account

The article is published synchronously, the public number of political cloud technology team, welcome to pay attention to