系统重构解耦的过程涉及不同领域服务分拆,或同一服务下实时响应部分和非响应部分分拆,分解后的各部分通过异步消息的流转传递,完成整体的业务逻辑,但是频繁的在业务层面直接调用不同消息队列的SDK,个人感觉不够简洁,最近开源一个中间件OSS.Dataflow,希望能帮到看到的同学。

  OSS.Dataflow主要实现异步消息传递的过程抽象,在业务层面提供消息发布订阅的统一抽象接口,在业务逻辑分支之间,以简单的调用完成消息的传递,和具体的消息存储触发实现无关。同时,在底层的存储和触发层面提取接口,能够在系统的全局适配具体的消息基础设施。(在这些接口之上,还实现了事件处理器,通过消息的重复投放,实现事件执行的容错补充机制,这个后边文章再介绍,源代码单元测试有示例。)

一. 消息业务侧使用

  OSS.Dataflow 的代码可以通过GiteeGitHub获取,使用时可以通过Nuget直接安装,也可以通过命令行:Install-Package OSS.DataFlow

  组件的使用非常简单,只需要关注:

  1. 消息发布者接口,由组件注册时返回,供业务方法调用传入消息体。
  2. 消息订阅(消费)者接口实现或委托方法,在组件注册时传入。

  具体示例:

  1. 消息的发布订阅独立调用示例
       // 全局初始化,注入订阅者实现
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的更多相关文章

  1. NSQ源码剖析——主要结构方法和消息生产消费过程

    目录 1 概述 2 主要结构体及方法 2.1 NSQD 2.2 tcpServer 2.3 protocolV2 2.4 clientV2 2.5 Topic 2.6 channel 3 启动过程 4 ...

  2. Spring整合ActiveMQ,实现队列主题消息生产消费

    1.引入依赖 pom.xml 1 <!-- activemq --> 2 <dependency> 3 <groupId>org.springframework&l ...

  3. 消息抽象层设计和实现-OSS.DataFlow

    前面已经介绍了消息生产消费中间类库(OSS.DataFlow)的简单使用,这篇主要介绍内部的设计实现.主要内容包含: 1. 消息生产消费的抽象设计. 2. 具体使用示例 一. 消息生产消费的抽象设计. ...

  4. Kafka创建&查看topic,生产&消费指定topic消息

    启动zookeeper和Kafka之后,进入kafka目录(安装/启动kafka参考前面一章:https://www.cnblogs.com/cici20166/p/9425613.html) 1.创 ...

  5. Dyno-queues 分布式延迟队列 之 生产消费

    Dyno-queues 分布式延迟队列 之 生产消费 目录 Dyno-queues 分布式延迟队列 之 生产消费 0x00 摘要 0x01 前情回顾 1.1 设计目标 1.2 选型思路 0x02 产生 ...

  6. kafka生产消费原理笔记

    一.什么是kafka Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性 ...

  7. Spring Cloud Stream如何处理消息重复消费?

    最近收到好几个类似的问题:使用Spring Cloud Stream操作RabbitMQ或Kafka的时候,出现消息重复消费的问题.通过沟通与排查下来主要还是用户对消费组的认识不够.其实,在之前的博文 ...

  8. ActiveMQ消息的消费原理

    消费端消费消息: 在 初识ActiveMQ 中我提到过,两种方法可以接收消息,一种是使用同步阻塞的ActiveMQMessageConsumer#receive方法.另一种是使用消息监听器Messag ...

  9. kafka_2.11-0.8.2.1+java 生产消费程序demo示例

      Kafka学习8_kafka java 生产消费程序demo示例 kafka是吞吐量巨大的一个消息系统,它是用scala写的,和普通的消息的生产消费还有所不同,写了个demo程序供大家参考.kaf ...

随机推荐

  1. 痞子衡嵌入式:MCUBootUtility v3.4发布,支持串行NAND

    -- 痞子衡维护的 NXP-MCUBootUtility 工具距离上一个大版本(v3.3.0)发布过去 4 个多月了,这一次痞子衡为大家带来了版本升级 v3.4.0,这个版本主要有几个非常重要的更新需 ...

  2. 大型项目源码集合「GitHub 热点速览 v.21.39」

    作者:HelloGitHub-小鱼干 代码,尤其是优雅规范的代码,一直都是学习编程技巧的捷径.虽然有实用的代码小片段,能拯救当前业务的燃眉之急,但是真要去提升自己的技能还是得从大型的项目,尤其是有一定 ...

  3. P5437-[XR-2]约定【拉格朗日差值,数学期望】

    正题 题目链接:https://www.luogu.com.cn/problem/P5437 题目大意 \(n\)个点的完全图,连接\(i,j\)的边权值为\((i+j)^k\).随机选出一个生成树, ...

  4. 基于SpringBoot+Mybatis plus+React.js实现条件选择切换搜索功能

    笔记/朱季谦 在写React前端逻辑时,经常遇到可以切换不同条件的列表查询功能,例如下边截图这样的,其实,这块代码基本都一个逻辑,可以一次性将实现过程记录下来,待以后再遇到时,直接根据笔记复用即可. ...

  5. Pycharm软件学生和老师可申请免费专业版激活码

    有一种邮箱,叫做教育邮箱,这东西在这个互联网的世界有很大的优惠及特权,在 Jetbrain 这里, 如果你有教育邮箱(没有教育邮箱怎么办?.edu.cn后缀的邮箱)但很多学生.甚至老师都未必有. 你只 ...

  6. Python中open和with open有什么区别?怎么用?

    open 打开文件 file=open("文件名","读写模式") 操作文件 代码段 关闭文件 file.close() 注意事项:使用open方法,文件操作完 ...

  7. Stream聚合函数

    Stream班介绍 幼稚园开学的第一天,各们家长把小朋友送到了园里,各位小朋友都你看看我,我看看你.有的嚎啕大哭,有的呆若木鸡....这里时候园长安排我拿来小本本记录入园的小朋友.... 记录小朋友 ...

  8. Jetbrains CLion 安装与激活 详解

    1. 下载与安装 1.1 下载 这里提供了三个操作系统的官网下载地址 Mac Windows Linux 进入页面后向下拉点击蓝色按钮即可下载. 1.2 安装 这里将用 MacOS 来进行示例,Win ...

  9. 基于ZooKeeper,Spring设计实现的参数系统

    一.简介 基于ZooKeeper服务端.ZooKeeper Java客户端以及Spring框架设计的用于系统内部进行参数维护的系统. 二.设计背景 在我们日常开发的系统内部,开发过程中最常见的一项工作 ...

  10. SAE助力南瓜电影7天内全面Severless

    作者:李刚(寻如),阿里云解决方案架构师 南瓜电影APP是国内领先的专注于影视精品化运营的垂直类视频产品,在移动互联网.IPTV.OTT等客户端,面向广大中产阶级精英群体,提供有异于院线及其他视频平台 ...