基于Redis消息的订阅发布应用场景

原文:基于Redis消息的订阅发布应用场景

目录

  • 基于Redis消息的订阅发布应用场景
  • 1.应用背景
  • 2.困境
    • 2.1 锁表风险
    • 2.2 实时性差
    • 2.3 增加编程复杂性
    • 2.4 实时效果
  • 3.解决方案
    • 3.1 前端传值给服务端
    • 3.2 服务端通过消息传给采集控制端
  • 4.详细代码设计
    • 4.1 CSRedisCore
    • 4.2 接口设计如下
    • 4.3 接口实现如下
    • 4.4 ConfigureServices中依赖注入
    • 4.5 创建一个RedisMQ的消息对象
    • 4.6 实现层代码设计
  • 5.效果
    • 5.1 打开风扇按钮
    • 5.2 RedisDesktopManager工具中观察
    • 5.3 观察web频道输出信息
    • 5.4 观察实际风扇效果
  • 6 框架图
  • 7 GitHub

基于Redis消息的订阅发布应用场景


1.应用背景

在物联网采集管控系统中,前后端隔离的情况下,前端通过表单(比如按钮,开关,表格等)输入数据到数据库(比如MySql,通过WEBAPI服务端输入),然后采集控制端到数据库里去扫表取数据,将数据下发给物联网络中的终端设备(比如风扇控制板),从而来控制风扇的开跟关。


2.困境

采集控制端需要到数据库中去扫表。这个扫表操作会带来几个问题:

2.1 锁表风险

扫表会有锁表风险,当该DBContext被占用的时候,其他线程不能实时使用此DBContext。

2.2 实时性差

在物联网系统中,数据会非常多,比如有10000台设备,每台设备有100个采集控制点,则控制点最多可能会达到100W数据,这样去扫表,不仅占用DBContext上下文的时间会很长,而且实时性会很差。

2.3 增加编程复杂性

增加了采集服务端编程的复杂性。

2.4 实时效果

用户体验效果较差:客户点了开关控制风扇打开,然后底端设备需要很长时间才能真正打开。


3.解决方案

使用消息订阅发布方法。RabbitMQ比较重,故这里选用Redis的订阅发布功能,而且很多情况下Redis已经被作为缓存在引用,详见如下。

3.1 前端传值给服务端

前端将实时控制值以Restful API形式通过IP地址端口号+路由(比如:192.168.2.106:5000/ControlConfig)将此值传递给服务端。

3.2 服务端通过消息传给采集控制端

这里通过nuget获得CSRedisCore,来操作Redis的订阅发布功能。采集控制端订阅消息。服务端发布消息。这样操作达到了如下目的:2.1不用经过数据库消息的实时传递;2.2 实时性好;2.3 编程也简单;2.4 实时效果好。


4.详细代码设计

4.1 CSRedisCore

CSRedis 是 redis.io 官方推荐库,支持 redis-trib集群、哨兵、私有分区与连接池管理技术,简易 RedisHelper 静态类。

https://www.nuget.org/packages/CSRedisCore/

通过Nuget获得CSRedisCore库

4.2 接口设计如下

详细说明参考注释。

using CSRedis;
namespace IBMS.Infrastruct.Redis
{
    public interface IRedisMQ
    {   //连接Redis
        CSRedisClient ConnectCSRedis();
        //订阅频道
        void SubscribeCSRedis(string ChannelName);
        //把message异步发布Redis的频道
        void PublishAsyncCSRedis(string channel, string message);
        //释放Redis
        void DisposeCSRedis();
        //订阅接受下来的msg的方法
        void Rcv(string Msg, string channel);
    }
}

4.3 接口实现如下

详细说明见注释

using System;
using CSRedis;
using IBMS.Infrastruct.Appsetting;

namespace IBMS.Infrastruct.Redis
{
    public class RedisMQ : IRedisMQ
    {
        //读取连接Redis字符串
        private readonly string connectRedis = Appsettings.app(new string[] { "AppSettings", "RedisCaching", "ConnectionString" });//按照层级的顺序,依次写出来
        //定义一个Redis客户端对象
        CSRedisClient _RedisMQ;
        //连接Redis
        public CSRedisClient ConnectCSRedis()
        {
           return _RedisMQ = new CSRedisClient(connectRedis);
        }
        //释放Redis
        public void DisposeCSRedis()
        {
            _RedisMQ.Dispose();
        }
       //异步发布消息到Redis的某个频道
        public void PublishAsyncCSRedis(string channelName, string message)
        {
            _RedisMQ.PublishAsync(channelName, message);
        }

        //如果自己需要用消息值,需要想方法返回数据
        //订阅消息的处理方法
        public void Rcv(string channel, string Msg)
        {
            Console.WriteLine($"{DateTime.Now.ToLongDateString()}|Rcv:{channel},Msg:{Msg}");
        }
        //订阅消息
        public void SubscribeCSRedis(string ChannelName)
        {
            _RedisMQ.Subscribe((ChannelName, msg => Rcv(msg.Channel, msg.Body)));
        }

    }
}

4.4 ConfigureServices中依赖注入

在Startup.cs中的ConfigureServices方法进行依赖注入,如下。

services.AddScoped<IRedisMQ, RedisMQ>();

4.5 创建一个RedisMQ的消息对象

在Controller里定义创建一个消息对象,这一步的前提是需要依赖注入,依赖注入在某种意义上跟C语言的typedef有点像,将typedef会将控制权交给编译器,编译器定义新类型,然后程序运行之后就可以就可以随意通过新类型来定义对象。

IRedisMQ _RedisMQ =new RedisMQ();

4.6 实现层代码设计

        // PUT: api/ControlConfig/5
        [HttpPut]
        public async Task  Update([FromBody] ControlConfig ControlConfig)
        {
           _RedisMQ.ConnectCSRedis();
           _RedisMQ.SubscribeCSRedis("web");
           _RedisMQ.PublishAsyncCSRedis("web", $"add at{DateTime.Now}");
           _RedisMQ.PublishAsyncCSRedis("web", $"{SerializeHelper.Serialize(ControlConfig)}");
           Console.ReadKey();
           _RedisMQ.DisposeCSRedis();
        }

5.效果

5.1 打开风扇按钮

5.2 RedisDesktopManager工具中观察

在RedisDesktopManager的命令行窗口中输入PSUBSCRIBE web,进行订阅web频道,如下

5.3 观察web频道输出信息

在前端控制了风扇打开操作之后如5.1,在RedisDesktopManager观察web频道输出信息

5.4 观察实际风扇效果

风扇实时打开。

备注:采集控制端跟设备端是基于TCP长连接组网方式,协议用的是基于MODBUS的变种,比如加入我们自己的包头包尾包类型等信息,这里不做展开


6 框架图

补上一张框架图,拖到浏览器新窗口,点击放大即可清晰浏览,采用亿图制作,以便更好理解。

7 GitHub

Demo地址:

https://github.com/JerryMouseLi/RedisMQDemo.git

原文地址:https://www.cnblogs.com/lonelyxmas/p/11015953.html

时间: 2024-10-11 13:56:29

基于Redis消息的订阅发布应用场景的相关文章

Spring基于事件驱动模型的订阅发布模式代码实例详解

代码下载地址:http://www.zuidaima.com/share/1791499571923968.htm 原文:Spring基于事件驱动模型的订阅发布模式代码实例详解 事件驱动模型简介 事件驱动模型也就是我们常说的观察者,或者发布-订阅模型:理解它的几个关键点: 首先是一种对象间的一对多的关系:最简单的如交通信号灯,信号灯是目标(一方),行人注视着信号灯(多方): 当目标发送改变(发布),观察者(订阅者)就可以接收到改变: 观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的

PHP + Redis 订阅/发布 实现即时通讯功能

最近比较忙,没时间更新博客,先暂时记下,待后续补充 Redis Sub/Pub 订阅/发布 待编辑 PHP + Redis 订阅/发布 实现即时通讯 待编辑 原文地址:http://blog.51cto.com/12750968/2105579

订阅发布模式

场景概述: 有时需要将多个应用程序集成到一个框架中,这些应用程序常见的基础通信方式包含总线模式.代理模式. 或者点对点模式.一些应用程序发送多种类型的消息,其他应用程序可能更关注这些消息类型的组合. 例如,在一个金融系统存在多个应用程序管理同一客户信息的情况,存在一个客户关系管理程序(CRM)掌握客户信息. 一种典型的情况:客户信息存在于其他系统中,且这些系统执行各自客户信息管理函数来处理客户信息. 当某个面向客户的应用程序生成更新客户信息的消息,例如客户地址的修改时,CRM和其他管理客户信息的

【分布式架构】(10)---基于Redis组件的特性,实现一个分布式限流

分布式---基于Redis进行接口IP限流 场景 为了防止我们的接口被人恶意访问,比如有人通过JMeter工具频繁访问我们的接口,导致接口响应变慢甚至崩溃,所以我们需要对一些特定的接口进行IP限流,即一定时间内同一IP访问的次数是有限的. 实现原理 用Redis作为限流组件的核心的原理,将用户的IP地址当Key,一段时间内访问次数为value,同时设置该Key过期时间. 比如某接口设置相同IP10秒内请求5次,超过5次不让访问该接口. 1. 第一次该IP地址存入redis的时候,key值为IP地

Sprint Boot如何基于Redis发布订阅实现异步消息系统的同步调用?

前言 在很多互联网应用系统中,请求处理异步化是提升系统性能一种常用的手段,而基于消息系统的异步处理由于具备高可靠性.高吞吐量的特点,因而在并发请求量比较高的互联网系统中被广泛应用.与此同时,这种方案也带来了调用链路处理上的问题,因为大部分应用请求都会要求同步响应实时处理结果,而由于请求的处理过程已经通过消息异步解耦,所以整个调用链路就变成了异步链路,此时请求链路的发起者如何同步拿到响应结果,就需要进行额外的系统设计考虑. 为了更清晰地理解这个问题,小码哥以最近正在做的共享单车的IOT系统为例,给

基于Redis的消息订阅/发布

在工业生产设计中,我们往往需要实现一个基于消息订阅的模式,用来对非定时的的消息进行监听订阅. 这种设计模式在 总线设计模式中得到体现.微软以前的WCF中实现了服务总线 ServiceBus的设计模式.然并卵.WCF已经好像是上个世纪的产物................ 基于事件订阅的模式,比如 EventBus类的组件产品.但是往往设计比较复杂. 如果依赖于 Redis做事件消息推送.那就大大简化了这种设计模式,而且性能也比较客观. Redis在 2.0之后的版本中 实现了 事件推送的  pu

分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.NET Socket Tcp 技术实现的分布消息总线,也是一个简单的发布订阅框架: 并且以案例的形式为大家演示了如何使用这个分布式消息总线架构发布订阅架构模式的应用程序,在得到各位同仁的反馈的同时,大家也非常想了解订阅者离线的情况,即支持离线构发布订阅框架. 二.离线架构 不同于订阅者.发布者都同时在

2020-04-05-SpringBoot+WebSocket基于Redis订阅发布实现集群化

SpringBoot+WebSocket基于Redis订阅发布实现集群化 前面讲了单机版的websocket如何使用发送群聊(2020-03-24-springboot快速集成websocket实现群聊),那么要是部署多个服务实现集群话怎么实现呢? 由于websocket是长连接,session保持在一个server中,所以在不同server在使用websocket推送消息时就需要获取对应的session进行推送,在分布式系统中就无法获取到所有session,这里就需要使用一个中间件将消息推送到

redis的消息订阅发布介绍

1.redis的消息订阅发布: 进程间的一种消息通信模式:发送者(pub)发送信息,订阅者(sub)接收信息. 注: 图1为 三个客户端 client2.client5.client1 通过 subscribe 命令订阅 频道 channel1 ,图二为 当有新消息通过 publish 命令发送给频道 channel1时,这个消息就会被发送给订阅它的三个客户端. 2.消息订阅发布的相关命令: PSUBSCRIBE pattern [pattern...]: 订阅一个或者多个符合给定模式的频道 P