rabbitmq 方法的一些参数设置以及解释
消费者采用手动应答
// 采用手动应答 false 采用手动应答,true采用自动应答
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME,autoAck,deliverCallback,cancelCallback);
然后,需要在接收消息的内部类中添加手动应答消息的tag(标记)
// 声明 接收消息
DeliverCallback deliverCallback = (consumerTag, message) ->{
//沉睡
SleepUtils.sleep(30);
System.out.println("接收到的消息:"+new String(message.getBody(),"UTF-8"));
//手动应答
/**
* 1、消息的标记 tag
* 2、是否批量应答 false 不批量应答 true 批量应答
*/
channel.basicAck(message.getEnvelope().getDeliveryTag(),false);
};
队列持久化
Channel channel = RabbitMqUtils.getChannel();
// 声明队列
boolean durable = true; //queueDeclare 第二个参数 true 队列持久化 false 不持久化
channel.queueDeclare(QUEUE_NAME,durable,false,false,null);
//发消息
//String message = "hello world";
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
String message = scanner.next();
channel.basicPublish("",QUEUE_NAME,null,message.getBytes("UTF-8"));
System.out.println("生产者发送的消息:"+message);
}
消息持久化
// 要想让消息实现持久化需要在消息生产者,添加MessageProperties.PERSISTENT_TEXT_PLAIN这个属性
channel.basicPublish("",QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes("UTF-8"));
不公平分发 和 预取值
最开始学习的是RabbitMQ轮询的方式来发消息,这种情况下并不是最好的,最好的应该是处理任务快的多发消息,处理任务慢的少发消息。我们可以在消费者接收消息之前设置参数channel.basicQos(1)来实现
int prefetchCount = 1;
channel.basicQos(prefetchCount);
发布确认模式
单个确认
public static void publishMessageIndividually() throws Exception{
Channel channel = RabbitMqUtils.getChannel();
// 队列的声明
String queueName = UUID.randomUUID().toString();
channel.queueDeclare(queueName,true,false,false,null);
// 开启发布确认
channel.confirmSelect();
// 开始时间
long begin = System.currentTimeMillis();
// 批量发消息
for (int i = 0; i < MESSAGE_COUNT; i++) {
String message = i + "";
channel.basicPublish("",queueName,null,message.getBytes());
// 单个消息就马上发布确认
boolean flag = channel.waitForConfirms();
if(flag){
System.out.println("消息发送成功");
}
}
// 结束时间
long end = System.currentTimeMillis();
System.out.println("发布"+MESSAGE_COUNT+"个单独确认消息,耗时"+(end-begin)+"ms");
}
批量确认
public static void publishMessageBatch()throws Exception{
Channel channel = RabbitMqUtils.getChannel();
// 队列的声明
String queueName = UUID.randomUUID().toString();
channel.queueDeclare(queueName,true,false,false,null);
// 开启发布确认
channel.confirmSelect();
// 开始时间
long begin = System.currentTimeMillis();
//批量确认消息的大小
int batchSize = 100;
//批量发送消息 并且批量发布确认
for (int i = 0; i < MESSAGE_COUNT; i++) {
String message = i + "";
channel.basicPublish("",queueName,null,message.getBytes());
//判断批量消息达到100条的时候 批量确认一次
if(i % batchSize == 0){
channel.waitForConfirms();
}
}
// 结束时间
long end = System.currentTimeMillis();
System.out.println("发布"+MESSAGE_COUNT+"个批量确认消息,耗时"+(end-begin)+"ms");
}
异步确认
public static void publishMessageAsync() throws Exception{
Channel channel = RabbitMqUtils.getChannel();
// 队列的声明
String queueName = UUID.randomUUID().toString();
channel.queueDeclare(queueName,true,false,false,null);
// 开启发布确认
channel.confirmSelect();
/**
* 线程安全的一个hash表,适用于高并发的情况下
* 1、轻松的将序号御消息进行关联
* 2、轻松批量删除条目,只要给到序号
* 3、支持高并发(多线程)
*/
ConcurrentSkipListMap<Long,String> outStandingConfirms =
new ConcurrentSkipListMap<>();
// 消息确认成功 回调函数
ConfirmCallback ackCallback = (deliveryTag, mutiple) -> {
if(mutiple){ // 如果是批量确认
// 2、删除掉已经确认的消息,剩下就是未确认的消息
ConcurrentNavigableMap<Long, String> confirmed = outStandingConfirms.headMap(deliveryTag);
confirmed.clear();
}else{ // 如果不是批量确认
outStandingConfirms.remove(deliveryTag);
}
System.out.println("确认的消息:"+deliveryTag);
};
// 消息确认失败 回调函数
ConfirmCallback nackCallback = (deliveryTag, mutiple) -> {
// 3、打印一下未确认的消息
String message = outStandingConfirms.get(deliveryTag);
System.out.println("未确认的消息是"+message+".......未确认的标记:"+deliveryTag);
};
// 准备消息监听器 监听哪些消息成功 哪些消息失败
channel.addConfirmListener(ackCallback,nackCallback);
// 开始时间
long begin = System.currentTimeMillis();
for (int i = 0; i < MESSAGE_COUNT; i++) {
String message = i + "消息";
// 1、此处记录下所有要发送的消息,消息的总和
outStandingConfirms.put(channel.getNextPublishSeqNo(),message);
channel.basicPublish("",queueName,null,message.getBytes());
}
// 结束时间
long end = System.currentTimeMillis();
System.out.println("发布"+MESSAGE_COUNT+"个异步发布确认消息,耗时"+(end-begin)+"ms");
}