Dapr专题之04状态存储

Dapr状态存储



提示:以下是本篇文章正文内容,下面案例可供参考

Dapr状态存储的优势

  • 可插拔的存储组件
    • 支持的存储组件:
      https://docs.dapr.io/zh-hans/reference/components-reference/supported-state-stores/
      
  • 并发控制:通过Etag实现
  • 一致性:可以指定是否强一致性来保证所有存储副本保存成功之后再返回成功
  • 批量操作

调用终结点

http://localhost:<dapr-port>/v1.0/state/<store-name>/
  • <dapr-port>:Dapr正在侦听的HTTP端口
    
  • <store-name>:要使用的状态存储组件的名称。
    

代码编写

  1. FrontEnd项目下,新建StateController
  2. 注入DaprClient
     private readonly ILogger<StateController> _logger;
     private readonly DaprClient _daprClient;
     public StateController(ILogger<StateController> logger, DaprClient daprClient)
     {
         _logger = logger;
         _daprClient = daprClient;
     }
    
  3. 声明要使用的存储组件和Key
    const string STATE_STORE = "statestore";
    const string KEY_NAME = "guid";
    
  4. 新增接口
     //设置强一致性,保存一个值
     [HttpPost]
     public async Task<ActionResult> PostAsync()
     {
         await _daprClient.SaveStateAsync<string>(STATE_STORE, KEY_NAME, Guid.NewGuid().ToString(), new StateOptions() { Consistency = ConsistencyMode.Strong });
         return Ok("done");
     }
     
     //通过tag防止并发冲突,保存一个值
     [HttpPost("withtag")]
     public async Task<ActionResult> PostWithTagAsync()
     {
         var (value, etag) = await _daprClient.GetStateAndETagAsync<string>(STATE_STORE, KEY_NAME);
         var resust= await _daprClient.TrySaveStateAsync<string>(STATE_STORE, KEY_NAME, Guid.NewGuid().ToString(), etag);
         return Ok("done");
     }
     
     // 获取一个值
     [HttpGet]
     public async Task<ActionResult> GetAsync()
     {
         var result = await _daprClient.GetStateAsync<string>(STATE_STORE, KEY_NAME);
         return Ok(result);
     }
     
      // 获取一个值和etag
     [HttpGet("withetag")]
     public async Task<ActionResult> GetWithEtagAsync()
     {
         var (value, etag) = await _daprClient.GetStateAndETagAsync<string>(STATE_STORE, KEY_NAME);
         return Ok($"value is {value}, etag is {etag}");
     }
     
     //删除一个值
     [HttpDelete]
     public async Task<ActionResult> DeleteAsync()
     {
         await _daprClient.DeleteStateAsync(STATE_STORE, KEY_NAME);
         return Ok("done");
     }
     
      //通过tag防止并发冲突,删除一个值
     [HttpDelete("withtag")]
     public async Task<ActionResult> DeleteWithTagAsync()
     {
         var (value, etag) = await _daprClient.GetStateAndETagAsync<string>(STATE_STORE, KEY_NAME);
         var success = await _daprClient.TryDeleteStateAsync(STATE_STORE, KEY_NAME, etag);
         return Ok($"value is {value}, etag is {etag}");
     }
     
     //根据FromState获取一个值,健值name从路由模板获取
     [HttpGet("fromState/{name}")]
     public async Task<ActionResult> GetFromBindingAsync([FromState(STATE_STORE, KEY_NAME)] StateEntry<string> state)
     {
         return Ok(state.Value);
     }
    
     // 根据FromState获取并修改值,健值name从路由模板获取
     [HttpPost("fromState/{name}")]
     public async Task<ActionResult> PostWithBindingAsync([FromState(STATE_STORE, KEY_NAME)] StateEntry<string> state)
     {
         state.Value = Guid.NewGuid().ToString();
         return Ok(await state.TrySaveAsync());
     }
     
     // 获取多个个值
     [HttpGet("list")]
     public async Task<ActionResult> GetListAsync()
     {
         var result = await _daprClient.GetBulkStateAsync(STATE_STORE, new List<string> { KEY_NAME }, 10);
         return Ok(result);
     }
    
     //批量删除
     [HttpDelete("list")]
     public async Task<ActionResult> DeleteListAsync()
     {
         var data = await _daprClient.GetBulkStateAsync(STATE_STORE, new List<string> { KEY_NAME }, 10);
         var removeList = new List<BulkDeleteStateItem>();
         foreach (var item in data)
         {
             removeList.Add(new BulkDeleteStateItem(item.Key, item.ETag));
         }
         await _daprClient.DeleteBulkStateAsync(STATE_STORE, removeList);
         return Ok("done");
     }
    

运行与测试

  • 启动FrontEnd
    dapr run --dapr-http-port 3501 --app-port 5001  --app-id frontend dotnet  .\FrontEnd\bin\Debug\net6.0\FrontEnd.dll
    

调用结果如下:
新增接口:在这里插入图片描述
可以看到Redis已经有了值:
在这里插入图片描述
其他接口就不一一在此测试了,大家有兴趣可以自己去试试

切换存储组件

  • 新增yaml文件statestore-mysql,写入以下代码

    apiVersion: dapr.io/v1alpha1
    kind: Component
    metadata:
       name: statestore-mysql
    spec:
     type: state.mysql
     version: v1
     metadata:
     - name: connectionString
     value: "root:mysql123@tcp(192.168.11.112:3306)/?allowNativePasswords=true"
    
    
  • 修改STATE_STORE,注意这里的STATE_STORE 需要和yaml文件中metadata的name保持一致

    const string STATE_STORE = "statestore-mysql";
    
  • 重启项目

测试

调用结果如下:
新增接口
在这里插入图片描述
mysql已经插入了数据:
在这里插入图片描述
其他的接口大家也可自行测试,这里就不一一为大家展示了


总结

以上就是这次要给大家分享的内容,本文介绍了Dapr中关于状态存储的实操过程,下次将给大家介绍Dapr中的发布订阅,欢迎各位朋友点赞收藏,同时希望本文能够给大家带来一丝帮助与启发。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值