Dapr牵手.NET学习笔记:发布-订阅
queue,是很好的削峰填谷工具,在业内也是主流;发布订阅,可以有效的解耦两个应用,所以dapr把他们进行了有效的封装,我们使用起来更简单高效。
本篇的案例是下完订单后,会把消息发布到redis(当然也可以是其他)中,通知系统和支付系统会订单这个消息,同时,通知系统和支付系统的两个实例中,只会有一个实例接收到这个消息,进行处理,调用示意图如下:
项目结构如下:
一、配置
用docker-compose部署,docker-compose.yml内容
version: '3.4'services:#┌────────────────────────────────┐#│ ordersystem app + Dapr sidecar │#└────────────────────────────────┘ordersystem:image: ${DOCKER_REGISTRY-}ordersystemdepends_on:- redis- placementbuild:context: ../dockerfile: OrderSystem/Dockerfileports:- "3500:3500"volumes: - ../OrderSystem:/OrderSystem networks:- b2c-daprordersystem-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "order", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components"]depends_on:- ordersystemnetwork_mode: "service:ordersystem"volumes: - ../components:/components #┌───────────────────────────────────┐#│ paymentsystem1 app + Dapr sidecar │#└───────────────────────────────────┘ paymentsystem1:image: ${DOCKER_REGISTRY-}paymentsystembuild:context: ../dockerfile: PaymentSystem/Dockerfileports:- "3601:3500"volumes: - ../PaymentSystem:/PaymentSystem networks:- b2c-dapr paymentsystem1-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "pay", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components" ]depends_on:- paymentsystem1network_mode: "service:paymentsystem1"volumes: - ../components:/components #┌───────────────────────────────────┐#│ paymentsystem2 app + Dapr sidecar │#└───────────────────────────────────┘ paymentsystem2:image: ${DOCKER_REGISTRY-}paymentsystembuild:context: ../dockerfile: PaymentSystem/Dockerfilevolumes: - ../PaymentSystem:/PaymentSystem ports:- "3602:3500"networks:- b2c-dapr paymentsystem2-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "pay", "-app-port", "80" ,"-placement-host-address", "placement:50006","-components-path","/components"]depends_on:- paymentsystem2network_mode: "service:paymentsystem2"volumes: - ../components:/components #┌───────────────────────────────────┐#│ noticesystem1 app + Dapr sidecar │#└───────────────────────────────────┘ noticesystem1:image: ${DOCKER_REGISTRY-}noticesystembuild:context: ../dockerfile: NoticeSystem/Dockerfileports:- "3701:3500"volumes: - ../NoticeSystem:/NoticeSystem networks:- b2c-dapr noticesystem1-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "notice", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components" ]depends_on:- noticesystem1network_mode: "service:noticesystem1"volumes: - ../components:/components #┌───────────────────────────────────┐#│ noticesystem2 app + Dapr sidecar │#└───────────────────────────────────┘ noticesystem2:image: ${DOCKER_REGISTRY-}noticesystembuild:context: ../dockerfile: NoticeSystem/Dockerfileports:- "3702:3500"volumes: - ../NoticeSystem:/NoticeSystem networks:- b2c-dapr noticesystem2-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "notice", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components" ]depends_on:- noticesystem2network_mode: "service:noticesystem2"volumes: - ../components:/components #┌────────────────────────┐#│ Dapr placement service │#└────────────────────────┘ placement:image: "daprio/dapr"command: ["./placement", "-port", "50006"]ports:- "50006:50006"networks:- b2c-dapr#┌───────────────────┐#│ Redis state store │#└───────────────────┘ redis:image: "redis:latest"ports:- "6380:6379"networks:- b2c-dapr
networks:b2c-dapr:
pubsub.yaml(在components文件夹下 )内容是默认,如下
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: pubsub
spec:type: pubsub.redisversion: v1metadata:- name: redisHostvalue: redis:6379- name: redisPasswordvalue: ""
订阅配置文件如下subscription.yaml(在components文件夹下 )
apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:name: myevent-subscription
spec:topic: orderCompleteroute: /ordercompletepubsubname: pubsub
scopes:
- pay
- notice
二、代码
OrderSystem项目的appsettings.json
"PublishUrl": "http://localhost:3500/v1.0/publish/pubsub/orderComplete"
OrderSystem项目的发布方法
[HttpGet("/orderpub/{orderno}")]public async Task<IActionResult> OrderPub(string orderno){try{_logger.LogInformation($"Order,publish");await Task.Delay(400);var client = _clientFactory.CreateClient();var stringContent = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(new { OrderNo = orderno, Amount = 30000, OrderTime = DateTime.UtcNow}), System.Text.Encoding.UTF8, "application/json");_logger.LogInformation(stringContent.ToString());var content = await client.PostAsync(_publishUrl, stringContent);return new JsonResult(new { order_result = "Order success,and publish", pay_result = content });}catch (Exception exc){_logger.LogCritical(exc, exc.Message);return new JsonResult(new { order_result = "Order success,and publish,pay exception", message = exc.Message });}}
PaymentSystem和NoticeSystem项目中的订阅实现
两个实体类
public class PubBody
{public string id { get; set; }public string source { get; set; }public string pubsubname { get; set; }public string traceid { get; set; }public PubOrder data { get; set; }public string specversion { get; set; }public string datacontenttype { get; set; }public string type { get; set; }public string topic { get; set; }
}public class PubOrder
{public string OrderNo { get; set; }public decimal Amount { get; set; }public DateTime OrderTime { get; set; }
}
NoticeSystem和PaymentSystem两个项目中的订阅方法如下
[HttpPost("/ordercomplete")]public async Task<IActionResult> OrderComplete(){try{_logger.LogInformation("PaymentSystem OrderComplete runing……");using var reader = new StreamReader(Request.Body, System.Text.Encoding.UTF8);var content = await reader.ReadToEndAsync();var pubBody = Newtonsoft.Json.JsonConvert.DeserializeObject<PubBody>(content);_logger.LogInformation($"--------- HostName:{Dns.GetHostName()},OrderNo:{pubBody?.data.OrderNo},OrderAmount:{pubBody?.data.Amount},OrderTime:{pubBody?.data.OrderTime} -----------");await Task.Delay(200);_logger.LogInformation($"subscription pay complete");_logger.LogInformation($"return SUCCESS");return new JsonResult(new{Status = "SUCCESS"});}catch (Exception exc){_logger.LogCritical(exc, exc.Message);_logger.LogInformation($"return RETRY");return new JsonResult(new{Status = "RETRY"});}}
三、发布测试
进入在B2C目发,用命令行启动docker compose
docker-compose up -d
可以测试了,调用OrderSystem的对外地址,下订单NO0001,和NO0002
localhost:3500/v1.0/invoke/order/method/orderpub/NO0001和
localhost:3500/v1.0/invoke/order/method/orderpub/NO0001
查看容器noticesystem1
查看容器noticesystem2
查看容器paymentsystem1
查看容器paymentsystem2
NoticeSystem和PaymentSystem同时订阅OrderSystem项目的发布orderComplete,两个实例会轮询处理订阅结果。Dapr就这样,把复杂的发布订阅,封装成一个api一样的简单调用和接收,项目中没有一点的痕迹。
Dapr牵手.NET学习笔记:发布-订阅相关推荐
- Dapr牵手.NET学习笔记:状态管理之docker-compose发布
Dapr牵手.NET学习笔记:想入非非的服务调用 Dapr牵手.NET学习笔记:跨物理机负载均衡服务调用 Dapr牵手.NET学习笔记:用docker-compose部署服务 说明:为了给出demo的 ...
- Dapr牵手.NET学习笔记:开篇
dapr,一个为分布式应用程序的运行时,为开发者在对接分布式组件时,提供了便利.使用dapr带来的好处可扩展性,因为它是通过sidecar的理概念来集成其他运行时的.同时dapr还提供了多种语言的SD ...
- 【Redis数据库】命令学习笔记——发布订阅、事务、脚本、连接等命令汇总
本篇基于redis 4.0.11版本,学习发布订阅.事务.脚本.连接的相关命令. Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 序号 ...
- Dapr牵手.NET学习笔记:可观测性-分布式跟踪
分布式跟踪在dapr里是开箱即用的,不需要对应用作任何一丁点的侵入式编程.之前的开发,如果想实现分式跟踪,就得在应用中埋点,这是一个与业务无关系的动作.dpar通过sidecar可以轻松做到这点,从而 ...
- Dapr牵手.NET学习笔记:绑定
绑定有点像订阅发布,但又不一样,绑定更简单,绑定输出(调用方)-绑定输入(被调用方). 本例是用docker compose编排,并且用rabbitMQ来支持,因为rabbitMQ支持输入和输出绑定. ...
- Dapr牵手.NET学习笔记:Actor一个场景
接上一篇最后的场景,为了解决相同帐户并发引起的数据库行级锁,可以引入Actor的串机制,相同ActorID的实例,串行,这样就能在应用层把读取余额的资源争抢解决掉,剩下的工作就是一定时间间隔,把内存中 ...
- Dapr牵手.NET学习笔记:Actor小试
Actor模型是一种避免线程共享数据,相同Actor实体串行化的方案,所以不便dapr的其他功能,几乎都是非编程入侵的,相反,Dapr Acror深度定制的,关于Actor,.net中有一些通用框架, ...
- Dapr牵手.NET学习笔记:状态管理进阶(二)
为了防止并发对数据修改造成差异,dapr使用了etag标签来作为版本号,对数据修改进行验证. 下面是对etag的一个demo appsettings.json中的url配置 "StateUr ...
- Dapr牵手.NET学习笔记:状态管理进阶(一)
在上一篇文章中说到,dapr默认的状态是不可能跨appid的,也就是只能在相同的应用内访问自己设置的状态数据,dapr支持三种状态的共享配置:appid,nam,none,是通过修改component ...
最新文章
- 找出没有相邻的1的二进制数的个数---2013年2月17日
- 干货 | 云计算时代携程的网络架构变迁
- redis 后台运行_第一章 1.3Linux下安装Redis
- 计算机应用基础2010版知识点,2010计算机应用基础选择题(含答案版)重点.doc
- HTML meter控件
- Bootstrap 折叠插件Collapse 调用方式
- tp5使用layui表格_tp5+layui增、删、改、查。
- python主成分分析法实训报告_基于 python 的主成分分析步骤及应用实例
- R语言:ggplot2精细化绘图——以实用商业化图表绘图为例
- ros开发增加clion常用模板及初始化配置(三)
- 如何利用工业大数据降本增效
- 2.5. 标准路由器:Zend_Controller_Router_Rewrite
- Cesium笔记(3):基本控件简介—ImageryProvider地图瓦片地图配
- Windows内核的基本概念
- 计算机mac地址设置路由器,路由器设置:如何查看电脑/手机的MAC地址?
- GIS数据转换器(栅格)(栅格向矢量网格和栅格向栅格的转换)
- IE疑难杂症之已取消网页导航--该站点安全证书的吊销信息不可用
- Revit插件中的“喷淋对齐”“链接CAD”功能操作
- 台式计算机能不能安装蓝牙驱动,蓝牙驱动怎么安装_台式电脑怎么安装蓝牙驱动...
- 联想笔记本:安装适配自己电脑的驱动