【02基础】- RabbitMQ基础
目录
- 2- RabbitMQ
- 2-1 介绍和安装
- 安装
- 2-2 RabbitMQ 快速入门
- 2-3 RabbitMQ 数据隔离
- 3- Java客户端
- 3-1 快速入门
- AMQP
- 快速入门
- 📑小结:SpringAMQP如何收发消息?
- 3-2 WorkQueues 任务模型
- 案例-使用 WorkQueue 单队列绑定多消费者
- 📑小结:Work模型的使用
- 3-3 Fanout 交换机
- 案例- FanouotExchange 使用
- 📑小结:交换机的作用是什么?
- 3-4 Direct 交换机
- 案例-利用 SpringAMQP 演示 DirectExchange 的使用
- 📑小结:DirectExchange 的作用是什么?
- 3-5 Topic 交换机
- 案例-利用 SpringAMQP 演示 DirectExchange 的适用
- 📑小结:描述下 Direct 交换机和 Topic 交换机的差异
- 3-6 声明队列和交换机
- 声明队列和交换机的方式(Java代码实现)
- 代码实现
- 使用注解的方式解决 Direct 交换机问题
- 📑小结
- 3-7 消息转换器
- 案例-利用 SpringAMQP 发送对象类型的消息
- 问题
- 4- 使用 MQ 改造支付业务代码
- 案例
2- RabbitMQ
2-1 介绍和安装
RabbitMQ 的整体架构以及核心概念
publisher:消息发送者cunsumer:消息消费者queue:队列exchange:交换机,负责路由消息virtual-host:虚拟主机,起到数据隔离的作用;一个 MQ 中可以创建多个virtual-host
数据流转的模型:①生产者将数据发送给交换机 ——> ②交换机将消息路由给队列 ——> ③消费者监听队列拿到消息

安装
- 上传镜像文件
mq.tar到 Linux 系统中 - 执行命令
docker load -i mq.tar
- 复制以下代码执行
- 其中 15672 ,是控制台端口
- 其中 5672 ,是收发消息的端口
docker run \
-e RABBITMQ_DEFAULT_USER=itheima \
-e RABBITMQ_DEFAULT_PASS=123321 \
-v mq-plugins:/plugins \
--name mq \
--hostname mq \
-p 15672:15672 \
-p 5672:5672 \
--network hmall \
-d \
rabbitmq:3.8-management
2-2 RabbitMQ 快速入门
需求
- 在
rabbitmq的控制台完成下列操作: - 新建队列
hello.queue1和hello.queue2 - 向默认的
amp.fanout交换机发送一条消息 - 查看消息是否到达
hello.queue1和hello.queue2
实现
- 需要创建队列,同时在交换机中需要绑定队列才能实现消息的路由。
总结规律
①如果交换机和队列没有绑定能否收到消息?
- 交换机:是负责路由和转发消息的。交换机通过绑定队列,之后可以将消息转发到队列中。
②如果绑定了所有队列是不是所有队列都可以收到消息?
- 是的,如果一个交换机绑定了多个队列,那类似于广播的效果所有队列都能收到消息。
2-3 RabbitMQ 数据隔离
- 在 RabbitMQ 中有虚拟主机的概念,对于交换机和队列而言都有二者自己的虚拟主机。
需求
- 在 RabbitMQ 的控制台下完成下列操作
- 新建一个用户 hmall
- 为 hmall 用户创建一个 vitual host
- 测试不同的 vitual host 之间的数据隔离现象
实现
- ① 首先在
Admin——>Users中创建用户 - ② 在
Admin——>Users中创建虚拟主机
总结
- 各个虚拟主机下都是相互隔离的。
3- Java客户端
3-1 快速入门
AMQP

什么是 AMQP?
- Advanced Message Queuing Protocol,是一种高级的消息队列协议,是用于在应用程序之间传递业务消息的开放标准。该协议与语言和平台无关,更符合微服务中独立性的要求。
Spring AMQP
Spring AMQP是基于 AMQP 协议定义的一套 API 规范,提供了模板来发送和接收消息。包含两部分,其中Spring AMQP是基础抽象,spring-rabbit是底层的默认实现
快速入门
需求
- 利用控制台创建队列 simple.queue
- 在 publisher 服务中,利用 SpringAMQP 直接向 simple.queue 发送消息
- 在 consumer 服务中,利用 SpringAMQP 编写消费者监听 simple.queue 队列

实现
- ① 引入
spring-amqp依赖,在父工程中引入spring-amqp依赖,这样publisher和consumer服务都可以使用
<!-- AMQP依赖,包含RabbitMQ -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- ② 在每个微服务中引入 MQ 服务端信息,这样微服务才能连接到 RabbitMQ

- ③ 发送消息: SpringAMQP 提供了 RabbitTemplate 工具类,方便我们发送消息,发送消息的代码如下
@Autowired
private RabbitTemplate rabbitTemplate;@Test
public void testSimpleQueue() {// 队列名称String queueName = "simple.queue";// 消息String message = "hello, spring amqp!";// 发送消息rabbitTemplate.convertAndSend(queueName, message);
}
- ④ 接收消息:
SpringAMQP提供声明式的消息监听,我们只需要通过 注解 在方法上声明要监听的队列名称,将来SpringAMQP就会把消息传递给当前方法。
@Slf4j
@Component
public class SpringRabbitListener {@RabbitListener(queues = "simple.queue")public void listenSimpleQueueMessage(String msg) throws InterruptedException {log.info("spring 消息接收到消息: [" + msg + "]");if (true) {throw new MessageConversionException("故意的");}log.info("消息处理完毕");}
}
📑小结:SpringAMQP如何收发消息?

3-2 WorkQueues 任务模型
- Work queues,任务模型。简单来说就是 让多个消费者绑定到一个队列,共同消费队列中的消息。

案例-使用 WorkQueue 单队列绑定多消费者
模拟 WorkQueue 实现一个队列绑定多个消费者,基本思路如下
- ① 在 RabbitMQ 的控制台创建一个队列,名为
work.queue - ② 在 publisher 服务中定义测试方法,在 1 秒内产生 50 条消息,发送到
work.queue - ③ 在 consumer 服务中顶级两个消息监听者,都监听
work.queue队列 - ④ 消费者每 1 秒处理 50 条消息,消费者每 2 秒处理 5 条消息
实现
- ① 实现消费者
@Slf4j
@Component
public class MqListener {@RabbitListener(queues = "simple.queue")public void listenSimpleQueue(String msg) {System.out.println("消费者收到了simple.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 work.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 work.queue的消息: [" + msg + "]");}
}
- ② 实现生产者
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid testSendMessage2Queue() {String queueName = "simple.queue";String msg = "hello, amqp!";rabbitTemplate.convertAndSend(queueName, msg);}@Testvoid testWorkQueue() throws InterruptedException {String queueName = "work.queue";for (int i = 1; i <= 50; i++) {String msg = "hello, worker, message_" + i;rabbitTemplate.convertAndSend(queueName, msg);Thread.sleep(20);}}
}
结果
- 发现在消费的过程中,两个消费者并没有都消费 50 条消息。
- 二者消费的过程是采用轮询的方式进行消费。

通过改变消费速度
- 即便改变了消费的速度,消费的过程中消费者1 和消费者2,也是按照轮询的方式消费任务。
@RabbitListener(queues = "work.queue")public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 work.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 work.queue的消息: [" + msg + "]");Thread.sleep(20);}
📑小结:Work模型的使用

3-3 Fanout 交换机
Fanout Exchange 交换机会将收到的消息广播到每一个跟其绑定的 queue,所以也叫 广播模式

案例- FanouotExchange 使用
实现思路如下
- ① 在 RabbitMQ 控制台中,声明队列
fanout.queue1和fanout.queue2 - ② 在 RabbitMQ 控制台中,声明交换机
hmall.fanout将两个队列与其绑定 - ③ 在 consumer 服务中,编写两个消费者方法,分别监听
fanout.queue1和**fanout.queue2 - ④ 在 publisher 中编写测试方法,向
hmall.fanout发送消息。

Fanout 交换机
- 消费者
@RabbitListener(queues = "fanout.queue1")
public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 fanout.queue1的消息: [" + msg + "]");
}@RabbitListener(queues = "fanout.queue2")
public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 fanout.queue2的消息: [" + msg + "]");
}
- 生产者
@Test
void testSendFanout() {String exchangeName = "hmall.fanout";String msg = "hello,everyone";rebbitTemplate.converAndSend(exchangeName,numm,msg);
}
- 运行结果

📑小结:交换机的作用是什么?

3-4 Direct 交换机
Direct Exchange 会将接收到的消息根据路由规则路由到指定的 Queue,因此可以称为定向路由。
- 每一个 Queue 都与 Exchange 设置一个 Bindingkey
- 发布者发送消息时,制定消息的 RoutingKey
- Exchange 将消息路由到 BindingKey 与消息 RoutingKey 一致的队列

案例-利用 SpringAMQP 演示 DirectExchange 的使用
需求如下
- ① 在 RabbitMQ 控制台中,声明队列 direct.queue1 和 direct.queue2
- ② 在 RabbitMQ 控制台中,声明交换机 hmall.direct,将两个队列与其绑定
- ③ 在 consumer 服务中,编写两个消费方法,分别监听 direct.queue1 和 direct.queue2
- ④ 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 hmall.direct 发送消息

📑小结:DirectExchange 的作用是什么?
:::info
- DirectExchange 交换机可以通过 bindingKey 来设置,将消息通过 bindingKey 发送到指定的队列中。通过设置合适的绑定键,您可以确保特定的消息被发送到特定的微服务进行处理。这样可以实现消息的精确路由,确保消息只被需要的消费者接收和处理。
:::
3-5 Topic 交换机
TopicExchange 与 DirectExchange 类似,区别在于 routingKey 可以是多个单词的列表,并且以 . 分割。
- Queue 与 Exchange 指定 BindingKey 时可以使用通配符
#代表 0 个 或多个单词。*:代指一个单词

- 类似上述实现,如果一个 bindingKey 定义为了
china.#那么,对于其而言只会接收与china.#开头的消息。
案例-利用 SpringAMQP 演示 DirectExchange 的适用
需求如下
- ① 在 RabbitMQ 控制台中,声明队列 topic.queue1 和 topic.queue2
- ② 在 RabbitMQ 控制台中,声明交换机 hmall.topic 将两个队列与其绑定
- ③ 在 consumer 服务中,编写两个消费者方法,分别监听 topic.queue1 和 topic.queue2
- ④ 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 hmall.topic 发送消息

- 消费者
@RabbitListener(queues = "topic.queue1")
public void listenTopicQueue1(String msg) throws InterruptedException {System.out.println("消费者1 收到了 topic.queue1的消息: [" + msg + "] ");
}@RabbitListener(queues = "topic.queue2")
public void listenTopicQueue2(String msg) throws InterruptedException {System.out.println("消费者2 收到了 topic.queue2的消息: [" + msg + "] ");
}
- 发送者
- 以下情况消息会被路由到
**#.news**的队列中。
- 以下情况消息会被路由到
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "japan.news", msg);
}
- 发送者2
- 以下情况两个队列都会收到消息。
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "china.news", msg);
}
- 发送者3
- 以下情况只有队列1 会受到消息。
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "china.weather", msg);
}
📑小结:描述下 Direct 交换机和 Topic 交换机的差异

3-6 声明队列和交换机
- 使用 Java 代码声明队列交换机才是最靠谱的方式
声明队列和交换机的方式(Java代码实现)
SpringAMQP 提供了几个类,用来声明队列、交换机及其绑定关系
Queue:用于声明队列,可用工厂类QueueBuilder创建Exchange:用于声明交换机,可以用工厂类ExchangeBuilder构建Binding:用于声明队列和交换机的绑定关系,可以用工厂类BindingBuilder构建

代码实现
- 例如,声明一个 Fanout 类型的交换机,并且创建队列与其绑定
public class FanoutConfiguration {@Beanpublic FanoutExchange fanoutExchange(){// ExchangeBuilder.fanoutExchange("").build();return new FanoutExchange("hmall.fanout2");}@Beanpublic Queue fanoutQueue3(){// QueueBuilder.durable("ff").build();return new Queue("fanout.queue3");}@Beanpublic Binding fanoutBinding3(Queue fanoutQueue3, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue3).to(fanoutExchange);}@Beanpublic Queue fanoutQueue4(){// QueueBuilder.durable("ff").build();return new Queue("fanout.queue4");}@Beanpublic Binding fanoutBinding4(){return BindingBuilder.bind(fanoutQueue4()).to(fanoutExchange());}
}
使用注解的方式解决 Direct 交换机问题
- 由于 Direct 交换机可以配置对应的 key,但对于声明式方式来说,需要对每个 key 都写一个 binding 方法,这样效率很低,所以引入注解的方式实现
- SpringAMQP 还提供了基于 @RabbitListener 注解来声明队列和交换机的方式,在 Listener 的部分通过注解实现
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue1",durable = "true"),exchange = @Exchange(name = "hmall,direct",type = ExchangeTypes,DIRECT),key = {"red","blue"}
))
public void listenDirectQueue1(String msg) throws InterruptedException{System.out.println("消费者 1 收到了 direct.queueq 的消息:【"+msg+"】");
}
📑小结

3-7 消息转换器
案例-利用 SpringAMQP 发送对象类型的消息
- ① 声明一个队列,名为 object.queue
- ② 编写单元测试,向队列中直接发送一条消息,消息类型为 Map
- ③ 在控制台查看消息,总结你能发现的问题
// 准备消息
Map<String,Object> msg = new HashMap<>();
msg.put("name","Jack");
msg.put("age",21);
@Test
void testSendObject() {Map<String, Object> msg = new HashMap<>(2);msg.put("name", "jack");msg.put("age", 21);rabbitTemplate.convertAndSend("object.queue", msg);
}
问题
- Spring 对消息对象的处理是由 org.springframework,amqp.support.converter.MessageConveerter 来处理的。而默认实现是 SimpleMessageConverter,基于 JDK 的 ObjectOutputStream 完成序列化。
存在以下问题
- JDK 的序列化有安全风险
- JDK 序列化的消息太大
- JDK 序列化的消息可读性差
建议采用 JSON 薛丽华代替默认的的 JDK 序列化,要做两件事情:
- 在 publisher 和 consumer 中都要引入 Jackson 依赖:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>
- 在 publisher 和 consumer 中都要配置 MessageConverter
@Bean
public MessageConverter messageConverter() {return new Jackson2JsonMessageConverter();
}
4- 使用 MQ 改造支付业务代码
案例
- 需求:改造余额支付功能,不再同步调用交易服务的 OpenFeign 接口,而是采用异步的 MQ 通知交易服务更改订单状态

-
- 业务中引入 AMQP 依赖
<!-- amqp -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- 2.配置 MQ 的地址
spring:rabbitmq:host: 192.168.150.101port: 5672virtual-host: /hmallusername: hmallpassword: 123
-
- 配置 MQ 的 Configure
@Configuration
public class MqConfig {@Beanpublic MessageConverter jackson2JsonMessageConverter() {return new Jackson2JsonMessageConverter();}
}
-
- 编写监听器
@Component
@RequiredArgsConstructor
public class PayStatusListener {private final IOrderService orderService;@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "mark.order.pay.queue", durable = "true"),exchange = @Exchange(name = "pay.topic", type = ExchangeTypes.TOPIC),key = "pay.success"))public void listenOrderPay(Long orderId) {// 标记订单状态为已支付orderService.markOrderPaySuccess(orderId);}
}
-
- 业务异步调用
rabbitTemplate.convertAndSend("pay.topic", "pay.success", po.getBizOrderNo());
相关文章:
【02基础】- RabbitMQ基础
目录 2- RabbitMQ2-1 介绍和安装安装 2-2 RabbitMQ 快速入门2-3 RabbitMQ 数据隔离 3- Java客户端3-1 快速入门AMQP快速入门📑小结:SpringAMQP如何收发消息? 3-2 WorkQueues 任务模型案例-使用 WorkQueue 单队列绑定多消费者📑小结…...
vue3中跨层传递provide、inject
前置说明 在 Vue 3 中,provide 和 inject 是一对用于跨组件树传递数据的 API。它们允许你在祖先组件中使用 provide 提供数据或服务,然后在后代组件中使用 inject 来获取这些数据或服务。这种方式特别适用于跨多个层级的组件传递数据,而不需要…...
Nacos-1.4.6升级2.3.2
一、nacos-2.3.2部署(非升级测试步骤) 1、使用nginx进行代理 # nginx-1.25.5 docker run -d --name nginx-nacos --network nacos --privilegedtrue -v /data/nacos/nginx.conf:/etc/nginx/conf.d/default.conf -p 8848:8848 nginx:latest2、创建nacos服务 # nacos-2.3.2 do…...
东识集中文印管理系统|DW-S408系统的主要功能
集中文印管理系统以涉密文件集中管理为目标,实现办公文件汇总、打印信息生成、文件打印、文件追溯等功能,将用户与打印设备分离,有效防止纸媒泄密。 集中文印管理系统是由客户端和服务端两部分构成,客户端能够将打印文件上传至服…...
text-foreground讲解
1、fore单词讲解 fore 是 “forward” 或 “front” 的简写,意思是"前面的"、“前景的”。 一些常见的相关英文词: foreground fore ground,意思是"前景" background back ground,意思是"背景&qu…...
数字IC后端实现之Innovus Place跑完density爆涨案例分析
下图所示为咱们社区a7core后端训练营学员的floorplan。 数字IC后端实现 | Innovus各个阶段常用命令汇总 该学员跑placement前density是59.467%,但跑完place后density飙升到87.68%。 仔细查看place过程中的log就可以发现Density一路飙升! 数字IC后端物…...
【牛客刷题实战】二叉树遍历
大家好,我是小卡皮巴拉 文章目录 目录 牛客题目: 二叉树遍历 题目描述 输入描述: 输出描述: 示例1 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码(C语言) 兄弟们共勉 !&…...
消息队列mq有哪些缺点?
大家好,我是锋哥。今天分享关于【消息队列mq有哪些缺点?】面试题?希望对大家有帮助; 消息队列mq有哪些缺点? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 消息队列(MQ)的缺点 消…...
【CENet】多模态情感分析的跨模态增强网络
在MSA领域,文本的准确度远远高于音频和视觉,如果文本能达到90%,那么音频和视觉的准确度只有60%~80%,但是过往研究很少针对情感分析的背景下去提高音频和视频的准确度。 abstract: 多模态情感分析(MSA&…...
动态代理:面向接口编程,屏蔽RPC处理过程
RPC远程调用 使用 RPC 时,一般的做法是先找服务提供方要接口,通过 Maven把接口依赖到项目中。在编写业务逻辑的时候,如果要调用提供方的接口,只需要通过依赖注入的方式把接口注入到项目中,然后在代码里面直接调用接口…...
HTTP 405 Method Not Allowed:解析与解决
HTTP 405 Method Not Allowed:解析与解决 引言 在Web开发中,HTTP状态码是服务器与客户端之间通信的重要组成部分。当我们使用Python进行网络请求时,经常会遇到各种HTTP状态码。其中,HTTP 405 “Method Not Allowed” 错误是一个…...
推荐一款CAD/CAM设计辅助工具:Mastercam
Mastercam是一款非常好用的软件,我们的这款软件是由美国CNC软件公司开发,集平面制图、三维设计、曲面设计、数 控编程、刀具处理等多项强大功能于一体。软件的使用过程具有非常直观的特点,用户可以很方便地对自己的作品进行设计。 Mastercam不…...
位运算刷题记录
1. 使两个整数相等的位更改次数 3226. 使两个整数相等的位更改次数 给你两个正整数 n 和 k。 你可以选择 n 的 二进制表示 中任意一个值为 1 的位,并将其改为 0。 返回使得 n 等于 k 所需要的更改次数。如果无法实现,返回 -1。 class Solution {pub…...
爬虫技术——小白入狱案例
知孤云出岫 目录 1. 案例概述2. 案例需求分析3. 实现步骤Step 1: 环境准备Step 2: 分析百度图片URL请求规律Step 3: 编写爬虫代码代码解析 4. 运行代码5. 注意事项6. 案例总结 要实现大批量爬取百度图片,可以使用Python编写一个网络爬虫,通过发送HTTP请求…...
vue 果蔬识别系统百度AI识别vue+springboot java开发、elementui+ echarts+ vant开发
编号:R03-果蔬识别系统 简介:vuespringboot百度AI实现的果蔬识别系统 版本:2025版 视频介绍: vuespringboot百度AI实现的果蔬识别系统前后端java开发,百度识别,带H5移动端,mysql数据库可视化 1 …...
全新更新!Fastreport.NET 2025.1版本发布,提升报告开发体验
在.NET 2025.1版本中,我们带来了巨大的期待功能,进一步简化了报告模板的开发过程。新功能包括通过添加链接报告页面、异步报告准备、HTML段落旋转、代码文本编辑器中的文本搜索、WebReport图像导出等,大幅提升用户体验。 FastReport .NET 是…...
信息学科平台系统设计与实现:Spring Boot技术手册
5系统详细实现 5.1 用户信息管理 基于保密信息学科平台系统的系统管理员可以对用户信息查询。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.2 教师信息管理 管理员可以对教师信息进行查下和删除。具体界面如图5.2所示。 图5.2 教师信息界面 5.3 学科动态管理 管理…...
conda下jupyterlab安装问题以及交互绘图问题记录
安装 1. 直接conda install jupyterlab就好,只要在base环境下安装就行,可以在任意环境下执行jupyter lab启动。 2. 打开jupyter lab后显示Could not determine jupyterlab build status without nodejs,可以执行conda install nodejs安装no…...
尚硅谷react教程_扩展_setState更新状态的2种写法
1.setState setState更新状态的2种写法(1).setState(stateChange,[callback])----对象式的setState1.stateChange为状态改变对象(该对象可以体现出状态的更改)2.callback是可选的回调函数,它在状态更新完毕、界面也更新…...
C语言编写的自动取款机模拟程序
#include〈stdio。h> #include<string。h> #include <stdio.h> #include〈stdlib.h〉 #include〈direct.h〉 #include<io.h> #include 〈errno。h> /********************************************************…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
