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

RabbitMQ 高级特性

目录

1.消息确认

1.1 消息确认机制

1.2 手动确认方法

1. 2.1肯定确认

1.2.2 否定确认

1.3 SpringBoot 代码示例

1.3.1 配置确认机制

1.3.2 配置队列,交换机,绑定关系

1.3.3 生产者(向 rabbitmq 发送消息)

1.3.4 消费者(消费队列中的信息)

2.持久性

2.1 交换机持久化

2.2 队列持久化

2.3 消息持久化

Java 原生API 发送非持久化和持久化消息

Spring 的 RabbitTemplate 发送持久化消息

2.4 将交换器、队列、消息都设置了持久化之后就能百分之百保证数据不丢失了吗?

3. 发送方确认

3.1 confirm 确认模式

3.1.1 配置 RabbitMQ

3.1.2. 设置确认回调逻辑并发送消息

RabbitTemplate.ConfirmCallback (Spring)和 ConfirmListener (JDK)区别

3.2 return 退回模式

3.2.1. 配置 RabbitMQ

3.2.2. 设置返回回调逻辑并发送消息

rabbitTemplate.setMandatory(true);

ReturnedMessage

3.3 常见面试题

4. 重试机制

4.1 重试配置

4.2 配置交换机&队列

4.3 发送消息

4.4 消费消息

4.5 测试

4.6 手动确认

4.7 注意

5. TTL

5.1 设置消息的 TTL

5.1.1 先看针对每条消息设置 TTL

配置交换机&队列

发送消息

运⾏程序,观察结果

5.2 设置队列的 TTL

配置队列和绑定关系

发送消息

运⾏程序,观察结果

5.3 两者区别

6. 死信队列

6.1 死信的概念

6.2 代码示例

6.2.1 声明队列和交换机

6.2.2 正常队列绑定死信交换机

6.2.3 制造死信产生的条件

6.2.4 发送消息

6.2.5 测试死信

1. 程序启动之后,观察队列

2. 测试过期时间,到达过期时间之后,进⼊死信队列

3. 测试达到队列⻓度,消息进⼊死信队列

4. 测试消息拒收

6.3 常见面试题

1. 死信队列的概念

2. 死信的来源

3. 死信队列的应用场景

7. 延迟队列

7.1 概念

7.2 应用场景

7.3 TTL+死信队列实现

7.3.1 声明队列

7.3.2 生产者

7.2.3 消费者

7.2.4 测试

7.2.4 存在问题

7.4 延迟队列插件

7.4.1 下载并上传插件

7.4.2. 启动插件

7.4.3. 验证插件

7.5 基于插件延迟队列实现

7.5.1. 声明交换机,队列,绑定关系

7.5.2. 生产者

7.5.3. 消费者

7.5.4. 运行程序,并测试

7.6 常见面试题

7.6.1 介绍下 RabbitMQ 的延迟队列

8. 事务

8.1 配置事务管理器和开启事务

8.2 声明队列

8.3 生产者

8.4 测试

9. 消息分发

9.1 概念

9.2 应用场景

9.2.1 限流

1. 配置 prefetch 参数,设置应答⽅式为⼿动应答

2. 配置交换机,队列

3. 发送消息,⼀次发送 20 条消息

4. 消费者监听

5. 测试

9.2.2 负载均衡

1. 配置prefetch参数,设置应答⽅式为⼿动应答

2. 启动两个消费者

3. 测试


1.消息确认

1.1 消息确认机制

⽣产者发送消息之后,到达消费端之后,可能会有以下情况:

a. 消息处理成功

b. 消息处理异常

        RabbitMQ 向消费者发送消息之后,就会把这条消息删掉,那么第两种情况,就会造成消息丢失.

         那么如何确保消费端已经成功接收了,并正确处理了呢?

        为了保证消息从队列可靠地到达消费者,RabbitMQ 提供了消息确认机制(message acknowledgement)。消费者在订阅队列时,可以指定 autoAck 参数,根据这个参数设置,消息确认机制分为以下两种:

         • ⾃动确认: 当autoAck 等于true时,RabbitMQ 会⾃动把发送出去的消息置为确认,然后从内存(或 者磁盘)中删除,⽽不管消费者是否真正地消费到了这些消息.⾃动确认模式适合对于消息可靠性要求不⾼的场景.

        • ⼿动确认:当 autoAck 等于 false 时,RabbitMQ 会等待消费者显式地调⽤ Basic.Ack 命令,回复确认信号后才从内存(或者磁盘)中移去消息.这种模式适合对消息可靠性要求⽐较⾼的场景.

        消费信息的方法:

String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;

代码示例:

DefaultConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, 
AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}
};
channel.basicConsume(Constants.TOPIC_QUEUE_NAME1, true, consumer);

        当 autoAck 参数置为 false,对于 RabbitMQ 服务端⽽⾔,队列中的消息分成了两个部分:

⼀. 是等待投递给消费者的消息.

⼆. 是已经投递给消费者,但是还没有收到消费者确认信号的消息. 如果 RabbitMQ ⼀直没有收到消费者的确认信号,并且消费此消息的消费者已经断开连接,则 RabbitMQ 会安排该消息重新进⼊队列,等待投递给下⼀个消费者,当然也有可能还是原来的那个消费者.

        

        从 RabbitMQ 的 Web 管理平台上,也可以看到当前队列中 Ready(要发送给消费者的信息) 状态和 Unacked (发送给消费者还没有得到确认的信息)状态的消息数

Ready:等待投递给消费者的消息数

Unacked:已经投递给消费者,但是未收到消费者确认信号的消息数

1.2 手动确认方法

        消费者在收到消息之后,可以选择确认,也可以选择直接拒绝或者跳过,RabbitMQ 也提供了不同的确认应答的⽅式,消费者客户端可以调⽤与其对应的 channel 的相关⽅法,共有以下三种

1. 2.1肯定确认

Channel.basicAck(long deliveryTag, boolean multiple) 

        RabbitMQ 已知道该消息并且成功的处理消息.可以将其丢弃了.

        参数说明:

        1) deliveryTag: 消息的唯⼀标识,它是⼀个单调递增的 64 位的⻓整型值.deliveryTag 是每个通道 (Channel)独⽴维护的,所以在每个通道上都是唯⼀的.当消费者确认(ack)⼀条消息时,必须使⽤对应的通道上进⾏确认.

        2)multiple:是否批量确认.在某些情况下,为了减少⽹络流量,可以对⼀系列连续的 deliveryTag 进 ⾏批量确认.值为 true 则会⼀次性 ack 所有⼩于或等于指定 deliveryTag 的消息.值为false,则只确认当前指定 deliveryTag 的消息.

        deliveryTag 是 RabbitMQ 中消息确认机制的⼀个重要组成部分,它确保了消息传递的可靠性和顺序性。

1.2.2 否定确认

        Channel.basicReject(long deliveryTag, boolean requeue)  RabbitMQ 在 2.0.0 版本开始引⼊了 Basic.Reject 这个命令,消费者客户端可以调⽤ channel.basicReject ⽅法来告诉 RabbitMQ 拒绝这个消息. 参数说明:

        1) deliveryTag: 参考channel.basicAck

        2) requeue:表⽰拒绝后,这条消息如何处理. 如果 requeue 参数设置为 true,则 RabbitMQ 会重新将这条消息存⼊队列,以便可以发送给下⼀个订阅的消费者.如果 requeue 参数设置为 false,则RabbitMQ 会把消息从队列中移除,⽽不会把它发送给新的消费者.

        3. 否定确认: Channel.basicNack(long deliveryTag, boolean multiple, boolean requeue) Basic.Reject 命令⼀次只能拒绝⼀条消息,如果想要批量拒绝消息,则可以使⽤ Basic.Nack 这个命令.消费者客户端可以调⽤ channel.basicNack ⽅法来实现.

        参数介绍参考上⾯两个⽅法.multiple 参数设置为 true 则表⽰拒绝 deliveryTag 编号之前所有未被当前消费者确认的消息

1.3 SpringBoot 代码示例

        基于 SpringBoot 来演⽰消息的确认机制,使⽤⽅式和使⽤ RabbitMQ Java Client 库有⼀定差异.

Spring-AMQP 对消息确认机制提供了三种策略.

public enum AcknowledgeMode { NONE,MANUAL,AUTO;
}

1. AcknowledgeMode.NONE 

        ◦ 这种模式下,消息⼀旦投递给消费者,不管消费者是否成功处理了消息,RabbitMQ 就会⾃动确认 消息,从 RabbitMQ 队列中移除消息.如果消费者处理消息失败,消息可能会丢失.

2. AcknowledgeMode.AUTO(默认)

        ◦ 这种模式下,消费者在消息处理成功时会⾃动确认消息,但如果处理过程中抛出了异常,则不会确认消息.

3. AcknowledgeMode.MANUAL

        ◦ ⼿动确认模式下,消费者必须在成功处理消息后显式调⽤ basicAck ⽅法来确认消息.如果消 息未被确认, RabbitMQ 会认为消息尚未被成功处理,并且会在消费者可⽤时重新投递该消息,这 种模式提⾼了消息处理的可靠性,因为即使消费者处理消息后失败,消息也不会丢失,⽽是可以被重新处理.

1.3.1 配置确认机制

spring:rabbitmq:host: 192.168.66.129port: 5672virtual-host: wuyulinusername: wuyulinpassword: wuyulinlistener:simple:#acknowledge-mode: none#acknowledge-mode: autoacknowledge-mode: manual

1.3.2 配置队列,交换机,绑定关系

package com.yulin.rabbitmqadvancedfeatures.configuration;import com.yulin.rabbitmqadvancedfeatures.constants.RabbitMQConstant;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Created with IntelliJ IDEA.* Description:* User: wuyulin* Date: 2025-01-01* Time: 23:32*/
@Configuration
public class RabbitMQConfiguration {/*** 声明 ackExchange 交换机* */@Bean("ackExchange")public Exchange ackExchange(){return ExchangeBuilder.topicExchange(RabbitMQConstant.ACK_EXCHANGE_NAME).durable(true).build();}//2. 队列@Bean("ackQueue")public Queue ackQueue() {return QueueBuilder.durable(RabbitMQConstant.ACK_QUEUE).build();}//3. 队列和交换机绑定 Binding@Bean("ackBinding")public Binding ackBinding(@Qualifier("ackExchange") Exchange exchange,@Qualifier("ackQueue") Queue queue) {return BindingBuilder.bind(queue).to(exchange).with("ack").noargs();}
}

1.3.3 生产者(向 rabbitmq 发送消息)

package com.yulin.rabbitmqadvancedfeatures.controller;import com.yulin.rabbitmqadvancedfeatures.constants.RabbitMQConstant;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** Created with IntelliJ IDEA.* Description:* User: wuyulin* Date: 2025-01-01* Time: 23:38*/
@RestController
@RequestMapping("/producer")
public class ProductController {@Autowiredprivate RabbitTemplate rabbitTemplate;@RequestMapping("/ack")public String ack(){rabbitTemplate.convertAndSend(RabbitMQConstant.ACK_EXCHANGE_NAME, "ack", "consumer ack test...");return "发送成功!";}}

1.3.4 消费者(消费队列中的信息)

package com.yulin.rabbitmqadvancedfeatures.listener;import com.rabbitmq.client.Channel;
import com.yulin.rabbitmqadvancedfeatures.constants.RabbitMQConstant;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;/*** Created with IntelliJ IDEA.* Description:* User: wuyulin* Date: 2025-01-01* Time: 23:40*/
@Component
public class AckQueueListener {//指定监听队列的名称@RabbitListener(queues = RabbitMQConstant.ACK_QUEUE)public void ListenerQueue(Message message, Channel channel) throws Exception {long deliveryTag = message.getMessageProperties().getDeliveryTag();try {System.out.printf("接收到消息: %s, deliveryTag: %d/n",new String(message.getBody(),"UTF-8"), deliveryTag);//模拟处理失败int num = 3/0;//⼿动签收//deliveryTag:这是一个长整型(long)参数,代表了需要确认的消息的唯一标识符。当消息从队列中被获取(通常是通过 basicConsume 方法)时,每条消息都会被分配一个 deliveryTag。//true:这个布尔值参数表示消息是否只应被当前消费者确认。如果是 true,则消息只会被当前消费者确认,不会被其他消费者再次确认。如果是 false,则消息可能会被其他消费者确认,这在多消费者环境中有时是有用的。channel.basicAck(deliveryTag, true);System.out.println("处理完成");}catch (Exception e){//异常了就拒绝签收//第三个参数requeue, 是否重新发送, 如果为true, 则会重新发送,,若为false, 则直接丢弃channel.basicNack(deliveryTag, true,true);System.out.println("处理异常");}}
}

2.持久性

        我们如何保证当 RabbitMQ 服务停掉以后,⽣产者发送的消息不丢失呢.默认情况下,RabbitMQ 退出或者由于某种原因崩溃时,会忽视队列和消息,除⾮告知他不要这么做.RabbitMQ 的持久化分为三个部分:

交换器的持久化

队列的持久化

消息的持久化.

2.1 交换机持久化

        交换器的持久化是通过在声明交换机时是将 durable 参数置为 true 实现的.相当于将交换机的属性在服务器内部保存,当 MQ 的服务器发⽣意外或关闭之后,重启 RabbitMQ 时不需要重新去建⽴交换机,交换机会⾃动建⽴,相当于⼀直存在.如果交换器不设置持久化,那么在 RabbitMQ 服务重启之后,相关的交换机元数据会丢失,对⼀个⻓期使⽤的交换器来说,建议将其置为持久化的.

ExchangeBuilder.topicExchange(Constant.ACK_EXCHANGE_NAME).durable(true).build()

2.2 队列持久化

        队列的持久化是通过在声明队列时将 durable 参数置为 true实现的. 如果队列不设置持久化,那么在 RabbitMQ 服务重启之后,该队列就会被删掉,此时数据也会丢失.(队列没有了,消息也⽆处可存了) 队列的持久化能保证该队列本⾝的元数据不会因异常情况⽽丢失,但是并不能保证内部所存储的消息不会丢失.要确保消息不会丢失,需要将消息设置为持久化.我前⾯博客⽤的创建队列的⽅式都是持久化

QueueBuilder.durable(Constant.ACK_QUEUE).build();

        点进去看源码会发现,该⽅法默认 durable 是 true

public static QueueBuilder durable(String name) {return (new QueueBuilder(name)).setDurable();
}
private QueueBuilder setDurable() {this.durable = true;return this;
}

通过下⾯代码,可以创建非持久化的队列

QueueBuilder.nonDurable(Constant.ACK_QUEUE).build(); 

2.3 消息持久化

        消息实现持久化,需要把消息的投递模式( MessageProperties 中的 deliveryMode )设置为2, 也就是 MessageDeliveryMode.PERSISTENT

public enum MessageDeliveryMode {NON_PERSISTENT,//⾮持久化 PERSISTENT;//持久化 
}

        设置了队列和消息的持久化,当 RabbitMQ 服务重启之后,消息依旧存在.

        如果只设置队列持久化,重启之后消息会丢失.

        如果只设置消息的持久化,重启之后队列消失,继⽽消息也丢失.所以单单设置消息 持久化⽽不设置队列的持久化显得毫⽆意义.

Java 原生API 发送非持久化和持久化消息

//⾮持久化信息 
channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
//持久化信息 
channel.basicPublish("",QUEUE_NAME, 
MessageProperties.PERSISTENT_TEXT_PLAIN,msg.getBytes());

Spring 的 RabbitTemplate 发送持久化消息

// 要发送的消息内容 
String message = "This is a persistent message";// 创建⼀个Message对象,设置为持久化 
Message messageObject = new Message(message.getBytes(), new 
MessageProperties());
messageObject.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
// 使⽤RabbitTemplate发送消息 
rabbitTemplate.convertAndSend(Constant.ACK_EXCHANGE_NAME, "ack", 
messageObject);

        RabbitMQ 默认情况下会将消息视为持久化的,除非队列被声明为非持久化,或者消息在发送时被标记为非持久化

        注意将所有的消息都设置为持久化,会严重影响 RabbitMQ 的性能(随机).、写⼊磁盘的速度⽐写⼊内存的速度慢得不只⼀点点.对于可靠性不是那么⾼的消息可以不采⽤持久化处理以提⾼整体的吞吐量.在选择是否要将消息持久化时,需要在可靠性和吐吞量之间做⼀个权衡.

2.4 将交换器、队列、消息都设置了持久化之后就能百分之百保证数据不丢失了吗?

        将交换器、队列、消息都设置了持久化之后就能百分之百保证数据不丢失了吗?

        答案是否定的. 

        1. 从消费者来说,如果在订阅消费队列时将 autoAck 参数设置为 true,那么当消费者接收到相关消息之后,还没来得及处理就宕机了,这样也算数据丢失.这种情况很好解决,将 autoAck 参数设置为 false,并进⾏⼿动确认.

        2. 在持久化的消息正确存⼊RabbitMQ之后,还需要有⼀段时间(虽然很短,但是不可忽视)才能存⼊磁盘 中.RabbitMQ 并不会为每条消息都进⾏同步存盘(调⽤内核的 fsync ⽅法)的处理,可能仅仅保存到操作系统缓存之中⽽不是物理磁盘之中.如果在这段时间内 RabbitMQ 服务节点发⽣了宕机、重启等异常情况,消息保存还没来得及落盘,那么这些消息将会丢失.

这个问题怎么解决呢 ?

        1. 引⼊RabbitMQ 的仲裁队列(后⾯再讲),如果主节点(master)在此特殊时间内挂掉,可以⾃动切换到从节点(slave),这样有效地保证了⾼可⽤性,除⾮整个集群都挂掉(此⽅法也不能保证100%可靠,但是配置了仲裁队列要⽐没有配置仲裁队列的可靠性要⾼很多,实际⽣产环境中的关键业务队列⼀般都会设置仲裁队列).

        2. 还可以在发送端引⼊事务机制或者发送⽅确认机制来保证消息已经正确地发送并存储⾄RabbitMQ 中,详细参考下⼀个章节内容介绍--"发送⽅确认"

3. 发送方确认

        在使⽤ RabbitMQ 的时候,可以通过消息持久化来解决因为服务器的异常崩溃⽽导致的消息丢失,但是还有⼀个问题,当消息的⽣产者将消息发送出去之后,消息到底有没有正确地到达服务器呢?

        如果在消息到达服务器之前已经丢失(比如 RabbitMQ 重启,那么 RabbitMQ 重启期间⽣产者消息投递失败),持久化操作也解决不了这个问题,因为消息根本没有到达服务器,何谈持久化? RabbitMQ 为我们提供了两种解决⽅案:

        a. 通过事务机制实现

        b. 通过发送⽅确认(publisher confirm)机制实现

        事务机制⽐较消耗性能,在实际⼯作中使⽤也不多,咱们主要介绍 confirm 机制来实现发送⽅的确认.RabbitMQ 为我们提供了两个⽅式来控制消息的可靠性投递

1. confirm 确认模式

2. return 退回模式

3.1 confirm 确认模式

        Producer 在发送消息的时候,对发送端设置⼀个 ConfirmCallback 的监听,⽆论消息是否到达 Exchange,这个监听都会被执⾏,如果 Exchange 成功收到,ACK( Acknowledge character ,确认 字符)为 true,如果没收到消息,ACK 就为 false.

步骤如下:

1. 配置RabbitMQ

2. 设置确认回调逻辑并发送消息

接下来看实现步骤

3.1.1 配置 RabbitMQ

# 应用服务 WEB 访问端口
server:port: 8081
spring:rabbitmq:host: 192.168.66.129port: 5672virtual-host: wuyulinusername: wuyulinpassword: wuyulin#配置消息确认机制listener:simple:# 这种模式下,消息⼀旦投递给消费者,不管消费者是否成功处理了消息,RabbitMQ 就会⾃动确认 消息,从 RabbitMQ 队列中移除消息.如果消费者处理消息失败,消息可能会丢失.#acknowledge-mode: none# (默认)这种模式下,消费者在消息处理成功时会自动确认消息,但如果处理过程中抛出了异常,则不会确认消息.#acknowledge-mode: auto# ⼿动确认模式下,消费者必须在成功处理消息后显式调用 basicAck ⽅法来确认消息.如果消息未被确认, RabbitMQ 会认为消息尚未被成功处理,并且会在消费者可用时重新投递该消息,这种模式提⾼了消息处理的可靠性,因为即使消费者处理消息后失败,消息也不会丢失,而是可以被重新处理.acknowledge-mode: manual# 配置发送方确认机制publisher-confirm-type: correlated

3.1.2. 设置确认回调逻辑并发送消息

        ⽆论消息确认成功还是失败,都会调⽤ ConfirmCallback 的 confirm ⽅法.如果消息成功发送到MQ, ack 为 true.如果消息发送失败,ack 为 false,并且 cause 提供失败的原因.

        注入一个新的 RabbitTemplate 对象,设置发送方确认,并确认回调逻辑

@Configuration
public class RabbitMQConfiguration {//如果单独注入新的 confirmRabbitTemplate 对象,会将普通的 rabbitTemplate 也改掉,所以还需要注入一个普通的 rabbitTemplate 对象//普通的 RabbitTemplate@Bean("rabbitTemplate")public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);return rabbitTemplate;}//配置了发送方确认机制的 RabbitTemplate@Bean("confirmRabbitTemplate")public RabbitTemplate confirmRabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);rabbitTemplate.setConfirmCallback(new  RabbitTemplate.ConfirmCallback(){@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {System.out.printf("");if (ack){System.out.printf("消息接收成功, id:%s \n", correlationData.getId()

相关文章:

RabbitMQ 高级特性

目录 1.消息确认 1.1 消息确认机制 1.2 手动确认方法 1. 2.1肯定确认 1.2.2 否定确认 1.3 SpringBoot 代码示例 1.3.1 配置确认机制 1.3.2 配置队列,交换机,绑定关系 1.3.3 生产者(向 rabbitmq 发送消息) 1.3.4 消费者(消费队列中的信息) 2.持久性 2.1 交换机…...

第01章 07 MySQL+VTK C++示例代码,实现医学影像数据的IO数据库存储

要实现将医学影像数据(如DICOM文件或其他医学图像格式)存储到MySQL数据库中,并使用VTK进行数据读取和处理的C示例代码,可以按照以下步骤进行。这个示例将展示如何将DICOM图像数据存储到MySQL数据库,然后使用VTK读取并显…...

Mysql创建定时任务

mysql查看存储过程 SHOW PROCEDURE STATUS;查看event_scheduler show events;查看当前event_scheduler的状态 SHOW VARIABLES LIKE event_scheduler;关闭event_scheduler set GLOBAL event_schedulerOFF;删除event_scheduler drop event event_name;创建存储过程 -- 创建存…...

【MySQL篇】使用mysqldump导入报错Unknown collation: ‘utf8mb4_0900_ai_ci‘的问题解决

💫《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨ 💫《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(…...

专业学习|最优化理论(目标函数、约束条件以及解题三板斧)

个人学习使用资料,请勿传播,若有侵权联系删除,资料来源:fairy girl。 一、最优化理论:让决策更科学,让模型更高效 (一)什么是最优化理论? 最优化理论是数学的一个分支,它研究如何在一定约束条件下找到使目标函数达到最大值或最小值的最优解。 关键概念:最优化理论的…...

【Linux】gawk编辑器二

一、变量 gawk编程语言支持两种变量:内建变量和自定义变量。 1、内建变量 gawk使用内建变量来引用一些特殊的功能。 字段和记录分隔符变量 数据字段变量 此变量允许使用美元符号($)和字段在记录中的位置值来引用对应的字段。要引用记录…...

Hadoop美食推荐系统 爬虫1.8w+数据 协同过滤余弦函数推荐美食 Springboot Vue Element-UI前后端分离

Hadoop美食推荐系统 爬虫1.8w数据 协同过滤余弦函数推荐美食 Springboot Vue Element-UI前后端分离 【Hadoop项目】 1. data.csv上传到hadoop集群环境 2. data.csv数据清洗 3.MapReducer数据汇总处理, 将Reducer的结果数据保存到本地Mysql数据库中 4. SpringbootEchartsMySQL 显…...

吴恩达深度学习——神经网络编程的基础知识

文章内容来自BV11H4y1F7uH,仅为个人学习所用。 文章目录 二分分类一些符号说明 逻辑斯蒂回归传统的线性回归函数 y ^ w T x b \hat{y}w^T\boldsymbol{x}b y^​wTxbSigmoid激活函数逻辑斯蒂回归损失函数损失函数成本函数与损失函数的关系 梯度下降法计算图逻辑斯蒂…...

第14个项目:E-Learning在线学习平台Python源码

源码下载地址:https://download.csdn.net/download/mosquito_lover1/90292074 系统截图: 功能介绍: 响应式设计,完全支持移动端 现代化的UI界面 用户认证系统 课程展示功能 模块化的结构 要进一步完善这个应用,您可以: 添加用户认证系统(登录/注册) 实现课程详情页面…...

Qt之文件系统操作和读写

Qt creator 6.80 MinGw 64bit 文本文件是指以纯文本格式存储的文件,如cpp和hpp文件。XML文件和JSON文件也是文本文件,只是使用了特定的标记符号定义文本的含义,读取这种文本文件需要先对内容解析再显示。 qt提供了两种读写文本文件的方法。…...

【物联网】keil仿真环境设置 keilV5可以适用ARM7

文章目录 一、ARM指令模拟器环境搭建1. keil软件2. Legacy Support 二、Keil仿真环境设置1. 创建一个项目2. 编译器介绍(1)arm-none-eabi-gcc(2)arm-none-linux-gnueabi-gcc(3)arm-eabi-gcc(4)grmcc(5)aarch64-linux-gnu-gcc 3. 安装编译器(1)设置调试 一、ARM指令模拟器环境搭…...

VIVADO ILA IP进阶使用之任意设置ILA的采样频率

VIVADO ILA IP进阶使用之任意设置ILA的采样频率 VIVADO ILA IP和VIO IP结合使用任意设置ILA的采样频率 目录 前言 一、VIO IP的配置 二、ILA IP的配置 三、测试代码 四、测试结果 总结 前言 VIVADO中编写完程序上板测试时经常会用到viavdo自带的ILA逻辑分析仪IP核&#x…...

网络编程-网络原理HTTP初识

文章目录 TCP/IP五层协议栈关于自定义协议常见自定义协议引入行文本格式XML格式JSONprotobuf HTTP原理非自定义的应用层协议HTTP的发展HTTP的传输模式HTTP协议中的代理模式和抓包工具 TCP/IP五层协议栈 具体的内容, 我们之前的网络初始里面有, 其实就是先前的计算机的发明者把…...

基于若依框架的动态分页逻辑的实现分析

如果让我们自己写分页查询的逻辑,应该怎么写呢? 在前端要完成分页的逻辑实际要做的工作还是挺多的。 分页查询应该支持查询参数的输入,对于一个有众多属性的列表,可能有很多查询参数,对于不同的参数类型,…...

51c~ONNX~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/11608027 一、使用Pytorch进行简单的自定义图像分类 ~ONNX 推理 图像分类是计算机视觉中的一项基本任务,涉及训练模型将图像分类为预定义类别。本文中,我们将探讨如何使用 PyTorch 构建一个简单的自定…...

【数据结构篇】顺序表 超详细

目录 一.顺序表的定义 1.顺序表的概念及结构 1.1线性表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 二.动态顺序表的实现 1.准备工作和注意事项 2.顺序表的基本接口: 2.0 创建一个顺序表 2.1 顺序表的初始化 2.2 顺序表的销毁 2.3 顺序表的打印 3.顺序…...

kubernetes 集群搭建(二进制方式)

Kubernetes 作为当今最流行的容器编排平台,提供了强大的功能来管理和扩展容器化应用。除了使用 kubeadm 等工具简化集群的创建过程外,直接通过二进制文件安装 Kubernetes 组件也是一种常见的方法。这种方式给予用户更多的控制权,并且适用于那…...

linux平台RTMP|RTSP播放器如何回调SEI数据?

我们在对接Linux平台RTMP|RTSP播放的时候,有遇到这样的技术需求,合作企业在做无人机视觉分析场景的时候,除了需要低延迟的拿到解码后的RGB|YUV数据,然后投递给他们自己的视觉算法处理模块外,还需要播放器支持SEI的回调…...

Vue uni-app免手动import

unplugin-auto-import 是一个流行的 JavaScript/TypeScript 插件,可以自动导入常用的库、API 或自定义函数,减少手动书写 import 语句的繁琐操作。它常用于 Vue、React 等框架,帮助开发者提高效率和减少样板代码。 核心功能: 自…...

7. 计算机视觉

计算机视觉(Computer Vision,简称 CV)是人工智能(AI)领域中的一个重要分支,旨在使计算机能够像人类一样“看”并理解数字图像或视频。它结合了计算机科学、数学、图像处理、模式识别、机器学习等多个学科&a…...

云原生时代的系统设计:架构转型的战略支点

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、云原生的崛起:技术趋势与现实需求的交汇 随着企业业务的互联网化、全球化、智能化持续加深,传统的 I…...

linux设备重启后时间与网络时间不同步怎么解决?

linux设备重启后时间与网络时间不同步怎么解决? 设备只要一重启,时间又错了/偏了,明明刚刚对时还是对的! 这在物联网、嵌入式开发环境特别常见,尤其是开发板、树莓派、rk3588 这类设备。 解决方法: 加硬件…...

Linux系统:进程间通信-匿名与命名管道

本节重点 匿名管道的概念与原理匿名管道的创建命名管道的概念与原理命名管道的创建两者的差异与联系命名管道实现EchoServer 一、管道 管道(Pipe)是一种进程间通信(IPC, Inter-Process Communication)机制,用于在不…...

Spring Boot SQL数据库功能详解

Spring Boot自动配置与数据源管理 数据源自动配置机制 当在Spring Boot项目中添加数据库驱动依赖(如org.postgresql:postgresql)后,应用启动时自动配置系统会尝试创建DataSource实现。开发者只需提供基础连接信息: 数据库URL格…...

【自然语言处理】大模型时代的数据标注(主动学习)

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构D 实验设计E 个人总结 A 论文出处 论文题目:FreeAL: Towards Human-Free Active Learning in the Era of Large Language Models发表情况:2023-EMNLP作者单位:浙江大…...

【Go语言基础【6】】字符串格式化说明

文章目录 零、格式化常用场景一、Go 字符串格式化核心概念二、常用格式化占位符1. 整数类型2. 浮点数类型3. 字符串与布尔类型4. 指针与通用类型 三、宽度与精度控制1. 宽度控制2. 精度控制(浮点数/字符串) 零、格式化常用场景 数值转字符串&#xff1a…...

JVM——对象模型:JVM对象的内部机制和存在方式是怎样的?

引入 在Java的编程宇宙中,“Everything is object”是最核心的哲学纲领。当我们写下new Book()这样简单的代码时,JVM正在幕后构建一个复杂而精妙的“数据实体”——对象。这个看似普通的对象,实则是JVM内存管理、类型系统和多态机制的基石。…...

操作系统期末版

文章目录 概论处理机管理进程线程处理机调度生产者消费者问题 死锁简介死锁的四个必要条件解决死锁的方法 存储管理链接的三种方式静态链接装入时动态链接运行时链接 装入内存的三种方式绝对装入可重定位装入动态运行时装入 覆盖交换存储管理方式连续分配**分段存储管理方式***…...

el-input限制输入数字,输入中文后数字校验失效

想要的效果:默认值为0,只能输入0-100的数字。 实现方式如下,使用 οnkeyup"this.valuethis.value.replace(/\D/g,‘’)"限制只能输入数字,输入数字没有问题,使用input实现数字不以0开头,也只能是…...

【CUDA 】第5章 共享内存和常量内存——5.3减少全局内存访问(2)

CUDA C编程笔记 第五章 共享内存和常量内存5.3 减少全局内存访问5.3.2 使用展开的并行规约思路reduceSmemUnroll4(共享内存)具体代码:运行结果意外发现书上全局加载事务和全局存储事务和ncu中这两个值相同 5.3.3 动态共享内存的并行规约reduc…...