状态管理

状态管理(State Management)使用键值对作为存储机制,可以轻松的使长时运行、高可用的有状态服务和无状态服务共同运行在我们的服务中。

我们的服务可以利用Dapr的状态管理API在状态存储组件中保存、读取和查询键值对。

状态存储组件是可插拔的,目前支持使用Azure CosmosDB、 Azure SQL Server、 PostgreSQL,、AWS DynamoDB、Redis 作为状态存储介质。

文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

编写示例代码

创建一个SpringBoot项目,命名为:state-management,该项目的状态管理调用过程如下图:

state-management该项目的pom.xml文件中添加如下依赖:

<dependency>
<groupId>io.dapr</groupId>
<artifactId>dapr-sdk-springboot</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>

注入一个DaprClient的bean:

@Configuration
public class DaprConfig { private static final DaprClientBuilder BUILDER = new DaprClientBuilder(); @Bean
public DaprClient buildDaprClient() {
return BUILDER.build();
}
}

state-management项目中一共有3个接口:

  • save:保存状态
  • get:读取状态
  • delete:删除状态

具体源码如下:

package one.more.society.state.management;

import io.dapr.client.DaprClient;
import io.dapr.client.domain.State;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; @Slf4j
@RestController
public class StateManagementController { @Autowired
private DaprClient client; private static final String STATE_STORE_NAME = "statestore";
private static final String STATE_STORE_KEY = "one.more.society"; /**
* 保存状态
*
* @param value value
* @return
*/
@RequestMapping(value = "/save", method = RequestMethod.GET)
public StateResponse save(String value) {
log.info("save - value:{}", value);
client.saveState(STATE_STORE_NAME, STATE_STORE_KEY, value).block(); StateResponse response = new StateResponse();
response.setCode(1);
response.setStatus("save");
response.setValue(value);
return response;
} /**
* 读取状态
*
* @return StateResponse
*/
@RequestMapping(value = "/get", method = RequestMethod.GET)
public StateResponse get() {
log.info("get");
State<String> value = client.getState(STATE_STORE_NAME, STATE_STORE_KEY, String.class).block();
log.info("value: {}", value.getValue()); StateResponse response = new StateResponse();
response.setCode(1);
response.setStatus("get");
response.setValue(value.getValue());
return response;
} /**
* 删除状态
*
* @return
*/
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public StateResponse delete() {
log.info("delete");
client.deleteState(STATE_STORE_NAME, STATE_STORE_KEY).block(); StateResponse response = new StateResponse();
response.setCode(1);
response.setStatus("delete");
return response;
}
}

另外,在application.properties中配置:

server.port=30003

文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

启动服务

在启动之前先用mvn命令打包:

mvn clean package

state-management项目的目录中执行以下命令,启动state-management服务:

dapr run --app-id state-management --app-port 30003 --dapr-http-port 31003 -- java -jar target/state-management-0.0.1-SNAPSHOT.jar

在Dapr Dashboard中看到:

服务都已经启动成功。

先访问http://localhost:30003/get,可以看到:

读取状态返回为null,接下来访问http://localhost:30003/save?value=万猫学社,可以看到:

状态已经保存了,再访问http://localhost:30003/get验证一下:

状态被正确读取,再访问http://localhost:30003/delete,可以看到:

状态已经被删除了,再访问http://localhost:30003/get验证一下:

读取状态返回为null。

文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

状态储存组件

初始化Dapr后,默认为我们指定的状态储存组件是Redis,在用户目录下的.dapr文件夹中的components文件夹中,可以找到statestore.yaml文件:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"

下面让我们来尝试一下,使用MySQL作为状态储存组件,把statestore.yaml文件修改为:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.mysql
version: v1
metadata:
- name: connectionString
value: "root:one.more.society@tcp(127.0.0.1:3306)/?allowNativePasswords=true"

重新启动服务,可以看到在日志中看到使用MySQL作为状态储存组件:

time="09:57:35.5632633+08:00" level=info msg="Creating MySql schema 'dapr_state_store'" app_id=state-management instance=JT-243137 scope=dapr.contrib type=log ver=1.7.3
time="09:57:35.5862126+08:00" level=info msg="Creating MySql state table 'state'" app_id=state-management instance=JT-243137 scope=dapr.contrib type=log ver=1.7.3
time="09:57:35.6563599+08:00" level=info msg="component loaded. name: statestore, type: state.mysql/v1" app_id=state-management instance=JT-243137 scope=dapr.runtime type=log ver=1.7.3

如果在MySQL中没有对应的库和表,Dapr默认为我们自动创建一个名为dapr_state_store的库,还有一个名为state的表,如下图:

其中,state的表结构为:

CREATE TABLE `state` (
`id` varchar(255) NOT NULL,
`value` json NOT NULL,
`isbinary` tinyint(1) NOT NULL,
`insertDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`eTag` varchar(36) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

再访问一下http://localhost:30003/save?value=万猫学社,就可以在数据库中看到对应的数据:

值得注意的是:MySQL状态储存组件目前还处于Alpha状态,最好不要在生产环境使用。

更详细的配置说明见下表:

配置项 是否必填 说明 示例
connectionString Y 用于连接到 MySQL 的连接字符串。 请不要将schema添加到连接字符串中。 非SSL连接:
"<user>:<password>@tcp(<server>:3306)/?allowNativePasswords=true"
Enforced SSL 连接:
"<user>:<password>@tcp(<server>:3306)/?allowNativePasswords=true&tls=custom"
schemaName N 要使用的schema名称。 如果指定的schema不存在,将会自动创建。默认值为"dapr_state_store" "one_more_state_store"
tableName N 要使用的表名。如果对应的表不存在,将被自动创建。默认值为 "state" "one_more_state"
pemPath N 使用 Enforced SSL 连接 时,指定要使用的 PEM 文件完整路径。 "/one/more/society/file.pem"
pemContents N 如果没有提供pemPath,用于Enforced SSL连接的PEM文件的内容。可以在K8s环境下使用。 "pem value"

配置示例:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.mysql
version: v1
metadata:
- name: connectionString
value: "root:one.more.society@tcp(127.0.0.1:3306)/?allowNativePasswords=true&tls=custom"
- name: schemaName
value: "one_more_state_store"
- name: tableName
value: "one_more_state"
- name: pemPath
value: "/one/more/society/file.pem"

微信公众号:万猫学社

微信扫描二维码

关注后回复「电子书」

获取12本Java必读技术书籍

Dapr在Java中的实践 之 状态管理的更多相关文章

  1. Trident中使用HBase进行状态管理

    1.使用的类 2.使用HBaseMapState 3.使用状态管理 使用的状态管理还要看Spout StateFactory factory1 = HBaseMapState.opaque(opts1 ...

  2. Java中的内存机制及管理

    1. Java根据虚拟机以及平台的版本不同而在内存中开辟不同大小的内存,通常不会关注这个大小. 2. 程序中的对象存储在内存的堆(heap)中 3. 程序中的方法和局部变量存储在内存的栈(Stack) ...

  3. react-redux --》react中 最好用的状态管理方式

    一.Redux与组件 react-redux是一个第三方插件使我们在react上更方便的来使用redux这个数据架构 React-Redux提供connect方法,用于从UI组件生成容器组件,conn ...

  4. java中线程的状态详解

    一.线程的五种状态   线程的生命周期可以大致分为5种,但这种说法是比较旧的一种说法,有点过时了,或者更确切的来说,这是操作系统的说法,而不是java的说法.但对下面所说的六种状态的理解有所帮助,所以 ...

  5. Java中一个线程只有六个状态。至于阻塞、可运行、挂起状态都是人们为了便于理解,自己加上去的。

    java中,线程的状态使用一个枚举类型来描述的.这个枚举一共有6个值: NEW(新建).RUNNABLE(运行).BLOCKED(锁池).TIMED_WAITING(定时等待).WAITING(等待) ...

  6. 并发基础(四) java中线程的状态

    一.程的五种状态   线程的生命周期可以大致分为5种,但这种说法是比较旧的一种说法,有点过时了,或者更确切的来说,这是操作系统的说法,而不是java的说法.但对下面所说的六种状态的理解有所帮助,所以也 ...

  7. 你真的了解JAVA中对象和类、this、super和static关键字吗

    作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 目录 Java对象究竟是什么? 创建对象的过程 ...

  8. Java中String、StringBuffer、StringBuilder区别与理解

    一.先比较String.StringBuffer.StringBuilder变量的HashCode值 使用System.out.println(obj.hashcode())输出的时对象的哈希码, 而 ...

  9. Java中的String和StringBuffer

    在任何编程语言中,字符串都是我们编写程序时不可避免要用到的常用的数据类型之一. 对于Java初学者而言,当谈到String和StringBuffer的区别时,通常都会有些困惑. 而要弄清楚两者之间的区 ...

  10. Java中关于String类型的一些思考

    作为初学者在学习Java的时候,变量类型是不可避免会遇到的,在以往我们的印象中字符串String都是作为基本类型而存在的,但是在Java中String类型确是一个实实在在的引用类型,是可以通过new关 ...

随机推荐

  1. 实现一个CRDT工具库——VClock 时钟向量类

    这段代码实现了一个VClock类,它是基于GCounter实现的.VClock是一种向量时钟,它可以用于在分布式系统中对事件发生的顺序进行排序.VClock的实现方式是将每个节点的计数器值存储在一个字 ...

  2. hdfs集群的扩容和缩容

    目录 1.背景 2.集群黑白名单 3.准备一台新的机器并配置好hadoop环境 3.1 我们现有的集群规划 3.2 准备一台新的机器 3.2.1 查看新机器的ip 3.2.2 修改主机名和host映射 ...

  3. SpringBoot中如何实现业务校验,这种方式才叫优雅!

    大家好,我是飘渺. 在日常的接口开发中,为了保证接口的稳定安全,我们一般需要在接口逻辑中处理两种校验: 参数校验 业务规则校验 首先我们先看看参数校验. 参数校验 参数校验很好理解,比如登录的时候需要 ...

  4. vue指令之事件指令

    目录 什么是事件指令 示例 什么是事件指令 事件指的是:点击事件,双击事件,划动事件,焦点事件... 语法 v-on:事件名='函数' # 注意:函数必须写在 methods配置项中 示例 # 点击按 ...

  5. Kubernetes(K8S)内核优化常用参数详解

    net.ipv4.tcp_keepalive_time=600 net.ipv4.tcp_keepalive_intvl=30 net.ipv4.tcp_keepalive_probes=10 net ...

  6. Django笔记二十一之使用原生SQL查询数据库

    本文首发于公众号:Hunter后端 原文链接:Django笔记二十一之使用原生SQL查询数据库 Django 提供了两种方式来执行原生 SQL 代码. 一种是使用 raw() 函数,一种是 使用 co ...

  7. XmlSerializer 反射类型xxx时出错,反射属性xxx时出错。

    在使用XmlSerializer将类序列化成XML时出错,看到InnerException的message可以知道是这个receiver里有错误,进入这个类查看一下代码发现有重名的类 NodeId类修 ...

  8. 从零开始学Vue(一)—— Vue.js 入门

    概述 vue.js作为现在笔记热门的JS框架,使用比较简单易上手,也成为很多公司首选的JS框架. 但是对于初学者可能学起来有些麻烦,所以推出<从零开始学Vue>系列博客,本系列计划推出19 ...

  9. 项目中统计SQL执行缓慢的方案-数据预处理

    使用场景: 由于表数据量巨大,导致一些统计相关的sql执行非常慢,使用户有非常不好的体验,并且sql和数据库已经没有优化空间了.(并且该统计信息数据实时性要求不高的前提下) 解决方案: 整体思路:创建 ...

  10. Appweb交叉编译

    Appweb交叉编译 编译环境:ubuntu-12.04 x64 开发平台:Hi3535 arm版 编译版本:appweb-6.1.1.zip 下载地址=> Appweb web site: h ...