RabbitMQ 在 Spring Boot中使用方式
文章目录
- 作用
- MQ docker 安装
- MQ使用
- RabbitMQ的整体架构及核心概念:
- RabbitMQ的整体架构及核心概念:
- 消费者消息推送限制
- 交换机与队列
- ## 项目使用MQ
- Direct: 直连模式
- Fanout: 广播模式
- Topic: 主题模式
- Headers: 头信息模式
- 使用DEMO地址
- 异常问题记录
作用
RabbitMQ 作为一款开源消息队列中间件(基于 AMQP 协议),在项目中主要解决系统间的异步通信、解耦、流量削峰等问题,提升系统的可扩展性和可靠性。以下是其核心作用及典型场景:
-
异步处理
- 场景:耗时操作(如发送邮件、短信、文件处理)异步执行,避免阻塞主流程。
- 示例:用户注册后,主线程快速返回,通过 RabbitMQ 异步触发邮件发送、数据清洗等任务。
- 优势:提升响应速度,优化用户体验,提高系统吞吐量。
-
应用解耦
- 场景:系统间通过消息通信,降低直接依赖。
- 示例:订单系统生成订单后,发送消息到队列,库存系统、物流系统各自订阅消息处理,任一系统故障不影响主流程。
- 优势:增强系统容错性,模块独立升级维护更灵活。
-
流量削峰
- 场景:应对突发高并发,避免服务过载。
- 示例:秒杀活动中,请求先写入消息队列,后端服务按处理能力消费,避免数据库被击穿。
- 优势:平滑流量波动,保护后端资源,结合限流策略提升系统稳定性。
-
日志收集与数据处理
- 场景:分布式系统中收集多节点日志或数据。
- 示例:多个服务将日志发送到 RabbitMQ,由统一消费者写入 Elasticsearch 或 Hadoop 分析。
- 优势:集中处理数据,降低对业务系统性能影响。
-
分布式系统协调
- 场景:实现跨服务事务最终一致性。
- 示例:电商下单后,通过消息队列通知积分系统增加积分,若失败则重试或补偿。
- 优势:替代同步 RPC 调用,降低分布式事务复杂度。
-
跨语言协作
- 场景:异构系统(不同语言/框架)间通信。
- 示例:Java 服务与 Python 数据分析服务通过 RabbitMQ 交换数据。
- 优势:协议标准化,支持多种客户端(Java、Python、Go 等)。
-
关键技术机制
- 可靠性:通过生产者确认(Publisher Confirm)、持久化(Persistent Messages)、消费者手动确认(ACK)确保消息不丢失。
- 灵活性:支持多种交换机类型(Direct、Topic、Fanout、Headers)实现消息路由。
- 扩展性:集群与镜像队列提供高可用,横向扩展消费者提升处理能力。
- 容错:死信队列(DLX)处理失败消息,避免消息无限重试。
注意事项
- 消息顺序:默认不保证严格顺序,需通过单队列单消费者或业务逻辑处理。
- 重复消费:网络重试可能导致消息重复,需业务层幂等设计。
- 监控:使用管理界面或 Prometheus + Grafana 监控队列积压、消费者状态。
典型应用案例
- 电商系统:订单状态更新、库存扣减、通知推送。
- 微服务架构:服务间事件驱动通信(如用户注销触发多系统清理)。
- IoT 数据流:设备上报数据缓冲与分发处理。
例如:
支付服务 ,将核心业务剥离 ,以下 交易服务、通知服务、 积分服务可以通过mq 去处理,无需实时服务调用

MQ docker 安装
docker pull rabbitmq:latestdocker run \-e RABBITMQ_DEFAULT_USER=root \-e RABBITMQ_DEFAULT_PASS=123456 \-v F:/docker/data/rabbitmq/plugins:/plugins \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:latest
# 运行mq
docker run -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 --name mq --hostname mq1 -p 15672:15672 -p 5672:5672 -d rabbitmq:3.8-management
# 进入容器
docker exec -it rabbitmq bash
# 开启 外部web页面
rabbitmq-plugins enable rabbitmq_management
MQ使用
RabbitMQ的整体架构及核心概念:
- virtual-host:虚拟主机,起到数据隔离的作用
- publisher:消息发送者
- consumer:消息的消费者
- queue:队列,存储消息
- exchange:交换机,负责路由消息
RabbitMQ的整体架构及核心概念:
virtual-host:虚拟主机,起到数据隔离的作用
publisher:消息发送者
consumer:消息的消费者
queue:队列,存储消息
exchange:交换机,负责路由消息
消费者消息推送限制
默认情况下,RabbitMQ的会将消息依次轮询投递给绑定在队列上的每一个消费者。但这并没有考虑到消费者是否已经处理完消息,可能出现消息堆积。
因此我们需要修改application.yml,设置preFetch值为1,确保同一时刻最多投递给消费者1条消息:
spring:rabbitmq:listener:simple:prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息
交换机与队列
交换机(Exchange):
交换机是用来接收生产者发送的消息并将这些消息路由到一个或多个队列中的实体。有不同类型
- Direct: 直连模式,根据路由键(Routing Key)精确匹配队列。
- Fanout: 广播模式,将消息广播给所有绑定到该交换机的队列,忽略路由键。
- Topic: 主题模式,使用通配符对路由键进行模式匹配来决定消息被发送到哪些队列。
- Headers: 头信息模式,基于消息头属性而非路由键来路由消息。
队列:
队列用于存储消息直到消费者可以处理它们。队列是实际存放消息的地方,消费者从这里获取消息。
绑定(Binding):
绑定是指将队列连接到交换机的过程。绑定时可以指定一个绑定键(Binding Key),这个键在不同的交换机类型中有不同的意义。
- 作用:它定义了交换机与队列之间的关系,即通过何种规则将消息从交换机路由到特定的队列。例如,在direct类型的交换机中,绑定键必须与消息的路由键完全匹配才能使消息进入对应的队列;而在topic类型的交换机中,则支持模式匹配。
## 项目使用MQ
maven 引入
<!-- amap -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
yaml 配置
spring:rabbitmq:host: 127.0.0.1port: 5672#虚拟主机virtual-host: /hmallusername: rootpassword: 123456
Direct: 直连模式
Direct: 直连模式
配置类定义队列、Direct类型的交换机以及它们之间的绑定关系。
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitConfig {// 定义队列@Beanpublic Queue myQueue() {return new Queue("myQueue", true); // true表示持久化队列}// 定义Direct交换机@Beanpublic DirectExchange directExchange() {return new DirectExchange("directExchange");}// 绑定队列到交换机上,并指定绑定键@Beanpublic Binding binding(Queue myQueue, DirectExchange directExchange) {return BindingBuilder.bind(myQueue).to(directExchange).with("routingKey");}
}
接收消息
@RabbitListener(queues = "myQueue")
public void receiveDirectMessage(String message) {System.out.println(" [x] Received '" + message + "'");
}
创建一个服务类用于向Direct交换机发送消息。
@Test
public void sendDirect(){String message = "Direct消息";rabbitTemplate.convertAndSend("test.direct", "test1", message);System.out.println(" [x] Sent '" + message + "'");
}
Fanout: 广播模式
广播模式通常指的是使用fanout类型的交换机来实现消息的广播。fanout交换机会将接收到的消息广播给所有绑定到该交换机的队列,而不考虑路由键(routing key)
配置Fanout Exchange和Queue
创建一个配置类来定义fanout类型的交换机以及需要绑定到此交换机的队列。
package com.itheima.consumer.config;import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitFanoutConfig {// 定义第一个队列@Beanpublic Queue queue1() {return new Queue("queue1", true); // 'true' for durable queue}// 定义第二个队列@Beanpublic Queue queue2() {return new Queue("queue2", true);}// 定义fanout类型的交换机@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("myFanoutExchange");}// 将queue1绑定到fanout交换机上@Beanpublic Binding binding1(Queue queue1, FanoutExchange fanoutExchange) {return BindingBuilder.bind(queue1).to(fanoutExchange);}// 将queue2绑定到fanout交换机上@Beanpublic Binding binding2(Queue queue2, FanoutExchange fanoutExchange) {return BindingBuilder.bind(queue2).to(fanoutExchange);}
}
发送消息
发送消息到fanout类型的交换机时,不需要指定路由键,因为fanout交换机会忽略路由键并将消息广播给所有绑定的队列。
@Test
public void sendFanout(){String message = "Fanout消息";rabbitTemplate.convertAndSend("myFanoutExchange", "", message);System.out.println(" [x] Sent '" + message + "'");
}
接收消息
为每个队列设置监听器来接收消息。
@RabbitListener(queues = "queue1")
public void receiveMessageFromQueue1(String message) {System.out.println("Queue1 [x] Received '" + message + "'");
}@RabbitListener(queues = "queue2")
public void receiveMessageFromQueue2(String message) {System.out.println("Queue2 [x] Received '" + message + "'");
}
所有绑定到myFanoutExchange交换机的队列都将接收到相同的消息。
Topic: 主题模式
主题模式(Topic Exchange)是一种灵活的消息路由机制。与直接模式(Direct Exchange)不同的是,主题交换机允许使用通配符来匹配消息的路由键(routing key),从而实现更加复杂的消息路由逻辑。下面是如何在Spring Boot中配置和使用主题模式的详细步骤。
在主题模式下,如果你想根据路由键进行个性化的监听,可以使用@RabbitListener的bindings属性,而不是直接指定队列名。这样可以根据路由键动态地监听消息。
- 在@RabbitListener中,使用了bindings属性来定义如何绑定队列到交换机上。
- value指定了要使用的队列,如果该队列不存在,则会自动创建。
- exchange指定了目标交换机及其类型(在这里是topic类型的交换机)。
- key定义了用于匹配消息路由键的绑定键。在这个例子中,item.*表示任何以item.开头的消息都会被发送到queue1;而#.update则匹配任何以.update结尾的消息并将其发送到queue2。
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "queue1", durable = "true"),exchange = @Exchange(value = "topicExchange", type = "topic"),key = "item.*"))
public void receiveMessageFromQueue11(String message) {System.out.println("Queue1 [x] Received '" + message + "'");
}@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "queue2", durable = "true"),exchange = @Exchange(value = "topicExchange", type = "topic"),key = "#.update"))
public void receiveMessageFromQueue21(String message) {System.out.println("Queue2 [x] Received '" + message + "'");
}
Topic Exchange发送消息。根据不同的路由键,消息会被分发到相应的队列中。
@Testpublic void sendTopic1(){String message = "Topic消息";rabbitTemplate.convertAndSend("topicExchange", "item.ded", message);System.out.println(" [x] Sent '" + message + "'");}@Testpublic void sendTopic(){String message = "Topic消息";rabbitTemplate.convertAndSend("topicExchange", "ded.update", message);System.out.println(" [x] Sent '" + message + "'");}
Headers: 头信息模式
Headers Exchange(头信息交换机)是一种基于消息头属性进行路由的消息传递机制。与直接模式(Direct Exchange)、扇出模式(Fanout Exchange)和主题模式(Topic Exchange)不同,Headers Exchange允许你根据消息的头部属性来决定路由逻辑,而不是简单的字符串匹配。
配置Headers Exchange、Queue及Bindings
创建一个配置类来声明Headers Exchange、队列以及它们之间的绑定关系。这里我们创建两个队列,并将它们通过不同的头部属性绑定到同一个Headers Exchange上。
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "queue6", durable = "true"),exchange = @Exchange(value = "headersExchange", type = "headers"),arguments = {@Argument(name = "type", value = "info"),@Argument(name = "format", value = "json")}))
public void receiveMessageHeaderFromQueue1(String message) {System.out.println("Queue1 [x] Received '" + message + "'");
}@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "queue7", durable = "true"),exchange = @Exchange(value = "headersExchange", type = "headers"),arguments = {@Argument(name = "type", value = "error")}))
public void receiveMessageHeaderFromQueue2(String message) {System.out.println("Queue2 [x] Received '" + message + "'");
}
发送消息
@Test
public void sendHeader(){Map<String, Object> headers = new HashMap<>();headers.put("type", "info");headers.put("format", "json");sendMessage(headers, "This is an info message in JSON format.");
}public void sendMessage(Map<String, Object> headers, String payload) {MessageProperties messageProperties = new MessageProperties();headers.forEach(messageProperties::setHeader);Message message = new Message(payload.getBytes(), messageProperties);rabbitTemplate.send("headersExchange", "", message);System.out.println(" [x] Sent with headers: " + headers + " and payload: " + payload);
}
使用DEMO地址
https://gitee.com/song_of_the_heart/mq-demo
异常问题记录
应该是 最新版的问题非集群, 退回到 3.8版本, docker 测试
org.springframework.amqp.AmqpIOException: java.io.IOExceptionat org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:70) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:603) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:725) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:252) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2210) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2183) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2163) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueInfo(RabbitAdmin.java:463) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:447) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.attemptDeclarations(AbstractMessageListenerContainer.java:1942) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.redeclareElementsIfNecessary(AbstractMessageListenerContainer.java:1915) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1384) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1230) ~[spring-rabbit-2.4.12.jar:2.4.12]at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.io.IOException: nullat com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:129) ~[amqp-client-5.14.2.jar:5.14.2]at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:125) ~[amqp-client-5.14.2.jar:5.14.2]at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:147) ~[amqp-client-5.14.2.jar:5.14.2]at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:439) ~[amqp-client-5.14.2.jar:5.14.2]at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1225) ~[amqp-client-5.14.2.jar:5.14.2]at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1173) ~[amqp-client-5.14.2.jar:5.14.2]at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connectAddresses(AbstractConnectionFactory.java:641) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connect(AbstractConnectionFactory.java:616) ~[spring-rabbit-2.4.12.jar:2.4.12]at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:566) ~[spring-rabbit-2.4.12.jar:2.4.12]... 12 common frames omitted
相关文章:
RabbitMQ 在 Spring Boot中使用方式
文章目录 作用MQ docker 安装MQ使用RabbitMQ的整体架构及核心概念:RabbitMQ的整体架构及核心概念:消费者消息推送限制交换机与队列## 项目使用MQDirect: 直连模式Fanout: 广播模式Topic: 主题模式Headers: 头信息模式 使用DEMO地址异常问题记录 作用 Ra…...
HAL库框架学习总结
概述:HAL库为各种外设基本都配了三套 API,查询,中断和 DMA。 一、HAL库为外设初始化提供了一套框架,这里以串口为例进行说明,调用函数 HAL_UART_Init初始化串口,此函数就会调用 HAL_UART_MspInit࿰…...
深入解析系统调用接口(System Call Interface, SCI)
在操作系统的世界中,用户态应用程序无法直接访问内核态资源,而必须通过一种受控的方式进行交互。这种方式就是系统调用(System Call)。系统调用接口(System Call Interface, SCI)是用户程序与操作系统内核之…...
深入理解Linux网络随笔(一):内核是如何接收网络包的(下篇)
3、接收网络数据 3.1.1硬中断处理 数据帧从网线到达网卡时候,首先到达网卡的接收队列,网卡会在初始化时分配给自己的RingBuffer中寻找可用内存位置,寻找成功后将数据帧DMA到网卡关联的内存里,DMA操作完成后,网卡会向…...
《只狼》运行时提示“mfc140u.dll文件缺失”是什么原因?要怎么解决?
《只狼》运行时提示“mfc140u.dll文件缺失”是什么原因?要怎么解决? 宝子们,是不是在玩《只狼》的时候,突然弹出一个提示:“找不到mfc140u.dll文件”?这可真是让人着急上火!别慌,今…...
SSM开发(十二) mybatis的动态SQL
目录 一、为什么需要动态SQL? Mybatis 动态 sql 是做什么的? 二、多种动态 SQL 元素 三、示例 1、model定义 2、数据库定义 3、UserMapper接口及UserMapper.xml内容定义 if标签 choose/when/otherwise 标签 foreach标签 trim 标签 四、动态SQL注意 一、为什么需…...
基于LVS负载均衡练习
对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势。 NAT模式,全称是网络地址转换模式。NAT模式下,负载均衡器(Director)会修改请求和响应的IP地址。客户端的请求先到达Director,Director将请…...
FreeRTOS低功耗总结
前言 Cortex-M核的MCU一般支持以下三种低功耗方式: ● 睡眠(Sleep)模式 ● 停止(Stop)模式 ● 待机(Standby)模式 睡眠模式 进入睡眠模式有两种指令:WFI(等待中断)和WFE(等待事件), WFI进入睡眠模式后,任意中断都可唤醒。 WFE进…...
【IC】AI处理器核心--第二部分 用于处理 DNN 的硬件设计
第 II 部分 用于处理 DNN 的硬件设计 第 3 章 关键指标和设计目标 在过去的几年里,对 DNN 的高效处理进行了大量研究。因此,讨论在比较和评估不同设计和拟议技术的优缺点时应考虑的关键指标非常重要,这些指标应纳入设计考虑中。虽然效率通常…...
React历代主要更新
一、React 16之前更新 React Fiber是16版本之后的一种更新机制,使用链表取代了树,是一种fiber数据结构,其有三个指针,分别指向了父节点、子节点、兄弟节点,当中断的时候会记录下当前的节点,然后继续更新&a…...
常用查找算法整理(顺序查找、二分查找、哈希查找、二叉排序树查找、平衡二叉树查找、红黑树查找、B树和B+树查找、分块查找)
常用的查找算法: 顺序查找:最简单的查找算法,适用于无序或数据量小的情况,逐个元素比较查找目标值。二分查找:要求数据有序,通过不断比较中间元素与目标值,将查找范围缩小一半,效率…...
Linux性能分析工具Trace使用
Linux Trace是⼀种⽤于抓取和分析系统运⾏时信息的⼯具。允许开发⼈员跟踪和分析系统的各种活动,以便深⼊了解系统的性能、⾏为和故障。下⾯是关于Linux Trace数据抓取的说明: 1. 数据抓取范围:Linux Trace可以抓取各种级别的数据,包括系统级别、进程级别和内核级别的数据。…...
2024华为OD机试真题-简单的自动曝光(C++)-E卷B卷-100分
2024华为OD机试最新E卷题库-(C卷+D卷+E卷)-(JAVA、Python、C++) 目录 题目描述 输入 输出 备注 示例1 示例2 解题思路 考点 代码 c++ 题目描述 一个图像有n个像素点,存储在一个长度为n的数组img里,每个像素点的取值范围[0,255]的正整数。 请你给图像每个像素点值…...
【python】向Jira测试计划下,附件中增加html测试报告
【python】连接Jira获取token以及jira对象 # 往 jira 测试计划下面,上传测试结果html def put_jira_file(plain_id):# 配置连接jiraconn ConnJira()jira conn.jira_login()[2]path jira.issue(O45- plain_id)attachments_dir os.path.abspath(..) \\test_API…...
STM32自学记录(九)
STM32自学记录 文章目录 STM32自学记录前言一、DMA杂记二、实验1.学习视频2.复现代码 总结 前言 DMA 一、DMA杂记 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预&…...
【C++】C++-教师信息管理系统(含源码+数据文件)【独一无二】
👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 【C】C教师信息管理系统(含源码&#x…...
Java Swing-5.jar 使用 jpackage 打包成 windows 可安装应用(exe,msi,免安装版exe)
环境 jdk17 (jdk14 以后自带将jar 打安装包工具 jpackage,版本从1.8调整到17) Maven:3.2.5 效果 对比 exe4j :免费版在启动的时候总是先弹出一个弹框,告诉用户你在用他们的免费版Launch4j:无法把jre环境打到exe文件中,用户需要单独…...
ADC入门准备(十):信号与系统知识回顾
4.7系统函数零极点分布决定时域特性 4.7.1 H(s)极点分布与h(t)的对应图解 4.7.2 H(s)、E(s)极点分布与自由响应、强迫响应特征的对应 4.8 H(s)零极点分布决定频域特性 4.8.1 s平面几何分析法 4.8.2 高通滤波器的频率特性 4.8.3 低通滤波器的频率特性 4.9 二阶谐振系…...
wx060基于springboot+vue+uniapp的宿舍报修系统小程序
开发语言:Java框架:springbootuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包&#…...
Spring Boot 配置 Mybatis 读写分离
JPA 的读写分离配置不能应用在 Mybatis 上, 所以 Mybatis 要单独处理 为了不影响原有代码, 使用了增加拦截器的方式, 在拦截器里根据 SQL 的 CRUD 来路由到不同的数据源 需要单独增加Mybatis的配置 Configuration public class MyBatisConfig {Beanpublic SqlSessionFactory…...
CCF-GESP 等级考试 2024年9月认证C++二级真题解析
2024年9月真题 一、单选题(每题2分,共30分) 正确答案:A 考察知识点:计算机存储 解析:磁心存储元件是早期计算机中用于存储数据的部件,它和现代计算机中的内存功能类似,都是用于临时…...
第二天:工具的使用
每天上午9点左右更新一到两篇文章到专栏《Python爬虫训练营》中,对于爬虫有兴趣的伙伴可以订阅专栏一起学习,完全免费。 键盘为桨,代码作帆。这趟为期30天左右的Python爬虫特训即将启航,每日解锁新海域:从Requests库的…...
HarmonyOS:使用List实现分组列表(包含粘性标题)
一、支持分组列表 在列表中支持数据的分组展示,可以使列表显示结构清晰,查找方便,从而提高使用效率。分组列表在实际应用中十分常见,如下图所示联系人列表。 联系人分组列表 在List组件中使用ListItemGroup对项目进行分组&#…...
Django5的新特征
Django是一个用Python编写的高级Web框架,它的目标是让开发人员能够快速高效地构建复杂的Web应用程序。自从2008年首次发布以来,Django已经成为开源Web框架中的佼佼者,被广泛应用于各种规模的项目中。Django 提供了一套强大且全面的工具&#…...
web自动化笔记(二)
文章目录 一、参数化测试1.pytest命令2.实现参数化测试3.填写地址测试4.生成Allure测试报告5.关键字驱动 二、案例1.实现后台登录1.1登录1.2.处理验证码1.3.封装识别验证码函数 2.通过cookie保持登录2.1给页面添加cookie2.2获取页面的cookie2.3自动化获取cookie 三、excel进行数…...
青少年编程与数学 02-009 Django 5 Web 编程 12课题、表单处理
青少年编程与数学 02-009 Django 5 Web 编程 12课题、表单处理 一、表单1. 表单类的定义示例:普通表单示例:模型表单 2. 字段类型3. 验证4. 渲染5. 表单处理示例:视图中的表单处理6. 自定义表单 二、验证1. 字段级验证示例2. 表单级验证示例3…...
JVM类加载和垃圾回收(详细)
文章目录 JVM介绍JDK/JRE/JVM的关系 内存结构堆程序计数器虚拟机栈本地方法栈本地内存 类文件字节码文件结构 类加载类的生命周期加载类加载器双亲委派模型 链接初始化类卸载 垃圾回收堆空间的基本结构内存分配和回收原则死亡对象判断方法垃圾收集算法垃圾收集器 JVM 介绍 JD…...
秘密信息嵌入到RGB通道的方式:分段嵌or完整嵌入各通道
目录 1. 将秘密信息分为三部分的理由 (1)均匀分布负载 (2)提高鲁棒性 (3)容量分配 2. 不将秘密信息分为三部分的情况 (1)嵌入容量 (2)视觉质量 &#…...
基于Flask的影视剧热度数据可视化分析系统的设计与实现
【FLask】基于Flask的影视剧热度数据可视化分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网技术的飞速发展,影视剧行业的数据量呈爆炸性增长&#x…...
Docker Desktop如何恢复出厂设置
在测试dify、ragfow等几个模型过程中,各种拉镜像建容器,导致错误提示“AssertionError(Can t access Redis. Please check the Redis status.)”,两个模型都无法使用,如何清空重建?请参照下面操作: 1、Win…...
