第 5 篇:RabbitMQ 消息队列与闸机通信设计

RabbitMQ 是一款开源的消息队列中间件(Message Queue,MQ),基于 Erlang 语言开发,遵循 AMQP(Advanced Message Queuing Protocol,高级消息队列协议) 标准,主要用于在分布式系统中实现消息的可靠传递,核心价值是解耦系统组件、削峰填谷、异步通信等。

RabbitMQ

一、核心定位:为什么需要 RabbitMQ?

RabbitMQ 作为“中间件”,通过存储转发消息的方式,让发送方(生产者)和接收方(消费者)“解耦”:生产者只需要把消息发给 RabbitMQ,不必关心谁来接收;消费者从 RabbitMQ 取消息,不必关心谁发来的。双方通过消息间接通信,提高系统灵活性和稳定性。

二、核心概念与架构

RabbitMQ 的工作流程基于“生产者-交换机-队列-消费者”的链路,核心组件包括:

  1. 生产者(Producer):发送消息的应用(如订单系统生成“新订单”消息)。
  2. 交换机(Exchange):接收生产者的消息,根据“路由规则”将消息转发到对应的队列。交换机是 RabbitMQ 灵活路由的核心,有 4 种类型:
    • 直连交换机(Direct Exchange):消息的“路由键”(Routing Key)必须与队列绑定的“绑定键”完全匹配才转发(如“order.pay”只能匹配“order.pay”)。
    • 主题交换机(Topic Exchange):支持通配符匹配(* 匹配一个单词,# 匹配多个单词),适合按“主题”分类消息(如“order.*”可匹配“order.pay”“order.cancel”)。
    • 扇形交换机(Fanout Exchange):忽略路由键,将消息广播到所有绑定的队列(适合“一对多”通知,如“系统通知”需要所有模块接收)。
    • Headers 交换机:不依赖路由键,根据消息头(Headers)的键值对匹配(较少用)。
  3. 队列(Queue):存储消息的缓冲区,消息最终会进入队列等待消费者取走。队列是“持久化”的(可配置),即使 RabbitMQ 重启,未消费的消息也能保留。
  4. 绑定(Binding):连接交换机和队列的“规则”,包含“绑定键”(Binding Key),用于交换机判断消息该转发到哪个队列。
  5. 消费者(Consumer):从队列中获取并处理消息的应用(如支付系统接收“新订单”消息并处理支付)。
三、工作流程(核心逻辑)
  1. 生产者发送消息时,会指定消息的“路由键”(Routing Key)和目标交换机。
  2. 交换机根据自身类型和“绑定规则”(绑定键),将消息转发到匹配的队列。
  3. 队列存储消息,等待消费者连接并获取。
  4. 消费者从队列中取走消息并处理,处理完成后向 RabbitMQ 发送“确认信号(Ack)”,RabbitMQ 收到后删除队列中的该消息(避免重复消费)。
一、引入消息队列的作用

闸机控制涉及设备通信,采用同步调用易受网络波动影响。引入 RabbitMQ 可实现:

  • 系统解耦:闸机控制服务与设备通信模块分离,便于独立扩展。

  • 异步处理:开闸、关闸命令异步发送,不阻塞主线程。

  • 可靠性保障:消息持久化,避免命令丢失。

二、RabbitMQ 核心组件设计

在这里插入图片描述

  1. 交换机(Exchange)
  • gate.control.exchange:处理闸机控制命令(开闸 / 关闸)。

  • access.record.exchange:处理通行记录存储。

  1. 队列(Queue)
  • gate.command.queue:绑定闸机控制交换机,接收命令。

  • record.save.queue:绑定记录交换机,异步保存通行信息。

  1. 消息模型
// 闸机命令消息public class GateCommand{public string GateCode { get; set; } // 目标闸机编码public int CommandType { get; set; } // 1-开闸/0-关闸public DateTime Timestamp { get; set; } = DateTime.Now;}
三、RabbitMQ 集成实现
  1. 安装依赖
dotnet add package RabbitMQ.Client
  1. 封装消息服务
public class RabbitMQService : IDisposable{private readonly IConnection _connection;private readonly IModel_channel;public RabbitMQService(string connectionString){var factory = new ConnectionFactory { Uri = new Uri(connectionString) };_connection = factory.CreateConnection();_channel = _connection.CreateModel();// 声明交换机和队列_channel.ExchangeDeclare("gate.control.exchange", ExchangeType.Direct, durable: true);_channel.QueueDeclare("gate.command.queue", durable: true, exclusive: false, autoDelete: false);_channel.QueueBind("gate.command.queue", "gate.control.exchange", "gate.command");}// 发送闸机命令public void PublishGateCommand(GateCommand command){var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(command));_channel.BasicPublish(exchange: "gate.control.exchange",routingKey: "gate.command",basicProperties: null,body: body);}// 消费命令(闸机端实现)public void ConsumeGateCommands(Action<GateCommand> handler){var consumer = new EventingBasicConsumer(_channel);consumer.Received += (model, ea) => {var body = ea.Body.ToArray();var command = JsonConvert.DeserializeObject\<GateCommand>(Encoding.UTF8.GetString(body));handler(command);_channel.BasicAck(ea.DeliveryTag, multiple: false);};_channel.BasicConsume(queue: "gate.command.queue", autoAck: false, consumer: consumer);}public void Dispose(){_channel?.Close();\connection?.Close();}}
四、闸机命令处理流程
  1. 验证通过后,系统向 RabbitMQ 发送开闸命令(CommandType=1)。

  2. 闸机端消费者接收命令,执行物理开闸操作。

  3. 开闸成功后,触发票证状态更新回调。

  4. 延迟 5 秒后,系统发送关闸命令(CommandType=0),完成一次控制流程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/92999.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/92999.shtml
英文地址,请注明出处:http://en.pswp.cn/web/92999.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 常用命令大全:覆盖日常 99% 操作需求

1、基本命令 pwd&#xff1a;显示当前工作目录的绝对路径&#xff0c;例如在复杂目录结构中快速确认位置&#xff0c;执行后会输出类似/home/user/documents的结果。 cd&#xff1a;切换目录&#xff0c;cd 目录路径可进入指定目录&#xff0c;cd ~回到当前用户的家目录&…

普通电脑与云电脑的区别有哪些?全面科普

近年来&#xff0c;越来越多的人不再购置升级自己的电脑&#xff0c;转而选择云电脑&#xff0c;云端产品正在变得越来越普及易用。那么它究竟跟我们的普通本地设备有什么区别呐&#xff1f;或许很多人并不知悉&#xff0c;对此&#xff0c;本篇内容小编就为大家简要科普一下普…

【Python】支持向量机SVM

示例代码&#xff1a;import numpy as np import matplotlib.pyplot as plt from sklearn import svm from sklearn.datasets import make_blobs from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report# 设…

当AI学会“抄近路”:残差网络如何突破深度学习的极限

**——解读《Deep Residual Learning for Image Recognition》**今天我想带大家回到2015年&#xff0c;见证人工智能领域的一场“捷径革命”——由何恺明等人提出的**深度残差学习框架&#xff08;ResNet&#xff09;**。这篇论文解决了困扰AI界多年的“深度诅咒”&#xff0c;…

HCIP--BGP综合实验

目录 BGP综合实验报告 一、实验拓扑 二、实验要求 三、实验思路 &#xff08;一&#xff09;IP地址规划 &#xff08;二&#xff09;整体思路 四、实验步骤 &#xff08;一&#xff09; IP地址配置 &#xff08;二&#xff09; AS2内部配置OSPF协议 &#xff08;三&a…

Java 基础编程案例:从输入交互到逻辑处理

在Java编程学习中&#xff0c;输入输出、循环控制和逻辑判断是核心基础。本文整理了10个经典案例&#xff0c;涵盖Scanner输入处理、斐波那契数列、成绩统计、登录验证等场景&#xff0c;帮助初学者掌握编程逻辑与实用技巧。 一、Scanner输入交互&#xff1a;获取用户输入并处理…

LeetCode 面试经典 150_数组/字符串_整数转罗马数字(18_12_C++_中等)(模拟)(对各位进行拆解)

LeetCode 面试经典 150_数组/字符串_整数转罗马数字&#xff08;18_12_C_中等&#xff09;题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;模拟&#xff09;&#xff1a;思路二&#xff08;对各位进行拆解&#xff09;&a…

计算机网络摘星题库800题笔记 第6章 应用层

第6章 应用层 6.1 网络应用的架构 考点 1 CS 架构 题组闯关 1.DNS 是基于 ( ) 模式的分布式系统。 A. C/S B. B/S C. P2P D. 以上均不正确 1.【参考答案】A 【解析】本题考查网络应用模型。 DNS 作为分布式应用&#xff0c;是一种典型的 C/S 模式&#xff0c;是随着 Internet 技…

BLUCK电路的输入电容应该怎么选取

借用TI的BULK芯片讨论一下输入电容怎么选取的问题&#xff0c;BULK电源是我们常用的电源&#xff0c;它的原理请看之前的文章&#xff1a; 高压差为何不用LDO&#xff1f;DCDC效率更高&#xff01;-CSDN博客 本文我们探讨一下输入电容&#xff0c;输入电容是控制纹波的关键&a…

CAN仲裁机制的原理

我们来详细讲 CAN 仲裁机制 的原理和工作方式,这是 CAN 总线最核心的特性之一。 1️⃣ 基本概念 CAN 总线是 多主机、多节点的串行总线,所有节点共享一根差分信号线(CAN_H / CAN_L)。 每个节点都可以随时发送消息(多主机机制) 总线只能同时有一个节点成功发送 仲裁 用…

【GPT入门】第46课 vllm安装、部署与使用

【GPT入门】第46课 vllm安装、部署与使用 1.准备服务器 2. 安装 conda环境,隔离base环境 3. vllm使用 3.1 在线推理, openai兼容服务器 3.2 模型离线调用 4. 没有使用GPU问题分析 1.准备服务器 cuda 版本选12.1 vllm官网介绍: https://vllm.hyper.ai/docs/getting-started/…

【从网络基础到实战】理解TCP/IP协议体系的核心要点(包含ARP协议等其他协议介绍)

前言&#xff1a; 学习计算机网络不仅是软件开发的基础功&#xff0c;更是成为一名合格后端工程师、网络工程师的重要门槛。本文将基于 TCP/IP 协议体系&#xff0c;系统梳理网络层、数据链路层、以及相关协议的核心知识&#xff0c;并结合实际案例与代码示例帮助理解。一、网络…

Python 元类基础:从理解到应用的深度解析

在 Python 的高级编程中&#xff0c;元类&#xff08;metaclass&#xff09; 无疑是最神秘又最强大的特性之一。它不仅是构建类的“工厂”&#xff0c;更是 Python 灵活对象模型的体现。本文将带你从基础概念入手&#xff0c;深入理解元类的本质、工作机制以及实际应用&#xf…

Nginx 配置代理服务器的详细方法

一、什么是代理服务器&#xff1f; 类型说明正向代理客户端通过代理访问目标服务器&#xff08;隐藏客户端身份&#xff09;反向代理客户端访问代理服务器&#xff0c;由代理服务器请求后端服务器&#xff08;隐藏后端服务器&#xff09; 二、Nginx 反向代理配置方法&#xff…

Lombok插件介绍及安装(Eclipse)

一、Lombok 的用途 Lombok是一个 Java 库&#xff0c;通过注解的方式简化 Java 代码的编写。它能够自动生成常见的代码&#xff0c;如getter、setter、toString、equals、hashCode等方法&#xff0c;从而减少样板代码&#xff0c;使代码更加简洁、易读。 Lombok 通过添加**Dat…

硬核操作!Go 语言生成 “会爬墙的清洁机器人”,玻璃外墙自己擦

本文聚焦于利用 Go 语言开发 “会爬墙的清洁机器人” 这一硬核技术&#xff0c;围绕该机器人如何实现玻璃外墙自主清洁展开。首先介绍开发背景与需求&#xff0c;接着阐述 Go 语言在其中的优势&#xff0c;详细讲解机器人的核心技术&#xff0c;包括吸附系统、运动控制、清洁机…

Qt——实现”Hello World“、认识对象树与Qt坐标系

在创建项目时&#xff0c;使用的基类Base Class为QWidget 1. 使用图形化界面的方式实现“Hello World” 双击文件&#xff1a;widget.ui&#xff0c;进入designer模式&#xff1a;在“控件盒子”的“Display Widgets”中找到“Label”&#xff0c;并拖放到白板中双击刚刚拖放到…

智能合约开发全流程实战指南

目录 灵感探索与概念验证合约开发常见问题 Hardhat 初始化项目问题合约编译错误处理智能合约设计缺陷 合约测试最佳实践 单元测试环境配置测试用例编写技巧测试覆盖率和策略常见测试失败原因 合约部署实战指南 部署到不同网络部署前准备事项部署后验证方法部署费用和Gas优化 合…

IPA1299至为芯替代TI ADS1299的脑机接口芯片

在脑机接口、神经科学研究和医疗电子设备领域&#xff0c;脑电信号采集芯片是连接生物电信号与数字世界的重要组件。目前&#xff0c;TI等国际厂商凭借技术优势占据市场主要份额&#xff0c;国内厂商在成本控制、供货周期和技术自主性方面面临挑战。英集芯推出的IPA1299低噪声多…

「数据获取」《中国海洋生态环境状况公报》(2001-2023年)(获取方式看绑定的资源)

01、数据简介在 2023 年的海洋环境监测工作中&#xff0c;监测范围广泛且细致。全年对 1359 个海洋环境质量国家控制点位进行了水质监测&#xff0c;这些点位分布在我国管辖的各大海域&#xff0c;能够全面反映海洋整体水质状况&#xff1b;对 230 个入海河流国家控制断面开展监…