rabbitmq - 流量控制
在 helloworld 的案例中,如果开启两个 Receive,消息被平均发送给了 2 个 Receive。
很多情况下,我们并不希望消息平均分配,可以对代码做如下修改。
场景:a 侦听器处理快,b 侦听器处理的慢,我们希望能将更多的消息分配给a。
import cn.swsk.springboot.rgyx.jx.test.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* @author Mr.css
* @date 2020-11-12 9:31
*/
public class Receive {
private static final String QUEUE_NAME = "queue_name";
public static void main(String[] args) {
try {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 限制消息接收的数量
channel.basicQos(0,1,false);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) {
String message = new String(body, StandardCharsets.UTF_8);
System.out.println("[Receive]:" + message);
try {
Thread.sleep(500);
//手动应答
channel.basicAck(envelope.getDeliveryTag(), false);
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
};
//自动应答设置为false
channel.basicConsume(QUEUE_NAME, false, consumer);
} catch (IOException | ShutdownSignalException | ConsumerCancelledException e) {
e.printStackTrace();
}
}
}
Qos(Quality of Service)直译是:服务质量,但是在这个场景下,理解为带宽分配、流量控制会更加合理
注意:MQTT 服务中也有一个 Qos 的概念,与当前不是一个东西,MQTT 是一种网络传输协议,rabbitmq 也支持使用这种协议。
basicQos(prefetchSize, prefetchCount, global)
These settings impose limits on the amount of data the server will deliver to consumers before requiring acknowledgements.Thus they provide a means of consumer-initiated flow control.
这些设置限制了服务器在请求确认之前将发送给消费者的数据量。因此,它们提供了一种消费者发起的流量控制方法。
参数说明
prefetchSize:服务器将提供的最大内容量(以字节为单位),如果没有限制则为0,似乎必须为0,程序执行到此报错,说还没有实现不为0的情况。
maximum amount of content (measured in octets) that the server will deliver, 0 if unlimited
prefetchCount:服务器将发送的最大消息数,如果没有限制,则为0。
maximum number of messages that the server will deliver, 0 if unlimited
global:设置是否应用于整个Connection,一个Connection可以有多个Channel,false则只对当前Channel有效。
true if the settings should be applied to the entire channel rather than each consumer