什么是发布-订阅

发布订阅是一种众所周知并被广泛使用的消息传送模式,常用在微服务架构的服务间通信,高并发削峰等情况。但是不同的消息中间件之间存在细微的差异,项目使用不同的产品需要实现不同的实现类,虽然是明智的决策,但必须编写和维护抽象及其基础实现。此方法需要复杂、重复且容易出错的自定义代码。

Dapr为了解决这种问题,提供开箱即用的消息传送抽象和实现,封装在 Dapr 构建基块中。业务系统只需调用跟据Dapr的要求实现订阅发布即可。

工作原理

Dapr 发布&订阅构建基块提供了一个与平台无关的 API 框架来发送和接收消息。

服务将消息发布到指定主题, 业务服务订阅主题以使用消息。

服务在 Dapr sidecar 上调用 pub/sub API。然后,sidecar 调用预定义 Dapr pub/sub 组件。

任何编程平台都可以使用 Dapr 本机 API 通过 HTTP 或 gRPC 调用构建基块。若要发布消息,请进行以下 API 调用:

http://localhost:<dapr-port>/v1.0/publish/<pub-sub-name>/<topic>

上述调用中有几个特定于 Dapr 的 URL 段:

  • <dapr-port> 提供 Dapr sidecar 侦听的端口号。

  • <pub-sub-name> 提供所选 Dapr pub/sub 组件的名称。

  • <topic> 提供消息发布到的主题的名称。

设置发布订阅组件

Dapr 为 Pub/Sub 提供很多支持的组件,例如 Redis 和 Kafka 等。支持组件详见 链接

在win10上的自承载的Dapr中,默认在 %UserProfile%\.dapr\components\pubsub.yaml 中使用redis作为了pub/sub组件,dapr run一个app时,使用默认组件作为pub/sub组件

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: pubsub
spec:type: pubsub.redisversion: v1metadata:- name: redisHostvalue: localhost:6379- name: redisPasswordvalue: ""

订阅主题

Dapr 允许两种方法订阅主题:

  • 声明式,其中定义在外部文件中。

  • 编程方式,订阅在用户代码中定义

1.声明式订阅

在默认组件目录 %UserProfile%\.dapr\components\pubsub.yaml 中新建subscription.yaml文件,并写入以下内容

apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:name: myevent-subscription
spec:topic: test_topicroute: /TestPubSubpubsubname: pubsub
scopes:
- frontend

上面的示例显示了 test_topic主题的事件订阅,使用组件 pubsub

  • route 告诉 Dapr 将所有主题消息发送到应用程序中的 /TestPubSub 端点。

  • scopes 为 FrontEnd启用订阅

现在需要在FrontEnd项目中定义接口TestSub,在FrontEnd中新建TestPubSubController

using Dapr.Client;using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;using System.IO;
using System.Text;
using System.Threading.Tasks;namespace FrontEnd.Controllers
{[Route("[controller]")][ApiController]public class TestPubSubController : ControllerBase{private readonly ILogger<TestPubSubController> _logger;private readonly DaprClient _daprClient;public TestPubSubController(ILogger<TestPubSubController> logger, DaprClient daprClient){_logger = logger;_daprClient = daprClient;}[HttpPost]public ActionResult Post(){Stream stream = Request.Body;byte[] buffer = new byte[Request.ContentLength.Value];stream.Position = 0L;stream.ReadAsync(buffer, 0, buffer.Length);string content = Encoding.UTF8.GetString(buffer);return Ok(content);}[HttpGet("pub")]public async Task<ActionResult> PubAsync(){var data = new WeatherForecast();await _daprClient.PublishEventAsync<WeatherForecast>("pubsub", "test_topic", data);return Ok();}}
}

需要在Startup的Configure中开启重复读取Body才能读取到数据

app.Use((context, next) =>{context.Request.EnableBuffering();return next();});

启动FrontEnd

dapr run --dapr-http-port 3501 --app-port 5001  --app-id frontend dotnet  .\FrontEnd\bin\Debug\net5.0\FrontEnd.dll

调用 pub API发布消息

查看订阅情况,订阅消息消费成功

2.编程式订阅

为了防止声明式订阅的影响,需要先把目录<%UserProfile%\.dapr\components\pubsub.yaml>中subscription.yaml文件删除

TestPubSubController新增Api Sub

[Topic("pubsub", "test_topic")][HttpPost("sub")]public async Task<ActionResult> Sub(){Stream stream = Request.Body;byte[] buffer = new byte[Request.ContentLength.Value];stream.Position = 0L;stream.ReadAsync(buffer, 0, buffer.Length);string content = Encoding.UTF8.GetString(buffer);_logger.LogInformation("testsub" + content);return Ok(content);}

在Startup的Configure方法中新增中间件

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{// ...app.UseCloudEvents();app.UseEndpoints(endpoints =>{endpoints.MapSubscribeHandler();// ...});
}

启动FrontEnd

dapr run --dapr-http-port 3501 --app-port 5001  --app-id frontend dotnet  .\FrontEnd\bin\Debug\net5.0\FrontEnd.dll

调用API发布消息

查看订阅情况,订阅消息消费成功

通过DapreCLI同样可以发布消息

dapr publish --publish-app-id frontend --pubsub pubsub --topic test_topic --data '{"date":"0001-01-01T00:00:00","temperatureC":0,"temperatureF":32,"summary":null}'

查看订阅情况,订阅消息消费成功

相关文章:

Dapr + .NET 实战(四)发布和订阅相关推荐

  1. Dapr + .NET 实战(十四)虚拟机集群部署 mDNS + Consul

    前面我们说了在单机模式下和K8S集群下的Dapr实战,这次我们来看看如何在不使用K8S的情况下,在一个传统的虚拟机集群里来部署Dapr. 1.环境准备 我们准备两台centos7虚拟机 Dapr1:1 ...

  2. Redis入门(2):五大数据类型(key,string,list,set,sortset)将其实战,配置文件详解,发布与订阅

    五大数据类型 redis常见数据类型操作命令:http://www.redis.cn/commands.html Redis键(key) 命令 描述 keys * 查看当前库所有key (匹配:key ...

  3. 面向.NET开发人员的Dapr——发布和订阅

    目录: 面向.NET开发人员的Dapr--前言 面向.NET开发人员的Dapr--分布式世界 面向.NET开发人员的Dapr--俯瞰Dapr 面向.NET开发人员的Dapr--入门 面向.NET开发人 ...

  4. 【cartographer_ros】四: 发布和订阅里程计odom信息

    上一节介绍了激光雷达Scan传感数据的订阅和发布. 本节会介绍里程计Odom数据的发布和订阅.里程计在cartographer中主要用于前端位置预估和后端优化. 官方文档: http://wiki.r ...

  5. Dapr + .NET 实战(十三)跨语言开发

    欢迎大家参加4小时Dapr+.NET 5的实战课程 课程链接     https://ke.qq.com/course/4000292?tuin=1271860f 因为基于Dapr的服务架构是不限语言 ...

  6. Dapr + .NET 实战(十二)服务调用之GRPC

    欢迎大家参加4小时Dapr+.NET 5的实战课程 课程链接     https://ke.qq.com/course/4000292?tuin=1271860f 什么是GRPC gRPC 是一种与语 ...

  7. Dapr + .NET 实战(十-终篇)K8S运行Dapr

    工作原理 为了实现在k8s上安装Dapr,Dapr需要部署dapr-sidecar-injector.dapr-operator.dapr-placement和dapr-sentry服务. dapr- ...

  8. Dapr + .NET 实战(七)Secrets

    什么是Secrets 应用程序通常会通过使用专用的存储来存储敏感信息,如连接字符串.密钥等. 通常这需要建立一个密钥存储,如Azure Key Vault.Hashicorp等,并在那里存储应用程序级 ...

  9. Dapr + .NET 实战(八)服务监测

    服务监测 分布式服务性能指标,链路追踪,运行状况,日志记录都很重要,我们日常开发中为了实现这些功能需要集成很多功能,替换监控组件时成本也很高. Dapr 可观测性模块将服务监测与应用程序分离.它自动捕 ...

  10. Dapr + .NET 实战(六)绑定

    什么是绑定 处理外部事件或调用外部接口的功能就是绑定,绑定可以提供以下好处: 避免连接到消息系统 ( 如队列和消息总线 ) 并进行轮询的复杂性 聚焦于业务逻辑,而不是如何与系统交互 使代码不受 SDK ...

最新文章

  1. Java中 实体类 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念
  2. ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type
  3. nginx实现web负载均衡
  4. oem718d 基准站设置_RTK基站设置、7参数、测点、放线等操作教程,文末有视频
  5. 单页面与多页面的区别与优缺点?
  6. 案例 | 新零售如何精细化运营?百联全渠道经验谈
  7. ORACLE TEXT DATASTORE PREFERENCE(五)
  8. 使用VirtualEnvWrapper隔离python项目的库依赖
  9. 工作总结10:解决vuex刷新数据消失
  10. 3.3栈与递归的实现
  11. android byte转string_唠点儿你不一定知道的Android小知识
  12. 计算机工程与应用 格式,计算机工程与应用模板.doc
  13. 2018-10-16
  14. linux之删除vi残留的swp文件
  15. 光储充一体化充电站_忙时给车充电 闲时上网供电 多能电动车充电站在乐清投用...
  16. java各知识点详细总结毕向东_毕向东课程笔记——Java语言基础
  17. 用requests库和BeautifulSoup4库爬取新闻列表
  18. 使用Jmeter做性能测试
  19. python图像识别植物识别_python 植物识别 error_code
  20. c语言辅音字符怎么表示,C 语言实例 - 判断元音/辅音

热门文章

  1. Exchange Powershell查看用户最后登陆邮箱时间
  2. css判断不同分辨率显示不同宽度布局实现自适应宽度
  3. HDU 3966 Aragorn's Story (树链剖分+线段树)
  4. 安装mongoDB遇见的一个路径问题
  5. Python集合和函数
  6. SQL JOIN连接分类[转]
  7. 正则表达式(括号)、[中括号]、{大括号}的区别
  8. MVC-控制器向View传值的三种方法
  9. Rails 开发小贴士积累
  10. 使用PowerShell配置Microsoft Teams