【Java中间件】RocketMQ
RocketMQ
一、MQ概述
Message Queue,是一种提供消息队列服务的中间件。提供了消息生产、存储、消费全过程API的软件系统。
MQ的作用
- 限流削峰:当用户发送超量请求时,将请求暂存,以便后期慢慢处理。如果不使用MQ暂存直接请求到业务系统中容易引起系统崩溃。
- 异步解耦:若上游系统和下游系统为同步调用,会大大降低系统的吞吐量和并发量。MQ层实现两个系统之间的异步调用
- 数据收集:分布式系统会产生海量数据流,如业务日志、监控数据、用户行为。针对这些数据流采集汇总,进行大数据分析。
主流应用的MQ产品
- Kafka:Scala/Java语言开发。特点是高吞吐量,但会丢数据,常用与大数据领域的实时计算、日志采集等场景。不遵循任何MQ协议,使用自研协议。
- RocketMQ:Java语言开发。经过数年阿里双十一考验,性能与稳定性非常高,功能全面。不遵循任何MQ协议,使用自研协议。开源版不如云上版(阿里商业版)
MQ常见协议
-
JMS:Java Messaging Service。Java平台上有关MOM(Message Orientated Middleware)的技术规范。他便于Java应用程序的消息交换,提供标准的接口简化开发。ActiveMQ时典型实现
-
STOMP:Streaming Text Orientated Message Protocol。是一种MOM的简单文本协议。STOMP提供一个可互操作的连接格式,允许 客户端与任意STOMP消息代理进行交互。ActiveMQ时典型实现
-
AMQP:Advanced Message Queuing Protocol。一个提供统一消息服务的应用层标准,是应用层协议的一个开放标准。RabbitMQ是典型实现
-
MQTT:Message Queueing Telemetry Transport。IBM开发的一个即时通讯协议(二进制协议),主要用于服务器和低功耗IoT设备之间的通信
二、基本概念
主题(Topic):表示一类消息的集合(可以理解为消息的类型),每个消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。一个生产者可以同时发送多种Topic消息,而一个消费者只能接收一种Topic消息
标签(Tag):用于快速过滤消息
三、Linux部署RocketMQ服务
1、在官网下载编译好的二进制压缩包,版本5.0.0即可,上传到Linux中
2、进行解压
3、配置环境变量ROCKETMQ_HOME和NAMESRV_ADDR

4、配置bin目录下的runserver.sh,根据实际情况修改JVM的内存参数

5、配置bin目录下的runbroker.sh,根据实际情况修改JVM的内存参数

6、执行nohup命令后台运行RocketMQ服务(nameserver必须先启动,broker需要再nameserver上注册)
# 启动nameserver
nohup bin/mqnamesrv & # 启动broker
nohup bin/mqbroker -c [confFile] & # -c可指定加载的配置文件,默认为conf/broker.conf# 查看日志rocketmq是否成功启动
tail nohup.out # 查看进程
jps # 停止broker
sh bin/mqshutdown broker# 停止namesrv
sh bin/mqshutdown namesrv
7、执行命令测试(rocketmq提供的测试样例,生产者会发送一千条消息)
bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
8、执行命令测试(rocketmq提供的测试样例,消费者会接受一千条消息)
bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
四、RocketMQ API
生产者同步发送消息
public void test_SyncProducer() throws MQClientException {DefaultMQProducer producer = new DefaultMQProducer("producer_group_name");//设置注册服务的ip地址的端口producer.setNamesrvAddr(RocketMQConstant.NAME_SRV_ADDR);//启动生产者producer.start();for(int i=0; i<3; i++){try {// 封装消息,设置topic,tag(用于消息快速过滤),消息数据Message message = new Message("TopicTest","TagA","ID04287777",("Hello, RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));//同步发送消息并获取发送结果,producer从broker获取发送结果SendResult sendResult = producer.send(message);System.out.println(sendResult);Thread.sleep(1500);} catch (Exception e) {throw new RuntimeException(e);}}producer.shutdown();
}
生产者异步发送消息
public void test_AsyncProducer() throws Exception{DefaultMQProducer producer = new DefaultMQProducer(RocketMQConstant.PRODUCER_GROUP_NAME);producer.setNamesrvAddr(RocketMQConstant.NAME_SRV_ADDR);producer.start();producer.setRetryTimesWhenSendAsyncFailed(0);int messageCount = 10;final CountDownLatch countDownLatch = new CountDownLatch(messageCount);for(int i=0; i<messageCount; i++){final int index = i;// 封装消息,设置topic,tag(用于消息快速过滤),消息数据Message message = new Message("TopicTest","TagA","ID04287777",("Hello, RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));// 异步发送消息,若broker有响应会调用SendCallback中的方法producer.send(message, new SendCallback() {public void onSuccess(SendResult sendResult) {countDownLatch.countDown();System.out.println(" Send Message "+ index +" OK: "+sendResult);}public void onException(Throwable throwable) {countDownLatch.countDown();System.out.println(" Send Message "+ index +" Exception: "+throwable);}});//单向发送producer.sendOneway(message);System.out.println("Message "+index+" send done");}//在100条消息发送完后关闭countDownLatch.await(5, TimeUnit.SECONDS);producer.shutdown();
}
生产者单向发送消息
public void test_OneWayProducer() throws Exception{DefaultMQProducer producer = new DefaultMQProducer(RocketMQConstant.PRODUCER_GROUP_NAME);producer.setNamesrvAddr(RocketMQConstant.NAME_SRV_ADDR);producer.start();producer.setRetryTimesWhenSendAsyncFailed(0);int messageCount = 10;final CountDownLatch countDownLatch = new CountDownLatch(messageCount);for(int i=0; i<messageCount; i++){final int index = i;// 封装消息,设置topic,tag(用于消息快速过滤),消息数据Message message = new Message("TopicTest","TagA","ID04287777",("Hello, RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));//单向发送producer.sendOneway(message);System.out.println("Message "+index+" send done");}//在100条消息发送完后关闭countDownLatch.await(5, TimeUnit.SECONDS);producer.shutdown();
}
消费者推模式
public static void test_PushConsumer() throws Exception{DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer_group_name");consumer.setNamesrvAddr(RocketMQConstant.NAME_SRV_ADDR);consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);//消费者订阅的消息topic和tag(subExpression,*表示任意)consumer.subscribe("TopicTest", "*");consumer.registerMessageListener(new MessageListenerConcurrently() {public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {System.out.println("Receive New Message : "+list);return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();System.out.println("Consumer Start...");
}
消费者拉模式
不同于推模式消费者,拉模式下需要手动管理消息队列MessageQueue和偏移量offset的映射关系。但是最新的LitePullConsumer底层源码已经实现对mq和offset的管理,比较方便。
//拉模式消费者
public static void test_LitePullConsumer() throws Exception{DefaultLitePullConsumer litePullConsumer = new DefaultLitePullConsumer(RocketMQConstant.CONSUMER_GROUP_NAME);litePullConsumer.setNamesrvAddr(RocketMQConstant.NAME_SRV_ADDR);litePullConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);litePullConsumer.subscribe("TopicTest", "*");litePullConsumer.start();try {while(true){List<MessageExt> messageExts = litePullConsumer.poll();System.out.printf("%s%n", messageExts);}}finally {litePullConsumer.shutdown();}
}
RocketMQ传递对象,对象所属类需要实现序列化接口,并且将对象转换为字节数组存入消息体中。
顺序消息
保证消息的局部有序(其中几条消息的有序,不一定是全部消息都要有序),以防止受到网络传输的影响。
实现原理
生产者将一组有序的消息一次发到同一个MessageQueue中(依靠队列的特点保证局部有序性)。消费者消费完一个MessageQueue的消息后才会去消费下一个MessageQueue的消息。
public class OrderProducer {public static void main(String[] args) {DefaultMQProducer producer = new DefaultMQProducer(WanfengConstant.PRODUCER_GROUP_NAME);try {producer.setNamesrvAddr(WanfengConstant.NAMESRV_ADDR);producer.start();for(int i=0; i<5; i++){//用于指定顺序的idint orderId = i;for(int j=0; j<5; j++){Message message = new Message(WanfengConstant.ORDER_TOPIC,"order_"+orderId,"KEY"+orderId,("order_"+orderId+" step "+j).getBytes(RemotingHelper.DEFAULT_CHARSET));//实现消息队列选择器对象,使同一个orderId的消息发送到同一个消息队列SendResult sendResult = producer.send(message,new MessageQueueSelector() {@Overridepublic MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {Integer id = (Integer) arg;int index = id % mqs.size();return mqs.get(index);}},orderId);System.out.printf("%s%n", sendResult);}}}catch(Exception e){e.printStackTrace();producer.shutdown();}}
}
public class OrderConsumer {public static void main(String[] args) {DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(WanfengConstant.CONSUMER_GROUP_NAME);consumer.setNamesrvAddr(WanfengConstant.NAMESRV_ADDR);consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);try {consumer.subscribe(WanfengConstant.ORDER_TOPIC, "*");//实现顺序消息监听者接口consumer.registerMessageListener(new MessageListenerOrderly() {@Overridepublic ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {context.setAutoCommit(true);for(MessageExt messageExt : msgs){System.out.println("Receive Message: " + new String(messageExt.getBody()));}return ConsumeOrderlyStatus.SUCCESS;}});consumer.start();System.out.println("Consumer Start...");} catch (Exception e) {e.printStackTrace();consumer.shutdown();}}
}
广播消息
生产者发送的消息推送给所有group的消费者
实现原理:将消费者设置MessageModel为广播模式。
public class BroadcastConsumer {public static void main(String[] args) {DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(WanfengConstant.CONSUMER_GROUP_NAME);consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);//设定消息模式为广播consumer.setMessageModel(MessageModel.BROADCASTING);try {consumer.subscribe(WanfengConstant.ARCHIVE_TOPIC, "*");consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {msgs.forEach(messageExt -> {Archive archive = (Archive) WanfengObjectUtil.bytesToObject(messageExt.getBody());System.out.println("Receive Message : "+archive.getId());});return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();System.out.println("Broadcast Consumer Start...");}catch (Exception e){e.printStackTrace();consumer.shutdown();}}
}
若指定MessageModel为CLUSTERING,则生产者发送的消息会随机指定消费者消费。
延迟消息
顾名思义就是消息发送到broker时延迟指定的时间后再发送给消费者。常用于定时发送
过滤消息
过滤消息通过tag实现,在消费者端指定过滤的tag即可。
//消费者订阅tag1或tag2的消息
consumer.subscribe("TopicTest", "tag1 || tag2");
在RocketMQ中,消费者指定过滤条件后,将其上推到Broker中,在Broker中进行tag过滤,以减少网络IO,但同时也增加了Broker的繁忙。
事务消息

public class TransactionProducer {public static void main(String[] args) {TransactionMQProducer producer = new TransactionMQProducer(WanfengConstant.PRODUCER_GROUP_NAME);TransactionListener transactionListener = new TransactionListener() {@Overridepublic LocalTransactionState executeLocalTransaction(Message msg, Object arg) {System.out.println("[WANFENG-INFO] TransactionProducer.executeLocalTransaction(): 执行成功...");String tags = msg.getTags();if (StringUtils.contains(tags, "TagA")) {//消息提交(发送出去)return LocalTransactionState.COMMIT_MESSAGE;} else if (StringUtils.contains(tags, "TagB")) {//消息回滚(丢掉消息)return LocalTransactionState.ROLLBACK_MESSAGE;} else {return LocalTransactionState.UNKNOW;}}@Overridepublic LocalTransactionState checkLocalTransaction(MessageExt msg) {System.out.println("[WANFENG-INFO] TransactionProducer.checkLocalTransaction(): 执行成功...");String tags = msg.getTags();if (StringUtils.contains(tags, "TagC")) {return LocalTransactionState.COMMIT_MESSAGE;} else {return LocalTransactionState.UNKNOW;}}};ExecutorService executorService = new ThreadPoolExecutor(2,5,100, TimeUnit.SECONDS,new ArrayBlockingQueue<>(3));producer.setExecutorService(executorService);producer.setTransactionListener(transactionListener);try {producer.start();} catch (Exception e) {e.printStackTrace();}String[] tags = new String[]{"TagA", "TagB", "TagC"};CountDownLatch countDownLatch = new CountDownLatch(9);for (int i = 0; i < 9; i++) {try {Message message = new Message("TopicTest", tags[i % tags.length], "Key" + i, ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));SendResult sendResult = producer.sendMessageInTransaction(message, null);System.out.println(sendResult);Thread.sleep(1000);countDownLatch.countDown();} catch (Exception e) {e.printStackTrace();}}try {countDownLatch.await();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {try {Thread.sleep(100000);} catch (InterruptedException e) {throw new RuntimeException(e);}producer.shutdown();}}
}
ACL权限控制
ACL对用户对Topic资源的访问权限进行控制
在pom依赖中引入acl的依赖包
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-acl</artifactId><version>5.0.0</version>
</dependency>
在服务端的conf/broker.conf文件,添加配置,开启acl
aclEnable=true
在服务端的conf/plain_acl.yml文件,配置具体权限规则(热加载,不需要重启mq)
accounts:- accessKey: RocketMQ #用户名secretKey: 12345678 #密码whiteRemoteAddress: #访问地址白名单admin: false #是否为管理员(管理员可以访问所有Topic)defaultTopicPerm: DENY #默认Topic访问权限defaultGroupPerm: SUB #默认组权限topicPerms: #Topic对应的权限,若这里找不到则采用defaultTopicPerm- topicA=DENY - topicB=PUB|SUB- topicC=SUBgroupPerms:# the group should convert to retry topic- groupA=DENY- groupB=PUB|SUB- groupC=SUB
在创建生产者对象时需加入RPCHook(acl的用户信息)
public class AclProducer {private static final String ACL_ACCESS_KEY = "RocketMQ";private static final String ACL_SECRET_KEY = "12345678";/*** 通过用户名和密码获取RPCHook* @return*/public static RPCHook getAclRPCHook(){return new AclClientRPCHook(new SessionCredentials(ACL_ACCESS_KEY, ACL_SECRET_KEY));}public static void main(String[] args) throws MQClientException, InterruptedException {//创建生产者时加入用户信息,即RPCHookDefaultMQProducer producer = new DefaultMQProducer(WanfengConstant.PRODUCER_GROUP_NAME, getAclRPCHook());producer.setNamesrvAddr(WanfengConstant.NAMESRV_ADDR);producer.start();for (int i = 0; i < 20; i++) {try {Message message = new Message("TopicTest",WanfengConstant.TAGS_NAME,("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /*消息体转换成二进制数组*/);SendResult sendResult = producer.send(message);System.out.printf("%s%n", sendResult);} catch (Exception e) {e.printStackTrace();Thread.sleep(1000);}}}
}
消息轨迹
Producer,Consumer,Broker处理消息的相关信息
消息轨迹的实现原理是MQ把消息轨迹都往RMQ_SYS_TRACE_TOPIC的Topic中放
在Broker端配置文件开启消息轨迹
traceTopicEnable=true
创建生产者时指定enableMsgTrace参数为true,开启消息轨迹。也可以指定customizedTraceTopic参数来自定义消息轨迹的Topic。
public class TraceProducer {public static void main(String[] args) throws MQClientException {//指定enableMsgTrace参数为true,开启消息轨迹DefaultMQProducer producer = new DefaultMQProducer(WanfengConstant.PRODUCER_GROUP_NAME, true);producer.setNamesrvAddr(WanfengConstant.NAMESRV_ADDR);producer.start();for (int i = 0; i < 20; i++) {try {Message message = new Message("TopicTest",WanfengConstant.TAGS_NAME,("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /*消息体转换成二进制数组*/);SendResult sendResult = producer.send(message);System.out.printf("%s%n", sendResult);} catch (Exception e) {e.printStackTrace();}}}
}
相关文章:
【Java中间件】RocketMQ
RocketMQ 一、MQ概述 Message Queue,是一种提供消息队列服务的中间件。提供了消息生产、存储、消费全过程API的软件系统。 MQ的作用 限流削峰:当用户发送超量请求时,将请求暂存,以便后期慢慢处理。如果不使用MQ暂存直接请求到…...
Megatron-LM、NVIDIA NeMo、MegaMolBART 、model_optim_rng.pt 文件是什么?
本文涉及以下几个概念,分别是: Megatron和Megatron-LM-v1.1.5-3D_parallelism NVIDIA NeMo Megatron和Megatron-LM-v1.1.5-3D_parallelism是什么? Megatron是由NVIDIA开发的一种用于训练大规模语言模型的开源框架。它旨在提供高效的分布式…...
2023年信息系统项目管理师如何报名?老司机告诉你
信息系统项目管理师是全国计算机技术与软件专业技术资格(水平)考试(简称软考)项目之一,是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试,既属于国家职业资格考试,又是职称资…...
linux ubuntu系统 命令备忘
一、安装软件包的命令 1、验证安装包是否安装 dpkg -s <软件包名> 2、从软件源服务器获取最新的软件信息并缓存到本地 apt update 3、从本地仓库中对比系统中所有已安装的软件,如果有新版本的话则进行升级 apt upgrade 4、列出本地仓库中所有的软件包名…...
我的第一个flutter项目(Android Webview)
前言:flutter开发环境搭建Flutter的开发环境搭建-图解_☆七年的博客-CSDN博客 第一个flutter简单项目,内容是一个主界面,其中: 1.内容点击数字自增 2.跳转一个空页, 3.跳转一个WebView界面 其中涉及添加主键…...
微信机器人搭建详细教程
确保已安装Python和pip。 在D盘上创建名为wxbot的文件夹,并将你的Python机器人项目文件放在这个目录中。 在D盘的wxbot文件夹中打开命令行工具,并创建一个新的Python虚拟环境(可选): python -m venv venv激活虚拟环…...
opengauss安装
opengauss安装 系统环境 Redhat版本:redhat7.6 虚拟机ip:192.168.5.144 Gauss版本:openGauss-5.0.0-CentOS-64bit-all.tar.gz 企业版 一.准备软硬件环境 1.1 安装依赖包 yum -y install bzip2 python3 libaio-devel flex bis…...
什么是SVM算法?硬间隔和软间隔的分类问题
SVM全称是supported vector machine(支持向量机),即寻找到一个超平面使样本分成两类,并且间隔最大。 SVM能够执行线性或⾮线性分类、回归,甚至是异常值检测任务。它是机器学习领域最受欢迎的模型之一。SVM特别适用于中小型复杂数据集的分类。…...
Normalization(BN and LN) in NN
Batch Normalization 称为批标准化。批是指一批数据,通常为 mini-batch;标准化是处理后的数据服从 N ( 0 , 1 ) N(0,1) N(0,1) 的正态分布。在训练过程中,数据需要经过多层的网络,如果数据在前向传播的过程中,尺度发…...
opencv-22 图像几何变换01-缩放-cv2.resize()(图像增强,图像变形,图像拼接)
什么是几何变换? 几何变换是计算机图形学中的一种图像处理技术,用于对图像进行空间上的变换,而不改变图像的内容。这些变换可以通过对图像中的像素位置进行调整来实现。 常见的几何变换包括: 平移(Translation&#x…...
python机器学习(五)逻辑回归、决策边界、代价函数、梯度下降法实现线性和非线性逻辑回归
线性回归所解决的问题是把数据集的特征传入到模型中,预测一个值使得误差最小,预测值无限接近于真实值。比如把房子的其他特征传入到模型中,预测出房价, 房价是一系列连续的数值,线性回归解决的是有监督的学习。有很多场…...
聊聊Linq中.AsEnumerable(), AsQueryable() ,.ToList(),的区别和用法
聊聊Linq中.AsEnumerable(), AsQueryable() ,.ToList(),的区别和用法 当使用LINQ查询数据时,我们常常会面临选择使用.AsEnumerable(), .AsQueryable(), 和 .ToList()方法的情况。这些方法在使用时有不同的效果和影响,需要根据具体场景来选择合适的方法。…...
【机器学习】机器学习中的“本体”概念
一、说明 在机器学习中,本体越来越多地用于提供基于相似性分析和场景知识的 ML 模型。 在传统的基于标签的定义中,对象往往是孤立的,可扩展性差,存在重复的可能性,对象之间的关系无法体现。在基于本体的定义中…...
ChatGPT是否能够进行对话中的参考和指代解析?
ChatGPT在对话中的参考和指代解析方面有一定的潜力,但需要针对具体任务和上下文进行定制和优化。参考和指代解析是指理解对话中的代词、名词短语等表达方式所指代的具体对象或信息。在对话中,参考和指代解析对于理解上下文、保持对话连贯性和生成准确回复…...
网红项目AutoGPT源码内幕及综合案例实战(三)
AutoGPT on LangChain PromptGenerator等源码解析 本节阅读AutoGPT 的prompt_generator.py源代码,其中定义了一个PromptGenerator类和一个get_prompt函数,用于生成一个提示词信息。PromptGenerator类提供了添加约束、命令、资源和性能评估等内容的方法,_generate_numbered_l…...
第八章:list类
系列文章目录 文章目录 系列文章目录前言list的介绍及使用list的介绍list的使用list的构造函数list的迭代器list的容量list的成员访问list的增删改查 list与vector的对比总结 前言 list是STL的一种链表类,可以在常数范围内在任意位置进行插入和删除的序列式容器。 …...
VUE声音-报警-实现方式
1.先准备一个mp3文件包:(这个24小时生效如果失效可留言,看到就会增加时效) 获取mp3地址: https://www.aliyundrive.com/t/uQ8zqjn9JKSfm7QlGOSr2.代码内容 进入页面就会自动 播放mp3的内容信息了。 <template>…...
【Coppeliasim C++】焊接机械臂仿真
项目思维导图 该项目一共三个demo: 机械臂末端走直线 2. 变位机转台转动 3.机械臂末端多点样条运动 笔记: 基于等级的蚁群系统在3D网格地图中搜索路径的方法: 基于等级的蚁群系统(Hierarchical Ant Colony System,HACS)是一种改进的蚁群优化算法。它在传…...
【LeetCode】94.二叉树的中序遍历
题目 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2]示例 2: 输入:root [] 输出:[]示例 3: 输入:root [1] 输…...
AWS IAM介绍
前言 AWS是世界上最大的云服务提供商,它提供了很多组件供消费者使用,其中进行访问控制的组件叫做IAM(Identity and Access Management), 用来进行身份验证和对AWS资源的访问控制。 功能 IAM的功能总结来看,主要分两种࿱…...
OpenClaw邮件处理助手:Qwen3-14b_int4_awq分类与自动回复
OpenClaw邮件处理助手:Qwen3-14b_int4_awq分类与自动回复 1. 为什么需要邮件自动化助手 每天早晨打开邮箱,看到堆积如山的未读邮件总是让人头疼。订阅的新闻简报、工作沟通、广告推广混杂在一起,手动分类和回复消耗了大量时间。作为技术从业…...
Ollama快速体验Llama-3.2-3B:生成工作总结和报告实测
Ollama快速体验Llama-3.2-3B:生成工作总结和报告实测 1. 模型介绍与部署准备 1.1 Llama-3.2-3B模型特点 Llama-3.2-3B是Meta公司开发的多语言大型语言模型,专为文本生成任务优化。这个3B参数的版本在保持轻量级的同时,提供了出色的文本生成…...
SEO_避开常见SEO误区,让你的优化更高效
SEO误区:避开常见陷阱,让你的优化更高效 在当前互联网营销的环境中,搜索引擎优化(SEO)是一个至关重要的环节。无论你是一个新手还是有一些经验的网站管理者,都会遇到各种各样的SEO误区。这些误区不仅可能浪…...
低成本个人知识库:OpenClaw+Qwen3-32B构建自动化归档系统
低成本个人知识库:OpenClawQwen3-32B构建自动化归档系统 1. 为什么需要个人知识库自动化 作为一个长期与技术文档打交道的开发者,我发现自己陷入了一个怪圈:每天收集大量有价值的网页、论文和代码片段,但它们最终都散落在浏览器…...
实测:千元安卓机离线跑DeepSeek-R1 1.5B模型,写代码、解数学题够用吗?
千元安卓机实测:离线运行DeepSeek-R1 1.5B模型的全场景性能报告 去年我在西藏旅行时,手机全程处于无信号状态,却需要紧急处理一封英文邮件。当时就幻想如果AI模型能完全离线运行该多好——没想到半年后这个愿望已成现实。最近一周,…...
KingbaseES V8R6备份还原踩坑实录:sys_dump、sys_restore和ksql到底怎么选?
KingbaseES V8R6备份还原实战指南:工具选型与典型问题解析 第一次接触KingbaseES V8R6的备份还原工作时,面对sys_dump、sys_restore和ksql这三个工具,我像大多数新手一样陷入了选择困难。记得那次紧急数据迁移任务,当我信心满满地…...
东方电机RS485嵌入式协议库:多型号统一控制与工业可靠性设计
1. 项目概述OrientalCommon_asukiaaa 是一个专为东方电机(Oriental Motor)RS485通信设备设计的嵌入式通用接口库。该库不直接实现物理层驱动,而是聚焦于协议层抽象与控制逻辑封装,为上层应用提供统一、可移植、符合工业现场总线规…...
华人辍学博士揪出Claude Code 51万行源码泄露,官方请求下架超8000个GitHub代码库并回应:这次是人为失误,无人被解雇!
整理 | 苏宓 出品 | CSDN(ID:CSDNnews) 这两天 AI 圈的热点话题,莫过于 Claude Code 51 万行核心源码意外泄露事件。而这场风波的起点,并非什么高明的黑客攻击、也没有复杂的攻击路径,而是一位安全研究员的…...
第4章 Mosquitto命令行工具快速上手
第4章 Mosquitto命令行工具快速上手 4.1 命令行工具概览 #mermaid-svg-J8aIvd39QR9TuYWA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-…...
从零开始掌握小红书数据采集:xhs库的5大实战应用场景
从零开始掌握小红书数据采集:xhs库的5大实战应用场景 【免费下载链接】xhs 基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/ 项目地址: https://gitcode.com/gh_mirrors/xh/xhs 你是否曾经想过如何批量获取小红书上的热门内容?…...
