Dapr(三) Dapr核心组件的使用一

news2024/11/17 8:37:53

结合前两期 Dapr(一) 基于云原生了解Dapr(Dapr(一) 基于云原生了解Dapr-CSDN博客) Dapr(二) 分布式应用运行时搭建及服务调用(Dapr(二) 分布式应用运行时搭建及服务调用-CSDN博客)

下篇推出dapr服务注册与发现,dapr组件绑定,dapr Actor功能。

目录

1.0 Dapr状态管理

1.1 Dapr状态组件配置文件

1.2 状态控制器

1.3 切换其它状态存储

1.4 工作原理

2.0 发布订阅

2.1 什么是发布订阅

2.2 设置发布订阅组件

2.3 控制器代码

2.3.1 发布控制器

2.3.2 订阅控制器

2.4 修改文件Program.cs

2.5 切换组件 

2.6 工作原理

总结:


1.0 Dapr状态管理

Dapr的状态管理允许应用程序保存和检索键值对数据,具有可插拔的存储、配置的行为和额外的安全特性。以下是主要特点:

  1. 可插拔状态存储:Dapr支持多种数据存储,比如MySQL、Redis、Azure CosmosDB等,可以在不修改代码的情况下切换。

  2. 配置存储行为:你可以指定并发控制和一致性级别。默认是最终一致性,但也支持强一致性。

  3. 并发控制:通过ETags实现乐观并发控制(OCC)。写操作需要匹配当前的ETag值,防止冲突。

  4. 自动加密:预览功能,支持应用程序状态的自动加密和密钥轮换。

  5. 一致性选项:可以选择强一致性的写入,等待所有副本确认,或者默认的最终一致性。

  6. 批量操作:支持一次性处理多条状态记录。

1.1 Dapr状态组件配置文件

Dapr默认使用的Redis进行存储。

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"

1.2 状态控制器

 public class StateController : ControllerBase
    {
        private readonly ILogger<StateController> _logger;
        private readonly DaprClient _daprClient;
        public StateController(ILogger<StateController> logger, DaprClient daprClient)
        {
            _logger = logger;
            _daprClient = daprClient;
        }

        // 获取一个值
        [HttpGet]
        public async Task<ActionResult> GetAsync()
        {
            var result = await _daprClient.GetStateAsync<string>("statestore", "guid");
            return Ok(result);
        }

        //保存一个值
        [HttpPost]
        public async Task<ActionResult> PostAsync()
        {
            await _daprClient.SaveStateAsync<string>("statestore", "guid", Guid.NewGuid().ToString(), new StateOptions() { Consistency = ConsistencyMode.Strong });
            return Ok("done");
        }

        //删除一个值
        [HttpDelete]
        public async Task<ActionResult> DeleteAsync()
        {
            await _daprClient.DeleteStateAsync("statestore", "guid");
            return Ok("done");
        }

        //通过tag防止并发冲突,保存一个值
        [HttpPost("withtag")]
        public async Task<ActionResult> PostWithTagAsync()
        {
            var (_, etag) = await _daprClient.GetStateAndETagAsync<string>("statestore", "guid");
            await _daprClient.TrySaveStateAsync("statestore", "guid", Guid.NewGuid().ToString(), etag);
            return Ok("done");
        }

        //通过tag防止并发冲突,删除一个值
        [HttpDelete("withtag")]
        public async Task<ActionResult> DeleteWithTagAsync()
        {
            var (_, etag) = await _daprClient.GetStateAndETagAsync<string>("statestore", "guid");
            return Ok(await _daprClient.TryDeleteStateAsync("statestore", "guid", etag));
        }


        // 从绑定获取一个值,健值name从路由模板获取
        [HttpGet("frombinding/{name}")]
        public ActionResult GetFromBindingAsync([FromState("statestore", "name")] StateEntry<string> state)
        {
            return Ok(state.Value);
        }


        // 根据绑定获取并修改值,健值name从路由模板获取
        [HttpPost("withbinding/{name}")]
        public async Task<ActionResult> PostWithBindingAsync([FromState("statestore", "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("statestore", new List<string> { "guid" }, 10);
            return Ok(result);
        }

        // 删除多个个值
        [HttpDelete("list")]
        public async Task<ActionResult> DeleteListAsync()
        {
            var data = await _daprClient.GetBulkStateAsync("statestore", new List<string> { "guid" }, 10);
            var removeList = new List<BulkDeleteStateItem>();
            foreach (var item in data)
            {
                removeList.Add(new BulkDeleteStateItem(item.Key, item.ETag));
            }
            await _daprClient.DeleteBulkStateAsync("statestore", removeList);
            return Ok("done");
        }
    }

1.3 切换其它状态存储

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

切换状态为MySql进行存储。

1.4 工作原理

应用程序与 Dapr sidecar 交互,以存储和检索键/值数据。 在底层,sidecar API 使用**可配置的状态存储组件**来保存数据。 开发人员可以从不断增长的受支持状态存储集合中选择,其中包括 Azure Cosmos DB、SQL Server 和 Cassandra。

2.0 发布订阅

2.1 什么是发布订阅

发布订阅(Publish-Subscribe)是一种通信模式,允许发布者发送消息到一个中心节点(通常是消息代理或主题),而不关心具体哪些订阅者会接收到这些消息。订阅者则注册他们感兴趣的特定类型的消息,当匹配的消息发布时,他们会收到通知。这种模式的特点在于解耦了发布者和订阅者,提高了系统的灵活性和可扩展性。

关键元素包括:

  1. 发布者 (Publisher): 生产消息的实体,它向主题或消息代理发送消息,无需了解谁会接收这些消息。
  2. 订阅者 (Subscriber): 对特定消息感兴趣并希望接收通知的实体,它们通过订阅主题或消息代理来表达兴趣。
  3. 主题 或 消息代理 (Topic or Message Broker): 中间媒介,接收并分发消息,确保消息从发布者到达正确的订阅者。

一个简单的示例是新闻系统,其中发布者发布新闻到特定类别,而订阅者选择关注他们感兴趣的类别。发布者不直接通知订阅者,而是通过消息代理进行,这样订阅者仅接收与其订阅相匹配的新闻。

发布订阅模式的应用场景通常涉及异步通信、事件驱动的系统或需要解耦组件的场景。

2.2 设置发布订阅组件

Dapr默认使用的Redis进行发布订阅

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

2.3 控制器代码

2.3.1 发布控制器

    [ApiController]
    [Route("[controller]")]
    public class PubsubController : ControllerBase
    {
        private DaprClient _daprClient;
        private ILogger<PubsubController> _logger;

        public PubsubController(DaprClient daprClient, ILogger<PubsubController> logger)
        {
            _daprClient = daprClient;
            _logger = logger;
        }

        /// <summary>
        /// 发布消息的方法
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("pub")]
        public async Task<IActionResult> PublishMessage()
        {
            _logger.LogInformation("***发布消息***");
            var data = new UserInfo(10001,"操作员",19);
            await _daprClient.PublishEventAsync("pubsub", "topic",data);

            return Ok("***发布消息成功***");
        }
    }

2.3.2 订阅控制器

    [ApiController]
    [Route("[controller]")]
    public class SubController : ControllerBase
    {
        private ILogger<SubController> _logger;

        public SubController(ILogger<SubController> logger)
        {
            _logger = logger;
        }


        [HttpPost("sub")]
        [Topic("pubsub", "topic")]
        public IActionResult ConsumerMessage(UserInfo user)
        {
            _logger.LogInformation("***消费消息***");
            Console.WriteLine($"userId:{user.UserId} userName:{user.UserName}");
            return Ok();
        }
    }

2.4 修改文件Program.cs

app.UseCloudEvents();
app.MapSubscribeHandler();

2.5 切换组件 

切换为RabbitMQ

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
  namespace: default
spec:
  type: pubsub.rabbitmq
  version: v1
  metadata:
  - name: host
    value: "amqp://123:123@192.168.157.157:5672"
  - name: durable
    value: "false"
  - name: deletedWhenUnused
    value: "false"
  - name: autoAck
    value: "false"
  - name: deliveryMode
    value: "0"
  - name: requeueInFailure
    value: "false"
  - name: prefetchCount
    value: "0"
  - name: reconnectWait
    value: "0"
  - name: concurrencyMode
    value: parallel
  - name: backOffPolicy
    value: "exponential"
  - name: backOffInitialInterval
    value: "100"
  - name: backOffMaxRetries
    value: "16"

2.6 工作原理

Dapr 发布&订阅构建基块提供了一个与平台无关的 API 框架来发送和接收消息。服务将消息发布到指定主题, 业务服务订阅主题以使用消息。服务在 Dapr sidecar 上调用 pub/sub API。 然后,sidecar 调用预定义 Dapr pub/sub 组件。

总结:

Dapr的发布订阅功能使得在分布式系统中实现发布/订阅消息模式变得更加简单。主要解决了不同消息产品之间实施复杂性和功能差异的问题。你可以通过Dapr的Sidecar API使用HTTP或gRPC来发布和订阅消息。以下是关键操作的概述:

  1. 发布(Publish)消息

    • 使用http://localhost:<dapr-port>/v1.0/publish/<pub-sub-name>/<topic> URL,其中 <dapr-port> 是Dapr Sidecar监听的端口,<pub-sub-name> 是选择的发布/订阅组件名,而 <topic> 是消息的目标主题。
  2. 订阅(Subscribe)消息

    • 应用程序在启动时,通过http://localhost:<appPort>/dapr/subscribe指定其订阅,其中 <appPort> 是应用程序监听的端口。
    • 订阅者处理消息后返回非错误响应,Dapr认为消息传递成功。
    • 支持订阅者通过响应负载中的状态进行精细化控制,比如指示重试(RETRY)或丢弃(DROP)消息。

Dapr的状态管理提供了一种跨服务持久化数据的方法,支持多种存储后端。关键特性包括:

  1. 原子性操作:支持原子性的读写操作,保证一致性。

  2. 版本控制:允许跟踪状态更改的历史版本,便于回滚。

  3. 事件驱动:状态变化可触发回调函数,实现基于状态变化的自动化操作。

  4. 过期策略:可设置状态项的过期时间。

  5. 备份与恢复:提供状态备份和恢复机制,确保高可用性。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1573912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java中的常用类详解(Math、Scanner、Random、String)

目录 一、Math&#xff08;数学类&#xff09; 自带常量 取整方法 三角函数方法 指数函数方法 其他方法 二、Scanner&#xff08;实用程序类&#xff09; 三、Random&#xff08;随机数类&#xff09; 四、String&#xff08;字符串类&#xff09; 获取相关 判断相关…

实践笔记-03 docker buildx 使用

docker buildx 使用 1.启用docker buildx2.启用 binfmt_misc3.从默认的构建器切换到多平台构建器3.1创建buildkitd.toml文件&#xff08;私有仓库是http没有证书的情况下&#xff0c;需要配置&#xff09;3.2创建构建器并使用新创建的构建器 4.构建多架构镜像并推送至harbor仓库…

清风DJ,DJ舞曲听不停

hi&#xff0c;大家好我是技术苟&#xff0c;每周准时上线为你带来实用黑科技&#xff01;由于公众号改版&#xff0c;现在的公众号消息已经不再按照时间顺序排送了。因此小伙伴们就很容易错过精彩内容。喜欢黑科技的小伙伴&#xff0c;可以将黑科技百科公众号设为标星&#xf…

如何选择适合智能型程控直流电子负载

在选择适合智能型程控直流电子负载时&#xff0c;需要考虑以下几个方面&#xff1a; 根据实际需求选择合适的负载容量&#xff0c;负载容量是指电子负载能够承受的最大电流和电压。一般来说&#xff0c;负载容量越大&#xff0c;价格越高。因此&#xff0c;在满足实际需求的前提…

Qt实现Kermit协议(四)

3 实现 3.3 KermitRecvFile 该模块实现了Kermit接收文件功能。 序列图如下&#xff1a; 3.3.1 KermitRecvFile定义 class QSerialPort; class KermitRecvFile : public QObject, public Kermit {Q_OBJECT public:explicit KermitRecvFile(QSerialPort *serial, QObject *…

【SCI绘图】【小提琴系列1 python】绘制按分类变量分组的垂直小提琴图

SCI&#xff0c;CCF&#xff0c;EI及核心期刊绘图宝典&#xff0c;爆款持续更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【小提琴系列1 python】绘制按分类变量分组的垂直小提琴图&#xff0c;文末附完整代码 小提琴图是一种常用的数据可视化工具…

YUM仓库和编译安装

目录 一.YUM仓库搭建 1.简介&#xff1a; 2.搭建思路&#xff1a; 3.实验&#xff1a;单机yum的创建 二.编译安装 1.简介 2.安装过程 3.实验&#xff1a;编译安装nginx 一.YUM仓库搭建 1.简介&#xff1a; yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红…

深度学习500问——Chapter06: 循环神经网络(RNN)(3)

文章目录 6.11 LSTM 6.11.1 LSTM的产生原因 6.11.2 图解标准RNN和LSTM的区别 6.11.3 LSTM核心思想图解 6.11.4 LSTM流行的变体 6.12 LSTMs与GRUs的区别 6.13 RNNs在NLP中的典型应用 6.11 LSTM 6.11.1 LSTM的产生原因 RNN在处理长期依赖&#xff08;时间序列上距离较远的…

DC电源模块在电子设备中的应用场景

BOSHIDA DC电源模块在电子设备中的应用场景 DC电源模块在电子设备中广泛应用于以下场景&#xff1a; 1. 电子产品&#xff1a;如手机、平板电脑、笔记本电脑等便携式设备&#xff0c;这些设备通常需要稳定的直流电源来供电。 2. 工业设备&#xff1a;包括自动化设备、工业机器…

【绘图案例-绘制图片 Objective-C语言】

一、绘制图片 1.接下来,我们来说这个绘制图片啊,把之前的copy代码复制粘贴一份儿,名字改成“05-绘制图片”, 1)首先:绘制图片,你要有图片,思路都是一样的,你绘制啥,首先要有啥, 素材里边,我们来说一下啊,这个里边儿,主要来说一下,小图、和、大图、的区别, 然后…

通过 Cookie、Redis共享Session 和 Spring 拦截器技术,实现对用户登录状态的持有和清理(四)

本篇内容对应 “2.5 开发登录、退出功能” 小节 “4.7 优化登陆模块” 小节 2.6 显示登录信息 2.7 账号设置 2.8 检查登录状态 登录功能的流程是什么&#xff1f; UUID为什么不会重复&#xff1f; 因为UUID是基于mac物理地址、时间戳、随机数等信息生成。因此UUID居于极高的唯…

太阳能光伏电子实验酸洗用PFA方槽耐受强酸碱耐高温

PFA清洗槽是四氟清洗桶后的升级款&#xff0c;主要用于半导体光伏光电等行业&#xff0c;一体成型&#xff0c;无需担心漏液&#xff0c;表面光滑无毛刺。 别名PFA浸泡桶、PFA酸缸、PFA方槽等&#xff0c;可定制尺寸&#xff0c;可配套盖子&#xff0c;盖子有PFA/PTFE两种材质…

智过网:一建继续教育,操作指南与周期解析

随着社会的快速发展和技术的不断更新&#xff0c;建筑行业对从业人员的专业素质要求也在逐步提高。为了确保一级建造师的专业技能能够与时俱进&#xff0c;满足行业发展的需求&#xff0c;继续教育成为了必不可少的环节。本文将详细解析一建继续教育的操作流程及其周期安排&…

Hugging Face入门(一)

简介 本文主要内容&#xff1a; Hugging Face介绍环境搭建敲两个例子 Hugging Face介绍 Hugging Face 是一家法美合资公司&#xff0c;总部位于纽约市&#xff0c;成立于2016年。它由法国企业家Clment Delangue、Julien Chaumond和Thomas Wolf在纽约市创立&#xff0c;最初是…

让智能体像孩子一样观察别人学习动作,跨视角技能学习数据集EgoExoLearn来了

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 在探索人工智能边界时&#xff0c;我们时常惊叹于人类孩童的学习能力 —— 可以轻易地将他人…

基于SpringBoot的高校自习室预约系统

基于SpringBoot的高校自习室预约系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统功能分析 本次的功能设计主要围绕着学生和管理员两个角色&#xff0c;对于学生的用…

AI预测福彩3D第29弹【2024年4月7日预测--第7套算法重新开始计算第2次测试】

今天咱们继续进行进行第7套算法的测试&#xff0c;今天是第2次测试&#xff0c;昨天已经成功命中&#xff0c;其中7码大方案全部命中&#xff0c;四码小方案也命中。再接再厉&#xff0c;继续验证&#xff0c;废话不多说&#xff0c;直接上图上结果~ 2024年4月7日3D的七码预测结…

集合容器面试题

Java 容器都有哪些&#xff1f; Java 容器分为 Collection 和 Map 两大类 Collection 和 Collections 有什么区别&#xff1f; Collection 是一个集合接口&#xff0c;它提供了对集合对象进行基本操作的通用接口方法&#xff0c;所有集合都是它的子类&#xff0c;比如 List、…

电商卖家如何从1688批量采集商品信息并铺货到自己店铺?

目前&#xff0c;各大电商平台严查无货源&#xff0c;不管是已经开店还是准备开店的卖家&#xff0c;想要店铺长久发展&#xff0c;都需要从1688找授权分销的厂家拿货源铺货。 然而很多新手卖家在1688找货源时&#xff0c;不知道如何找到物美价廉的源头厂货&#xff0c;选好货…

SpringBoot实现RabbitMQ的通配符交换机(SpringAMQP 实现Topic交换机)

文章目录 pomyml生产者消费者 Topic类型的Exchange与Direct相比&#xff0c;都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符&#xff01; Routingkey 一般都是有一个或多个单词组成&#xff0c;多个单词…