当前位置: 首页 > news >正文

MQTT+Disruptor 提高物联网高并发

基于springboot2.5.7

废话不多说,直接上干货:

@Slf4j
@Configuration
@EnableConfigurationProperties(MqttProperties.class)
@IntegrationComponentScan(basePackages = {"扫描包路径","扫描包路径"})
public class MqttAutoConfig {@Autowiredprivate MqttProperties mqttProperties;@Autowiredprivate ApplicationContext applicationContext;@Autowiredprivate DisruptorProperties disruptorProperties;@RefreshScope@Bean(value = "mqttParallelQueueHandler",initMethod = "start",destroyMethod = "shutDown")@ConditionalOnProperty(prefix = "custom-config.mqtt", name = "disruptor", havingValue = "true")public ParallelQueueHandler mqttParallelQueueHandler(){log.info("初始化Disruptor...");return new ParallelQueueHandler.Builder<DisruptorEventData>().setDisruptorProperties(disruptorProperties).setWaitStrategy(new BlockingWaitStrategy()).setListener(new MQTTMsgListener()).build();}@Bean@ConditionalOnProperty(prefix = "custom-config.mqtt", value = {"username","password", "host-url"})public MqttConnectOptions getReceiverMqttConnectOptionsForSub(){MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();mqttConnectOptions.setUserName(mqttProperties.getUsername());mqttConnectOptions.setPassword(mqttProperties.getPassword().toCharArray());List<String> hostList = Arrays.asList(mqttProperties.getHostUrl().trim().split(","));String[] serverURIs = new String[hostList.size()];hostList.toArray(serverURIs);mqttConnectOptions.setServerURIs(serverURIs);mqttConnectOptions.setKeepAliveInterval(2);mqttConnectOptions.setAutomaticReconnect(true);return mqttConnectOptions;}/***  MQTT 连接工厂* @return MqttPahoClientFactory*/@Bean@ConditionalOnMissingBeanpublic MqttPahoClientFactory receiverMqttClientFactoryForSub(MqttConnectOptions mqttConnectOptions) {DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();factory.setConnectionOptions(mqttConnectOptions);log.info("【MQTT】-初始化连接工厂...");return factory;}/*** 出站通道* @return MessageChannel*/@Beanpublic MessageChannel mqttOutboundChannel() {return new DirectChannel();}/***  MQTT 消息发送处理器* @return MessageHandler*/@Bean@ServiceActivator(inputChannel = "mqttOutboundChannel")public MessageHandler mqttOutbound(MqttPahoClientFactory factory) {MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(mqttProperties.getClientId()+"out", factory);messageHandler.setDefaultQos(1);//开启异步messageHandler.setAsync(true);messageHandler.setDefaultTopic("test");return messageHandler;}/*** 此处可以使用其他消息通道* Spring Integration默认的消息通道,它允许将消息发送给一个订阅者,然后阻碍发送直到消息被接收。** @return MessageChannel*/@Beanpublic MessageChannel mqttInBoundChannel() {return new DirectChannel();}/*** 适配器, 多个topic共用一个adapter* 客户端作为消费者,订阅主题,消费消息*/@Bean@ConditionalOnMissingBeanpublic MqttPahoMessageDrivenChannelAdapter mqttInbound(MqttPahoClientFactory factory) {List<String> topics = mqttProperties.getSubscribeTopics();String[] topicArray = new String[topics.size()];for (int i = 0; i < topics.size(); i++) {topicArray[i] = "$queue/"+ topics.get(i);}log.info("【MQTT】-订阅TOPIC:{}", Arrays.toString(topicArray));MqttPahoMessageDrivenChannelAdapter adapter =new MqttPahoMessageDrivenChannelAdapter(mqttProperties.getClientId(), factory, topicArray);adapter.setCompletionTimeout(mqttProperties.getCompletionTimeout());adapter.setConverter(new DefaultPahoMessageConverter());adapter.setRecoveryInterval(10000);adapter.setQos(1);adapter.setOutputChannel(mqttInBoundChannel());return adapter;}@Autowired(required = false)@Qualifier("mqttParallelQueueHandler")private ParallelQueueHandler<DisruptorEventData> parallelQueueHandler;/*** mqtt入站消息处理工具,对于指定消息入站通道接收到生产者生产的消息后处理消息的工具。* @return MessageHandler*/@Bean@RefreshScope@ServiceActivator(inputChannel = "mqttInBoundChannel")public MessageHandler mqttMessageHandler() {// 获取配置中的设备品牌MqttProperties.DeviceBrand deviceBrand = mqttProperties.getDeviceBrand();boolean disruptor = mqttProperties.isDisruptor();// 获取所有实现了 CustomMqttMessageHandler 接口的 Beanreturn message -> {log.info("【MQTT】-收到MQTT消息,Topic: {}, Payload: {}",message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC),message.getPayload());String topic = (String) message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC);Map<String, CustomMqttMessageReceiverHandler> handlers = applicationContext.getBeansOfType(CustomMqttMessageReceiverHandler.class);boolean handled = false;if (Objects.nonNull(deviceBrand)){CustomMqttMessageReceiverHandler handler = handlers.get(deviceBrand.getServiceName());if (Objects.nonNull(handler)){if (handler.supportsTopic(topic)) {handled = this.run(handler,message,topic,disruptor);}}else {log.error("【MQTT】-未找到设备品牌消息接收处理器,deviceBrand->{}",deviceBrand);}}else {for (CustomMqttMessageReceiverHandler handler : handlers.values()) {if (handler.supportsTopic(topic)) {handled = this.run(handler,message,topic,disruptor);}}}if (!handled) {log.warn("【MQTT】-未找到匹配的处理器来处理Topic {} 的消息", topic);}};}@Bean@ConditionalOnProperty(prefix = "custom-config.mqtt", value = {"username","password", "host-url"})public MqttMessageSender mqttMessageSender(){return new MqttMessageSender();}private boolean run(CustomMqttMessageReceiverHandler handler,Message<?> message,String topic,boolean disruptor){try {String traceId = MDC.get("traceId");if (!StringUtils.hasText(traceId)){traceId = UUID.randomUUID().toString().replaceAll("-", "");MDC.put("traceId",traceId);}if (disruptor && Objects.nonNull(parallelQueueHandler)){log.info("【MQTT】-使用Disruptor处理...");DisruptorEventData data = new DisruptorEventData();Map<String,Object> map = new HashMap<>();map.put("data",message);map.put("handler",handler);map.put("traceId",traceId);data.setMessage(map);parallelQueueHandler.add(data);}else {handler.handleMessage(message);}return true;} catch (Exception e) {log.error("【MQTT】-Handler {} 处理Topic {} 的消息时出错", handler.getClass().getSimpleName(), topic, e);return false;}finally {MDC.clear();}}

由于涉及隐私,其余代码可以留言

相关文章:

MQTT+Disruptor 提高物联网高并发

基于springboot2.5.7 废话不多说&#xff0c;直接上干货&#xff1a; Slf4j Configuration EnableConfigurationProperties(MqttProperties.class) IntegrationComponentScan(basePackages {"扫描包路径","扫描包路径"}) public class MqttAutoConfig {…...

SpringBoot项目集成ONLYOFFICE

ONLYOFFICE 文档8.2版本已发布&#xff1a;PDF 协作编辑、改进界面、性能优化、表格中的 RTL 支持等更新 文章目录 前言ONLYOFFICE 产品简介功能与特点Spring Boot 项目中集成 OnlyOffice1. 环境准备2. 部署OnlyOffice Document Server3. 配置Spring Boot项目4. 实现文档编辑功…...

用于nodejs的开源违禁词检测工具 JavaScript node-word-detection

地址 : https://www.npmjs.com/package/node-word-detection github地址: https://github.com/xiaobaidadada/node-word-detection 非常节省内存的轻量级快速违禁词、词典库 检测工具 、 50万个词大约需要300MB内存、被检测的文本100字内结果在1毫秒左右。本项目没有提供词库请…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发十二:在屏幕上显示多路视频播放,可以有不同的分辨率,格式和帧率。

上图是在安防领域的要求&#xff0c;一般都是一个屏幕上有显示多个摄像头捕捉到的画面&#xff0c;这一节&#xff0c;我们是从文件中读取多个文件&#xff0c;显示在屏幕上。...

Linux权限问题(账号切换,权限,粘滞位)

1.什么是权限&#xff1f; 在Linux下有两种用户&#xff0c;分别是超级用户&#xff08;root&#xff09;和普通用户。超级用户可以在Linux下做任何事情&#xff0c;几乎不受限制&#xff0c;而普通用户一般只能在自己的工作目录下&#xff08;/home/xxx&#xff09;工作&#…...

el-upload,上传文件,后端提示信息,前端需要再次重新上传(不用重新选择文件)

1.el-upload 上传附件&#xff1a; <el-uploadref"upload":action"upload.url ?updateSupport upload.updateSupport":auto-upload"false":disabled"upload.isUploading":headers"upload.headers":limit"1"…...

数字信号处理Python示例(5)使用实指数函数仿真PN结二极管的正向特性

文章目录 前言一、二极管的电流-电压关系——Shockley方程二、PN结二极管正向特性的Python仿真三、仿真结果分析写在后面的话 前言 使用Python代码仿真了描述二极管的电流-电压关系的Shockley方程&#xff0c;对仿真结果进行了分析&#xff0c;说明在正向偏置区域&#xff0c;…...

ctfshow(89,90,92,93)--PHP特性--intval函数

Web89 源代码&#xff1a; include("flag.php"); highlight_file(__FILE__);if(isset($_GET[num])){$num $_GET[num];if(preg_match("/[0-9]/", $num)){die("no no no!");}if(intval($num)){echo $flag;} }审计 GET传参num。 如果在参数num中…...

构建ubuntu22.04.4私有源服务以及配置ubuntu私有源

构建ubuntu22.04.4私有源服务以及配置ubuntu私有源 一、环境说明1.1 私有源服务器1.2 客户机二 、构建私有源服务2.1 服务构建2.2 发布新的deb包到源服务器1. 准备新的 `.deb` 包2. 将 `.deb` 包添加到仓库目录3. 更新 `Packages` 文件4. 更新仓库的发布文件(可选)5. 通知客户…...

模块功能的描述方法

目录 行为描述方法 语句块 过程赋值语句 高级程序语句 循环语句 数据流描述 结构描述 混合描述方法 module 模块名(端口列表); // 模块声明// 端口定义input [数据类型] [位宽] 输入端口列表; output [数据类型] [位宽] 输出端口列表; inout [数据类…...

【WPF】MatrixTransform类

【WPF】MatrixTransform类 主要特性使用场景示例 在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;MatrixTransform 类是用于表示一个仿射变换的类&#xff0c;它允许开发者通过一个矩阵来定义一个二维空间中的线性变换。这种变换可以包括平移&…...

【C++】继承的理解

1.继承的概念和定义 1.1继承的概念 继承 (inheritance) 机制是面向对象程序设计 使代码可以复用 的最重要的手段&#xff0c;它允许程序员在 保 持原有类特性的基础上进行扩展 &#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承 呈现了面向对象 程序…...

day50 图论章节刷题Part02(99.岛屿数量 深搜、99.岛屿数量 广搜、100.岛屿的最大面积)

前言&#xff1a;前段时间论文开题落下了很多进度&#xff0c;今天开始会尽快赶上 99.岛屿数量 深搜 思路&#xff1a;对地图进行遍历遇到一个没有遍历过的陆地节点&#xff0c;计数器就1&#xff0c;并把该节点所能遍历到的陆地都标记上&#xff1b;遇到标记过的陆地节点和海…...

超详细从基准将VMware ESXi 升级到 vSphere 6.7U1教程

哈喽大家好&#xff0c;欢迎来到虚拟化时代君&#xff08;XNHCYL&#xff09;&#xff0c;收不到通知请将我点击星标&#xff01; “ 大家好&#xff0c;我是虚拟化时代君&#xff0c;一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福…...

华为OD机试 - 打印机队列 - 优先队列(Java 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…...

MatrixOne 助力西安天能替换MySQL+MongoDB+ES打造一体化物联网平台

物联网&#xff08;IoT&#xff09;时代&#xff0c;企业正以前所未有的速度加快数字化转型。西安天能软件科技有限责任公司&#xff08;Skyable&#xff09;作为工业物联网领域的领先企业&#xff0c;携手MatrixOne&#xff0c;共同构建新一代一体化物联网平台&#xff0c;实现…...

正则表达式---元字符

简介 正则表达式分为两种语法&#xff1a;POSIX标准的语法&#xff0c;Perl语法。 正则表达式的POSIX规范&#xff0c;分为基本型正则表达式&#xff08;Basic Regular Expression, BRE&#xff09;&#xff0c;扩展型正则表达式&#xff08;Extended Regular Expression&…...

数据库Redis篇

系列文章目录 第一章 C/C语言篇第二章 计算机网络篇第三章 操作系统篇第四章 数据库MySQL篇第五章 数据库Redis篇第六章 场景题/算法题第七篇 常见HR问题篇 本系列专栏&#xff1a;点击进入 后端开发面经 关注走一波 秋招阶段&#xff0c;面过很多大中小厂&#xff0c;积攒了…...

在区块链技术中,什么是权益证明(PoS)?

权益证明&#xff08;Proof of Stake, PoS&#xff09;是一种与工作量证明&#xff08;Proof of Work, PoW&#xff09;类似的共识机制&#xff0c;但它通过不同的方式来确保区块链网络的安全性和一致性。PoS的主要目标是解决PoW中存在的高能耗问题&#xff0c;并提高网络的扩展…...

Spring Boot——日志介绍和配置

1. 日志的介绍 在前面的学习中&#xff0c;控制台上打印出来的一大堆内容就是日志&#xff0c;可以帮助我们发现问题&#xff0c;分析问题&#xff0c;定位问题&#xff0c;除此之外&#xff0c;日志还可以进行系统的监控&#xff0c;数据采集等 2. 日志的使用 在程序中获取日…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...