之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能——订阅发布

目录:
一、通过Dapr实现一个简单的基于.net的微服务电商系统

二、通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解

三、通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

四、通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布

附录:(如果你觉得对你有用,请给个star)
一、电商Demo地址

二、通讯框架地址

  惯例我们还是再老生常谈一下什么是订阅发布,订阅发布是根据设计模式之观察者模式发展出来的一种软件系统设计思想,它的核心是指“多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。假设一个系统有ABC三个模块其中BC依赖于A,当A进行改变后需要A主动调用BC进行相应改变,而观察者模式则将A的控制权剥离,A改变之后只是发送一个事件给消息总线“我改变了”,BC通过预先订阅该主题而获取到A的状态变化,再进行自身的状态变更。

强耦合调用模式

通过消息中间件订阅发布模式

  聪明的同学应该发现了,通过订阅发布其实我们是将以往强耦合的ABC通过巧妙的控制权转移的方式进行了解耦,由之前的BC依赖于A改为了BC依赖于消息组件,通过消息组件接受到A的消息后进行分发,这样设计系统的目的当然有好有坏,好处是这会大大提高A的吞吐量,假设以往操作ABC总耗时300ms平均单个操作耗时100ms,通过解耦后A耗时100ms后就可以马上返回线程。那坏处是什么呢,由于对BC进行了解耦往往状态的一致性就得不到保障了。当ABC处于同一个粗粒度的原子操作里(比如数据库事务操作、比如lock锁),我们很容易控制ABC的强一致性,ABC有一个操作失败可以很轻松的进行回滚而不用影响我们持久化设备的数据一致。另外由于需要依赖第三方中间件,整个系统的健壮性是会有一定影响的。另外还需要考虑订阅方消费失败、异常后如何处理。关于这部分内容这里我们就不展开了,如果大家确实感兴趣,推荐大家看看国内开源作者@杨晓东写的.netcore分布式一致性解决方案CAP,地址:https://github.com/dotnetcore/cap

  OK,老生常谈的部分唠完,咱今天就来唠唠在Dapr中如何实现订阅发布的。通过上面的部分大家应该知道如果要实现一个进程间的订阅发布系统,我们需要准备很多东西,其中一个是事件总线,事件总线的作用是让事件发布者可以通过该模块进行事件发布。第二个需要选型一个消息组件,第三需要订阅器对订阅特定类型组件的技术支持。由于每一种组件其协议和接口实现方式都不同,在传统的订阅发布设计中我们往往需要对某种特定类型的消息组件在基础设施层进行相应的SDK集成,通过为业务层提供事件总线接口和订阅接口来进行技术解耦。就算做到了业务系统中不耦合技术实现,往往我们也很难替换消息组件。而Dapr在这方面为开发者集成了相当一部分的主流订阅发布组件(通过该支持列表可预览支持)。同时在业务层面是完全基于http+谓词的形式来实现订阅发布的。这就大大降低了引入SDK产生的成本。

  订阅发布的API如下:

POST http://localhost:<daprPort>/v1.0/publish/<pubsubname>/<topic>[?<metadata>]
GET http://localhost:<appPort>/dapr/subscribe

  稍微说一下这两个接口的含义,第一个接口告诉sidecar,我们将会调用某个已申明的类型为pubsub的component发送我们的事件到特定的topic

  第二个接口是告诉sidecar我们当前这个服务会订阅哪些topic,我们提供的订阅器入口地址是什么,我们只接受哪一个component发布的数据

  也就是说和服务调用一样,我们只需要一个weapi+httpclient就可以实现一个订阅发布模式而,其他的一切都交给dapr好了。

  现在我们来看看如何实现它,首先我们还是需要选一个特定的订阅发布组件,这里我就选择redis,通过redis5.0新增的stream来做订阅发布。搭建redis这里不赘述,搭建好之后,我们需要创建一个dapr的特定CRD Component来申明引用该组件,其申明yaml文件如下

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: pubsub
spec:
type: pubsub.redis
version: v1
metadata:
- name: redisHost
value: redis.infrastructure.svc.cluster.local:6379

  其中的type是由Dapr预定义的,可以参考这里,不要随意改变。metadata是对组件的一组描述包括其地址、账号密码等等,由于是演示这里我就直接使用k8s创建了一个无密码的redis pod并暴露其6379端口到svc。当我们创建好并通过kubectl apply -f x.yaml后,可以在dashboard的Componsents页面观察是否已经创建成功

  基础设施准备完毕,接下来就是打开我们的项目看看如何实现订阅发布了。首先我们还是要把上一章的解决方案打开,上一章不是通过client发起一个对service的调用吗,今天我们反着来演示,我们在client创建一个订阅器,当clientsample调用servicesample时让servicesample发布一个事件,由该订阅器订阅并打印出文本到控制台。

  首先我们在clientsample创建一个订阅器,订阅器类必须继承ieventhandle接口,其订阅方法体必须添加EventHandlerFunc注解并申明需要订阅的主题(topic),订阅器接收参数必须以EventHandleRequest<T>的方式接收,否则反序列化器可能会收不到请求。最后ack必须以DefaultEventHandlerResponse.Default的方式返回,否则事件总线会认为本次订阅器消费失败,会重复推送。

  需要在我们的hostbuilder里注册这个对象到ioc容器:

  接着我们在RPC接口项目创建事件Data HelloEventData,其中之包含一个演示用的words字段(图略)。

  接下来我们在上一章的HelloServiceImpl中注入一个事件总线,并发送事件:

  一切就绪,我们重新按照上一章的内容打包并部署,然后开启postman和控制台日志观看结果,可以看到我们的clientsample发起一个服务调用后,我们的serversample回调并发送了事件,而clientsample成功订阅到了该事件并消费掉了。

  今天的分享到此为止,demo只是对dapr订阅发布最基础功能的演示,真正到生产环境还需要客服诸多问题来提高系统健壮,系统建设是一个长期持续的过程。欢迎大家评论区留言讨论~ 下期我们将讲一下dapr里如何做状态管理以及actor模型

  

通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布的更多相关文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统

    本来想在Dpar 1.0GA时发布这篇文章,由于其他事情耽搁了放到现在.时下微服务和云原生技术如何如荼,微软也不甘示弱的和阿里一起适时推出了Dapr(https://dapr.io/),园子里关于da ...

  2. 通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解

    首先感谢张队@geffzhang公众号转发了上一篇文章,希望广大.neter多多推广dapr,让云原生更快更好的在.net这片土地上落地生根. 目录:一.通过Dapr实现一个简单的基于.net的微服务 ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

    目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实现一个简单的基于.net的微服务电商系统(二)--通讯框架讲解 三.通过Dapr实现一个简单的基于.net的微服务电 ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理

    状态管理和上一章的订阅发布都算是Dapr相较于其他服务网格框架来讲提供的比较特异性的内容,今天我们来讲讲状态管理. 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实 ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务

    我个人认为Actor应该是Dapr里比较重头的部分也是Dapr一直在讲的所谓"stateful applications"真正具体的一个实现(个人认为),上一章讲到有状态服务可能很 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流

    在一般的互联网应用中限流是一个比较常见的场景,也有很多常见的方式可以实现对应用的限流比如通过令牌桶通过滑动窗口等等方式都可以实现,也可以在整个请求流程中进行限流比如客户端限流就是在客户端通过随机数直接 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪

    Dapr提供了一些开箱即用的分布式链路追踪解决方案,今天我们来讲一讲如何通过dapr的configuration来实现非侵入式链路追踪的 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权

    Oauth2授权,熟悉微信开发的同学对这个东西应该不陌生吧.当我们的应用系统需要集成第三方授权时一般都会做oauth集成,今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

随机推荐

  1. go-admin在线开发平台学习-2[程序结构分析]

    紧接着上一篇,本文我们对go-admin下载后的源码进行分析. 首先对项目所使用的第三方库进行分析,了解作者使用的库是否是通用的官方库可以有助于我们更快地阅读程序.接着对项目的main()方法进行分析 ...

  2. MySQL命名、设计及使用规范

    本文转载自MySQL命名.设计及使用规范 导语 最近在看MySQL相关的内容,整理如下规范,作为一名刚刚学习MySQL的菜鸟,整理的内容非常的基础,中间可能涉及到有错误的地方,欢迎批评指正,看到有错误 ...

  3. uni-app小白入门自学笔记(二)

    码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14429616.html 目录 码文不易啊,转载请带上本文链接呀,感谢感谢 https ...

  4. 前端axios传递一个包含数组的对象到后台,后台可以用String接收,也可以用List集合接收

    前端代码: data() { return { listQuery: { date: [], } }}, //查询列表信息getList() { if (this.listQuery.date == ...

  5. GMS的概述

    1 GMS GMS全称为GoogleMobile Service,即谷歌移动服务. GMS是Google所提供的一系列移动服务,包括开发用的一系列服务和用户所用的Google Apps. Maps与L ...

  6. vue3 一些关键属性

    环境搭建 尤大开发了一个项目构建工具vite npm init vite-app <project-name> cd <project-name> npm install np ...

  7. SpringCloud组件

    1.Hystrix 1.1.简介 Hystrix,英文意思是豪猪,全身是刺,看起来就不好惹,是一种保护机制. Hystrix也是Netflix公司的一款组件. 主页:https://github.co ...

  8. Hi3559AV100外接UVC/MJPEG相机实时采图设计(一):Linux USB摄像头驱动分析

    下面将给出Hi3559AV100外接UVC/MJPEG相机实时采图设计的整体流程,主要实现是通过V4L2接口将UVC/MJPEG相机采集的数据送入至MPP平台,经过VDEC.VPSS.VO最后通过HD ...

  9. 微信小程序一周时间表

    <view class="dateView"> <image class="dateLeft" bindtap="prevWeek& ...

  10. java 流程控制学习

    https://www.kuangstudy.com/course 用户交互Scanner import java.util.Scanner; public class Demo01 { public ...