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> <! -- < ! – 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 >
. < 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