先介绍rabbmitmq的几个方法:
// 声明一个队列 -// queue 队列名称 // durable 为true时server重启队列不会消失 (是否持久化) // exclusive 队列是否是独占的,如果为true只能被一个connection使用,其他连接建立时会抛出异常 // autoDelete 当没有任何消费者使用时,自动删除该队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
/* * 向server发布一条消息 * 参数1:exchange名字,若为空则使用默认的exchange * 参数2:routing key * 参数3:其他的属性 * 参数4:消息体 * RabbitMQ默认有一个exchange,叫default exchange,它用一个空字符串表示,它是direct exchange类型, * 任何发往这个exchange的消息都会被路由到routing key的名字对应的队列上,如果没有对应的队列,则消息会被丢弃 */ channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
// 同一时刻服务器只会发一条消息给消费者(能者多劳模式) channel.basicQos(1);
/*消息消费完成确认 * autoAck 是否自动确认 true自动确认 false手动确认 * 模式1:自动确认 只要消息从队列中获取,无论消费者获取到消息后是否成功消息,都认为是消息已经成功消费。 * 模式2:手动确认 * 消费者从队列中获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,如果消费者一直没有反馈,那么 该消息将一直处于不可用状态。 * 如果选用自动确认,在消费者拿走消息执行过程中出现宕机时,消息可能就会丢失!! */ channel.basicConsume(TASK_QUEUE_NAME, false, consumer);
当手动确认时,一定要在消息处理完成后,确认提交,加上如下代码:
// 消息处理完成,手动确认提交 // deliveryTag 该消息的index // multiple:是否批量 true:将一次性ack所有小于deliveryTag的消息。 channel.basicAck(envelope.getDeliveryTag(), false);
/* * 使用fanout类型创建的交换器 * exchange:交换机名称 * type:交换机类型(direct/topic/fanout) */ channel.exchangeDeclare(EXCHANGE_NAME, ConfigKey.EX_FANOUT);
/* * 获取到一个临时队列名称。 * channel.queueDeclare():创建一个非持久化、独立、自动删除的队列名称 * 此队列是临时的,随机的,一旦我们断开消费者,队列会立即被删除 * 随机队列名,如amq.gen-jzty20brgko-hjmujj0wlg */ String queueName = channel.queueDeclare().getQueue();
/* * 将队列跟交换器进行绑定 * queue:队列名称 * exchange:交换机名称 * routingKey:队列跟交换机绑定的键值 */ channel.queueBind(queueName, EXCHANGE_NAME, "black");