android接入rocketmq

news2025/3/10 23:08:47

一 前言

RocketMQ 作为一个功能强大的消息队列系统,不仅支持基本的消息发布与订阅,还提供了顺序消息、延时消息、事务消息等高级功能,适应了复杂的分布式系统需求。其高可用性架构、多副本机制、完善的运维管理工具,以及安全控制功能,使其成为企业级应用的首选消息中间件。
在Android应用中,你可以使用RocketMQ的客户端库来发送和接收消息.

二 接入流程

1 添加依赖

在Android项目的build.gradle文件中添加RocketMQ客户端库的依赖。

dependencies {
    implementation 'org.apache.rocketmq:rocketmq-client:5.3.1'
}
2 添加权限
<uses-permission android:name="android.permission.INTERNET" />
3 接收消息
ExecutorService executor = Executors.newFixedThreadPool(20);  //根据项目需要设置常用线程个数
String TAG = "MainActivity";
String GROUP = "producer";
String ADDRESS = "192.168.1.84:9876";
String KEY = "key";

executor.submit(() -> {
            try {
                DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(GROUP);
                consumer.setNamesrvAddr(ADDRESS);
                // 订阅 topic 下的全部 tab
                consumer.subscribe(TOPIC, "*");
                // BROADCASTING:广播模式,把消息发给了所有订阅了对应主题的消费者,不管消费者是不是同一个消费者组, CLUSTERING:集群模式(默认值),每一条消息只会被同一个消费者组中的一个实例消费
                consumer.setMessageModel(MessageModel.CLUSTERING);
                // CONSUME_FROM_LAST_OFFSET:从最新的偏移值开始消费(默认值), CONSUME_FROM_FIRST_OFFSET:从队列最开始的偏移值开始消费, CONSUME_FROM_TIMESTAMP:从指定的时间戳处开始消费
                consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
                // yyyyMMddHHmmss: 当选择从指定的时间戳处开始消费时, 需要指定该时间戳
                // consumer.setConsumeTimestamp("");
                // 使用并发方式从多个MessageQueue中取数据的方式监听
                consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
                    System.out.println();
                    for (MessageExt msg : msgs) {
                        Log.e(TAG,"收到消息:"+new String(msg.getBody()));
                    }
                    // 返回消费成功, 还可以是 RECONSUME_LATER:稍后重新消费
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                });
                consumer.start();
                TimeUnit.DAYS.sleep(1);
            } catch (Throwable cause) {
                cause.printStackTrace();
            }
        });
4 发送消息
 executor.submit(() -> {
            try {
                DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);
                producer.setNamesrvAddr(DEFAULT_NAMESRVADDR);
                producer.start();

                // 同步传递消息,消息会发给集群中的一个Broker节点。
                Message message = new Message(TOPIC, TAG, KEY, "android  hello word ss".getBytes(RemotingHelper.DEFAULT_CHARSET));
                SendResult result = producer.send(message);

                Log.e(TAG,"发送消息结果:result:"+ JSON.toJSONString(result));
                producer.shutdown();
            } catch (Exception e) {
                Log.e(TAG,"发送失败:"+e.getCause().toString());
                e.printStackTrace();
            }
        });

三 问题

启动项目,点击发送消息,项目报了异常信息,如下

java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory;  报错

这是因为RocketMQ客户端库依赖于Java标准库中的 java.lang.management.ManagementFactory 类,而Android并不完全支持Java标准库,尤其是 java.lang.management 包。

RocketMQ官方没有专门为Android提供适配版本,所以可以尝试使用这些版本,或者自己修改RocketMQ源码,移除对 ManagementFactory 的依赖。

四 修改源码

在github中,把rocketmq-client源码下载到本地
https://github.com/apache/rocketmq
在这里插入图片描述

导入到本地如下
在这里插入图片描述
然后找到前面ManagementFactory 报错的地方,将它移除或者用其他方法代替,经排查在
org.apache.rocketmq.common.UtilAll 有相关的引用
在这里插入图片描述
该方法则是为了通过获取jvm的进程ID,这边我们可以把它注释掉,然后用个固定值代替试下

 static {
        HEX_ARRAY = "0123456789ABCDEF".toCharArray();
       /* Supplier<Integer> supplier = () -> {
            // format: "pid@hostname"
            String currentJVM = ManagementFactory.getRuntimeMXBean().getName();
            try {
                return Integer.parseInt(currentJVM.substring(0, currentJVM.indexOf('@')));
            } catch (Exception e) {
                return -1;
            }
        };
        PID = supplier.get();*/
        PID = 888888;
    }

以及在org.apache.rocketmq.common.MixAll也有ManagementFactory相关引用,这个作用是获取当前java虚拟机(JVM)的进程ID,可以将其注释,然后返回固定的结果

public static long getPID() {
      String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
        if (StringUtils.isNotEmpty(processName)) {
            try {
                return Long.parseLong(processName.split("@")[0]);
            } catch (Exception e) {
                return 0;
            }
        }
        return 0;
    }

最后还有一个地方有涉及到,在包路径org.apache.rocketmq.store.StoreUtil,其作用是为了获取当前机器的总物理内存大小(以字节为单位)

 public static long getTotalPhysicalMemorySize() {
       long physicalTotal = 1024 * 1024 * 1024 * 24L;
        OperatingSystemMXBean osmxb = ManagementFactory.getOperatingSystemMXBean();
        if (osmxb instanceof com.sun.management.OperatingSystemMXBean) {
            physicalTotal = ((com.sun.management.OperatingSystemMXBean) osmxb).getTotalPhysicalMemorySize();
        }
        return physicalTotal;
    }

将相关的包修改后,然后将其重新打包,在maven工具下,选择rocketmq-common,选择Plugins下的jar组件,选中下面的jar进行打包
在这里插入图片描述
打包完成后,在模块的target目录下生成jar包
在这里插入图片描述
android需要用到的包如下:

implementation files('libs\\rocketmq-remoting-5.3.1.jar')
implementation files('libs\\rocketmq-client-5.3.1.jar')
implementation files('libs\\rocketmq-common-5.3.1.jar')

implementation 'io.github.aliyunmq:rocketmq-logback-classic:1.0.1'
implementation 'com.google.guava:guava:31.1-jre'
implementation 'commons-validator:commons-validator:1.7'

将模块rocketmq-remoting,rocketmq-client,rocketmq-commo三个模块重新打包后导入,然后再加上下面那三个相关联的依赖包.重新用android应用进行收发信息,测试如下:

2025-03-04 14:51:22.272 13676-13795/? E/MainActivity: 收到消息:android  hello word ss
2025-03-04 14:51:22.279 13676-13785/? E/MainActivity: 发送消息结果:result:{"messageQueue":{"brokerName":"broker-a","queueId":0,"topic":"TopicTestLss"},"msgId":"C10005FD90380CA347BF12A326F00000","offsetMsgId":"C2000B5400002A9F000000000007A575","queueOffset":4,"regionId":"DefaultRegion","sendStatus":"SEND_OK","traceOn":true,"transactionId":"C10005FD90380CA347BF12A326F00000"}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端数据模拟 Mock.js 学习笔记

mock.js介绍 Mock.js是一款前端开发中拦截Ajax请求再生成随机数据响应的工具&#xff0c;可以用来模拟服务器响应 优点是&#xff1a;非常方便简单&#xff0c;无侵入性&#xff0c;基本覆盖常用的接口数据类型支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜…

用DeepSeek-R1-Distill-data-110k蒸馏中文数据集 微调Qwen2.5-7B-Instruct!

下载模型与数据 模型下载&#xff1a; huggingface&#xff1a; Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…

DeepSeek大模型 —— 全维度技术解析

DeepSeek大模型 —— 全维度技术解析 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;可以分享一下给大家。点击跳转到网站。 https://www.captainbed.cn/ccc 文章目录 DeepSeek大模型 —— 全维度技术解析一、模型架构全景解析1…

EasyRTC嵌入式音视频通话SDK:基于ICE与STUN/TURN的实时音视频通信解决方案

在当今数字化时代&#xff0c;实时音视频通信技术已成为人们生活和工作中不可或缺的一部分。无论是家庭中的远程看护、办公场景中的远程协作&#xff0c;还是工业领域的远程巡检和智能设备的互联互通&#xff0c;高效、稳定的通信技术都是实现这些功能的核心。 EasyRTC嵌入式音…

qt open3dAlpha重建

qt open3dAlpha重建 效果展示二、流程三、代码效果展示 二、流程 创建动作,链接到槽函数,并把动作放置菜单栏 参照前文 三、代码 1、槽函数实现 void on_actionAlpha_triggered();//alpha重建 void MainWindow::

《深入浅出数据索引》- 公司内部培训课程笔记

深入浅出数据索引 内容&#xff1a;索引理论&#xff0c;索引常见问题&#xff0c;索引最佳实践&#xff0c;sql优化实战&#xff0c;问答 哈希不支持范围查询 4层 几个亿 5层 几十亿上百亿 B树的分裂&#xff0c;50-50分裂 都是往上插一个元素&#xff08;红黑树是左右旋转&a…

PPT 技能:巧用 “节” 功能,让演示文稿更有序

在制作PPT时&#xff0c;你是否遇到过这样的情况&#xff1a;幻灯片越来越多&#xff0c;内容越来越杂&#xff0c;找某一页内容时翻得眼花缭乱&#xff1f;尤其是在处理大型PPT文件时&#xff0c;如果没有合理的结构&#xff0c;编辑和调整都会变得非常麻烦。这时候&#xff0…

Xss漏洞问题

https://bu1.github.io/2021/01/12/%E7%AC%AC%E5%8D%81%E4%BA%8C%E5%91%A8%EF%BC%9AXSS%E6%BC%8F%E6%B4%9E%E5%AD%A6%E4%B9%A0%E5%AE%9E%E6%88%98/ 后端绕开了前端&#xff0c;直接调用接口入库&#xff1a; <select οnchange“alert(1)”>12 前端拿到这个文本后&…

Docker概念与架构

文章目录 概念docker与虚拟机的差异docker的作用docker容器虚拟化 与 传统虚拟机比较 Docker 架构 概念 Docker 是一个开源的应用容器引擎。诞生于 2013 年初&#xff0c;基于 Go 语言实现。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xf…

3.使用ElementUI搭建侧边栏及顶部栏

1. 安装ElementUI ElementUI是基于 Vue 2.0 的桌面端组件库。使用之前&#xff0c;需要在项目文件夹中安装ElementUI&#xff0c;在终端中输入以下命令&#xff0c;进行安装。 npm i element-ui -S并在main.js中引入ElementUI 2. 使用elmentUI组件进行页面布局 2.1 清空原…

C# OPC DA获取DCS数据(提前配置DCOM)

OPC DA配置操作手册 配置完成后&#xff0c;访问远程ip&#xff0c;就能获取到服务 C#使用Interop.OPCAutomation采集OPC DA数据&#xff0c;支持订阅&#xff08;数据变化&#xff09;、单个读取、单个写入、断线重连

不同开发语言之for循环的用法、区别总结

一、Objective-C &#xff08;1&#xff09;标准的c风格 for (int i 0; i < 5; i) {NSLog("i %d", i); } &#xff08;2&#xff09;for in循环。 NSArray *array ["apple", "banana", "orange"]; for (NSString *fruit in …

MuBlE:为机器人操作任务规划提供了逼真的视觉观察和精确的物理建模

2025-03-05&#xff0c;由华为诺亚方舟实验室、捷克技术大学和帝国理工学院联合开发的MuBlE&#xff08;MuJoCo and Blender simulation Environment&#xff09;模拟环境和基准测试。通过结合MuJoCo物理引擎和Blender高质量渲染&#xff0c;为机器人操作任务规划提供了逼真的视…

ASP.NET Core 6 MVC 文件上传

概述 应用程序中的文件上传是一项功能&#xff0c;用户可以使用该功能将用户本地系统或网络上的文件上传到 Web 应用程序。Web 应用程序将处理该文件&#xff0c;然后根据需要对文件进行一些验证&#xff0c;最后根据要求将该文件存储在系统中配置的用于保存文件的存储中&#…

2025年03月07日Github流行趋势

项目名称&#xff1a;ai-hedge-fund 项目地址url&#xff1a;https://github.com/virattt/ai-hedge-fund项目语言&#xff1a;Python历史star数&#xff1a;12788今日star数&#xff1a;975项目维护者&#xff1a;virattt, seungwonme, KittatamSaisaard, andorsk, arsaboo项目…

Cursor + IDEA 双开极速交互

相信很多开发者朋友应该和我一样吧&#xff0c;都是Cursor和IDEA双开的开发模式:在Cursor中快速编写和生成代码&#xff0c;然后在IDEA中进行调试和优化 在这个双开模式的开发过程中&#xff0c;我就遇到一个说大不大说小不小的问题&#xff1a; 得在两个编辑器之间来回切换查…

3.3.2 用仿真图实现点灯效果

文章目录 文章介绍Keil生成.hex代码Proteus仿真图中导入.hex代码文件开始仿真 文章介绍 点灯之前需要准备好仿真图keil代码 仿真图参考前文&#xff1a;3.3.2 Proteus第一个仿真图 keil安装参考前文&#xff1a;3.1.2 Keil4安装教程 keil新建第一个项目参考前文&#xff1a;3.1…

点云软件VeloView开发环境搭建与编译

官方编译说明 LidarView / LidarView-Superbuild GitLab 我的编译过程&#xff1a; 安装vs2019&#xff0c;windows sdk&#xff0c;qt5.14.2&#xff08;没安装到5.15.7&#xff09;&#xff0c;git&#xff0c;cmake3.31&#xff0c;python3.7.9&#xff0c;ninja下载放到…

PDF处理控件Aspose.PDF,如何实现企业级PDF处理

PDF处理为何成为开发者的“隐形雷区”&#xff1f; “手动调整200页PDF目录耗时3天&#xff0c;扫描件文字识别错误导致数据混乱&#xff0c;跨平台渲染格式崩坏引发客户投诉……” 作为开发者&#xff0c;你是否也在为PDF处理的复杂细节消耗大量精力&#xff1f;Aspose.PDF凭…

《2025年软件测试工程师面试》消息队列面试题

消息队列 消息队列&#xff08;Message Queue&#xff0c;简称 MQ&#xff09;是一种应用程序之间的通信方法。 基本概念 消息队列是一种先进先出&#xff08;FIFO&#xff09;的数据结构&#xff0c;它允许一个或多个消费者从队列中读取消息&#xff0c;也允许一个或多个生产者…