RabbitMq的消息应答机制

默认情况下,RabbitMQ 一旦向消费者发送了一条消息后,便立即将该消息标记为删除。由于消费者处理一个消息可能需要一段时间,假如在处理消息中途消费者挂掉了,我们会丢失其正在处理的消息以及后续发送给该消费者的消息。

为了保证消息在发送过程中不丢失,RabbitMQ 引入消息应答机制,消息应答意思就是:消费者在接收消息并且处理完该消息之后,才告知 RabbitMQ 可以把该消息删除了。

RabbitMQ 中消息应答方式有两种:自动应答(默认)、手动应答

   /**
         * 消费者消费消息
         * 1.消费哪个队列
         * 2.消费成功之后是否要自动应答 true 代表自动应答 false 手动应答
         * 3.消费者未成功消费的回调
         */
        channel.basicConsume(QueueNameConstant.XIAOXIYINGDA_MODEL,false,deliverCallback,cancelCallback);
自动应答

息发送后立即被认为已经传送成功,这种模式需要在高吞吐量和数据传输安全性方面做权 衡,因为这种模式如果消息在接收到之前,消费者那边出现连接或者 channel 关闭,那么消息就丢失了。

当然另一方面这种模式消费者那边可以传递过载的消息,没有对传递的消息数量进行限制, 当然这样有可能使得消费者这边由于接收太多还来不及处理的消息,导致这些消息的积压,最终使得内存耗尽,最终这些消费者线程被操作系统杀死。

所以这种模式仅适用在消费者可以高效并 以某种速率能够处理这些消息的情况下使用。

  • 不建议使用自动应答,实际业务场景中,一般我们使用手动应答。
手动应答

采用手动应答后的消息自动重新入队可以避免自动应答中消息丢失的情况。如果消费者由于某些原因失去连接(其通道已关闭,连接已关闭或 TCP 连接丢失),导致消息未发送 ACK 确认,RabbitMQ 将了解到消息未完全处理,并将对其重新排队。如果此时其他消费者可以处理,它将很快将其重新分发给另一个消费者。这样,即使某个消费者偶尔死亡,也可以确保不会丢失任何消息。

// 肯定确认
void basicAck(long deliveryTag, boolean multiple)

// 否定确认
void basicNack(long deliveryTag, boolean multiple, boolean requeue)
void basicReject(long deliveryTag, boolean requeue)

其中:deliveryTag表示消息的标志,multiple表示是否为批量应答(ture 代表批量应答channel上未应答的消息,比如当前channel上有传送tag为5678的消息,如果应答时tag=8,则5~8的这些还未应答的消息都会被确认收到消息应答;如果为 false 则此时只会应答tag=8的消息,567的消息不会被应答)

总结

在消息传播过程中,消息应答是应该关键的点,我们需要在效率和安全性之间进行抉择,一般在企业中消息应答机制都是手动应答,可以保证消费者宕机状态下消息仍然可以回到队列中再被其他消费者消费

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我是一名语言模型AI,不具备编写代码的能力。但我可以为你提供一些基于MATLAB的数字调制演示系统的参考代码,希望对你有所帮助: 1. ASK调制 % 定义基本参数 fc = 10; % 载波频率 fs = 100; % 采样频率 Ts = 1/fs; % 采样时间 % 定义信息序列 bit_rate = 5; % 信息速率 bit_length = fs/bit_rate; % 信息位长 info = randi([0 1],1,bit_length); % 随机生成0/1信息序列 % ASK调制 carrier = sin(2*pi*fc*(0:Ts:bit_length*Ts-Ts)); % 生成载波信号 ask_signal = carrier.*(2*info-1); % ASK调制 % 绘制波形图 t = 0:Ts:bit_length*Ts-Ts; subplot(3,1,1); plot(t,info); title('信息序列'); subplot(3,1,2); plot(t,carrier); title('载波信号'); subplot(3,1,3); plot(t,ask_signal); title('ASK调制信号'); 2. FSK调制 % 定义基本参数 fc1 = 10; % 第一个载波频率 fc2 = 20; % 第二个载波频率 fs = 100; % 采样频率 Ts = 1/fs; % 采样时间 % 定义信息序列 bit_rate = 5; % 信息速率 bit_length = fs/bit_rate; % 信息位长 info = randi([0 1],1,bit_length); % 随机生成0/1信息序列 % FSK调制 fsk_signal = []; for i=1:bit_length if info(i)==0 temp = sin(2*pi*fc1*(i-1)*Ts:Ts:2*pi*fc1*i*Ts-Ts); else temp = sin(2*pi*fc2*(i-1)*Ts:Ts:2*pi*fc2*i*Ts-Ts); end fsk_signal = [fsk_signal temp]; end % 绘制波形图 t = 0:Ts:bit_length*Ts*2-bit_length*Ts; subplot(3,1,1); plot(t,info); title('信息序列'); subplot(3,1,2); plot(t(1:bit_length*fs/bit_rate),fsk_signal(1:bit_length*fs/bit_rate)); title('FSK调制信号'); subplot(3,1,3); spectrogram(fsk_signal,[],[],[],fs,'yaxis'); title('FSK调制信号频谱图'); 3. PSK调制 % 定义基本参数 fc = 10; % 载波频率 fs = 100; % 采样频率 Ts = 1/fs; % 采样时间 % 定义信息序列 bit_rate = 5; % 信息速率 bit_length = fs/bit_rate; % 信息位长 info = randi([0 1],1,bit_length); % 随机生成0/1信息序列 % PSK调制 psk_signal = []; for i=1:bit_length if info(i)==0 temp = sin(2*pi*fc*(i-1)*Ts:Ts:2*pi*fc*i*Ts-Ts); else temp = sin(2*pi*fc*(i-1)*Ts:Ts:2*pi*fc*i*Ts-Ts+pi); end psk_signal = [psk_signal temp]; end % 绘制波形图 t = 0:Ts:bit_length*Ts*2-bit_length*Ts; subplot(3,1,1); plot(t,info); title('信息序列'); subplot(3,1,2); plot(t(1:bit_length*fs/bit_rate),psk_signal(1:bit_length*fs/bit_rate)); title('PSK调制信号'); subplot(3,1,3); spectrogram(psk_signal,[],[],[],fs,'yaxis'); title('PSK调制信号频谱图'); 以上是一些简单的数字调制演示系统的代码,你可以根据自己的需求进行修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值