事件消息生产消费中间件-OSS.DataFlow
系统重构解耦的过程涉及不同领域服务分拆,或同一服务下实时响应部分和非响应部分分拆,分解后的各部分通过异步消息的流转传递,完成整体的业务逻辑,但是频繁的在业务层面直接调用不同消息队列的SDK,个人感觉不够简洁,最近开源一个中间件OSS.Dataflow,希望能帮到看到的同学。
OSS.Dataflow主要实现异步消息传递的过程抽象,在业务层面提供消息发布订阅的统一抽象接口,在业务逻辑分支之间,以简单的调用完成消息的传递,和具体的消息存储触发实现无关。同时,在底层的存储和触发层面提取接口,能够在系统的全局适配具体的消息基础设施。(在这些接口之上,还实现了事件处理器,通过消息的重复投放,实现事件执行的容错补充机制,这个后边文章再介绍,源代码单元测试有示例。)
一. 消息业务侧使用
OSS.Dataflow 的代码可以通过Gitee和GitHub获取,使用时可以通过Nuget直接安装,也可以通过命令行:Install-Package OSS.DataFlow
组件的使用非常简单,只需要关注:
- 消息发布者接口,由组件注册时返回,供业务方法调用传入消息体。
- 消息订阅(消费)者接口实现或委托方法,在组件注册时传入。
具体示例:
- 消息的发布订阅独立调用示例
// 全局初始化,注入订阅者实现
const string msgPSKey = "Publisher-Subscriber-MsgKey";
DataFlowFactory.RegisterSubscriber<MsgData>(msgPSKey, async (data) =>
{
// 当前通过注入消费的委托方法,也可通过接口实现
// DoSomething(data);
return true;
}); // 获取发布者接口
private static readonly IDataPublisher publisher = DataFlowFactory.CreatePublisher(); // 业务方法中发布消息
await publisher.Publish(msgPSKey,new MsgData() {name = "test"});
2. 消息的流式调用示例
// 直接注册消费实现并获取消息发布接口
private static readonly IDataPublisher _delegateFlowpusher =
DataFlowFactory.RegisterFlow<MsgData>("delegate_flow",async (data) =>
{
// 当前通过注入消费的委托方法,也可通过接口实现
// DoSomething(data);
return true;
}); // 业务方法中发布消息
await _delegateFlowpusher.Publish("normal_flow",new MsgData() {name = "test"});
如上,只需要获取发布者,并注入消费实现,即可完成整个消息的异步消费处理,同一个消息key可以注册多个消费实现,当有消息进入消费时,会并发处理。
二. 消息底层存储适配扩展
前边介绍了业务接口的使用,和具体消息队列或数据库等隔离,这是对接业务层面的使用。因为业务场景不同,不同的项目对消息的响应速度和处理机制又各有需求,所以 OSS.DataFlow 同样提供了对接消息产品的扩展接口,方便使用者适配已有消息基础设施。
1. 消息存储适配接口
对于事件消息处理,需要关注两件事情:接收存储 和 消费触发。在类库中提供了 DataFlowManager 消息流管理类,用户可以通过实现IDataPublisherProvider接口,完成具体的存储实现。
同时在不同的消息产品触发消费时(比如数据库定时任务或者RabbitMQ消费), 调用通知方法(NotifySubscriber ),来触发通过类库注册的具体的业务订阅处理。
// 消息流核心部件管理者
public static class DataFlowManager
{
/// <summary>
/// 自定义 数据流发布(存储)实现的 提供者
/// </summary>
public static IDataPublisherProvider PublisherProvider { get; set; } /// <summary>
/// 通过自定义消息触发机制通知订阅者
/// 调用时请做异常拦截,防止脏数据导致 msgData 类型错误
/// </summary>
/// <param name="msgDataKey"></param>
/// <param name="msgData">消息内容,自定义触发时,请注意和注册订阅者的消费数据类型转换安全</param>
/// <returns></returns>
public static Task<bool> NotifySubscriber(string msgDataKey, object msgData)
{
....
}
}
关于 IDataPublisherProvider
public interface IDataPublisherProvider
{
/// <summary>
/// 数据发布者
/// </summary>
/// <param name="option"></param>
/// <returns> 返回消息发布接口实现 </returns>
IDataPublisher CreatePublisher(DataPublisherOption option);
} /// <summary>
/// 数据的发布者
/// </summary>
public interface IDataPublisher
{
/// <summary>
/// 推进数据(存储具体消息队列或者数据库实现)
/// </summary>
/// <param name="dataKey"></param>
/// <param name="data"></param>
/// <returns>是否推入成功</returns>
Task<bool> Publish<TData>(string dataKey,TData data);
}
可以看到 IDataPublisher 接口负责具体的存储实现,可以根据 DataPublisherOption 的 source_name 业务属性实现对不同业务需求返回不同的具体实现。
2. 默认实现介绍
借助.Net 自身的内存消息队列,在类库中提供了默认的内部消息存储转发实现(内存级别),使用者可以自行实现扩展相关接口并进行全局配置。
内置的.Net Core消息队列, 设置了默认1个队列,最大并发为32线程。 如果需要可以通过设置DataPublisherOption的source_name,类库将会为每个source_name 创建独立的内存队列。
如果你已经看到这里,并且感觉还行的话可以在下方点个赞,或者也可以关注我的公总号(见二维码)

事件消息生产消费中间件-OSS.DataFlow的更多相关文章
- NSQ源码剖析——主要结构方法和消息生产消费过程
目录 1 概述 2 主要结构体及方法 2.1 NSQD 2.2 tcpServer 2.3 protocolV2 2.4 clientV2 2.5 Topic 2.6 channel 3 启动过程 4 ...
- Spring整合ActiveMQ,实现队列主题消息生产消费
1.引入依赖 pom.xml 1 <!-- activemq --> 2 <dependency> 3 <groupId>org.springframework&l ...
- 消息抽象层设计和实现-OSS.DataFlow
前面已经介绍了消息生产消费中间类库(OSS.DataFlow)的简单使用,这篇主要介绍内部的设计实现.主要内容包含: 1. 消息生产消费的抽象设计. 2. 具体使用示例 一. 消息生产消费的抽象设计. ...
- Kafka创建&查看topic,生产&消费指定topic消息
启动zookeeper和Kafka之后,进入kafka目录(安装/启动kafka参考前面一章:https://www.cnblogs.com/cici20166/p/9425613.html) 1.创 ...
- Dyno-queues 分布式延迟队列 之 生产消费
Dyno-queues 分布式延迟队列 之 生产消费 目录 Dyno-queues 分布式延迟队列 之 生产消费 0x00 摘要 0x01 前情回顾 1.1 设计目标 1.2 选型思路 0x02 产生 ...
- kafka生产消费原理笔记
一.什么是kafka Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性 ...
- Spring Cloud Stream如何处理消息重复消费?
最近收到好几个类似的问题:使用Spring Cloud Stream操作RabbitMQ或Kafka的时候,出现消息重复消费的问题.通过沟通与排查下来主要还是用户对消费组的认识不够.其实,在之前的博文 ...
- ActiveMQ消息的消费原理
消费端消费消息: 在 初识ActiveMQ 中我提到过,两种方法可以接收消息,一种是使用同步阻塞的ActiveMQMessageConsumer#receive方法.另一种是使用消息监听器Messag ...
- kafka_2.11-0.8.2.1+java 生产消费程序demo示例
Kafka学习8_kafka java 生产消费程序demo示例 kafka是吞吐量巨大的一个消息系统,它是用scala写的,和普通的消息的生产消费还有所不同,写了个demo程序供大家参考.kaf ...
随机推荐
- urllib2获取CGI请求的数据
import urllib.request as urllib2 headers = { 'Authorization': 'Basic YWRtaW46YWRtaW4=', }#需要身份验证时,在请 ...
- 让selenium规避网站的检测
在使用selenium对某些网站模拟访问的时候会被检测出来,检测出来之后就有可能拿不到我们想要的数据,那么我们怎么可以规避掉呢? 在使用谷歌浏览器的时候我们右键-检查-console-输入window ...
- 鸿蒙内核源码分析(原子操作篇) | 是谁在为原子操作保驾护航 | 百篇博客分析OpenHarmony源码 | v34.02
百篇博客系列篇.本篇为: v34.xx 鸿蒙内核源码分析(原子操作篇) | 谁在为原子操作保驾护航 | 51.c.h .o 本篇说清楚原子操作 读本篇之前建议先读鸿蒙内核源码分析(总目录)系列篇. 基 ...
- Jmeter压测学习1—第一个项目:登录
我用的是我们公司的测试环境练习的 网址:http://****:9000/login.html 账号是admin 密码:123456 一.打开Jmeter 找到安装目录:bin->Jmeter ...
- Excel备忘录
1. 导入文本文件(.txt) 2. 排序 3. 批量填充空白 选定区域,Ctrl+G,定位,空值. 输入内容,Ctrl+Enter. 4. 清除无法修改的背景色. 5. 身份证号 数字精度为15位, ...
- 简单Tab切换
延迟Tab切换,使用css中的flex布局,原生js实现.(京东首页菜单也有此延迟功能哦!) 每天进步一丢丢~~ 1.延迟Tab切换 <!DOCTYPE html> <html la ...
- 升级了 Windows 11 正式版,有坑吗?
今天磊哥去公司上班,惊喜的发现 Windows 提示更新了,并且是 Windows 11 正式版,这太让人开心了,二话不说"先升为敬". 下载更新 下载完咱就重启更新呗. Wi ...
- FFT&原根&NTT&MTT
FFT bilibili 3b1b视频讲解 核心过程: 原根 Definition 若 \(a\) 模 \(m\) 的阶等于 \(\varphi(m)\),则称 \(a\) 为模 \(m\) 的一个原 ...
- Python爬取COVID-19疫情监控实战
一.项目概述 本项目基于Python.Flask.Echarts打造的一个疫情监控系统,涉及技术: Python网络爬虫 Python与Mysql数据库交互 使用Flask构建web项目 基于Echa ...
- js计算精确度丢失问题解决
(function () { var calc = { /* 函数,加法函数,用来得到精确的加法结果 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精 ...