先介绍rabbmitmq的几个方法:

    1. // 声明一个队列 -// queue 队列名称
    2. // durable 为true时server重启队列不会消失 (是否持久化)
    3. // exclusive 队列是否是独占的,如果为true只能被一个connection使用,其他连接建立时会抛出异常
    4. // autoDelete 当没有任何消费者使用时,自动删除该队列
    5. channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    1. /*
    2. * 向server发布一条消息
    3. * 参数1:exchange名字,若为空则使用默认的exchange
    4. * 参数2:routing key
    5. * 参数3:其他的属性
    6. * 参数4:消息体
    7. * RabbitMQ默认有一个exchange,叫default exchange,它用一个空字符串表示,它是direct exchange类型,
    8. * 任何发往这个exchange的消息都会被路由到routing key的名字对应的队列上,如果没有对应的队列,则消息会被丢弃
    9. */
    10. channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
    1. // 同一时刻服务器只会发一条消息给消费者(能者多劳模式)
    2. channel.basicQos(1);
    1. /*消息消费完成确认
    2. * autoAck 是否自动确认 true自动确认 false手动确认
    3. * 模式1:自动确认 只要消息从队列中获取,无论消费者获取到消息后是否成功消息,都认为是消息已经成功消费。
    4. * 模式2:手动确认
    5. * 消费者从队列中获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,如果消费者一直没有反馈,那么 该消息将一直处于不可用状态。
    6. * 如果选用自动确认,在消费者拿走消息执行过程中出现宕机时,消息可能就会丢失!!
    7. */
    8. channel.basicConsume(TASK_QUEUE_NAME, false, consumer);

    当手动确认时,一定要在消息处理完成后,确认提交,加上如下代码:

    1. // 消息处理完成,手动确认提交
    2. // deliveryTag 该消息的index
    3. // multiple:是否批量 true:将一次性ack所有小于deliveryTag的消息。
    4. channel.basicAck(envelope.getDeliveryTag(), false);
    1. /*
    2. * 使用fanout类型创建的交换器
    3. * exchange:交换机名称
    4. * type:交换机类型(direct/topic/fanout)
    5. */
    6. channel.exchangeDeclare(EXCHANGE_NAME, ConfigKey.EX_FANOUT);
    1. /*
    2. * 获取到一个临时队列名称。
    3. * channel.queueDeclare():创建一个非持久化、独立、自动删除的队列名称
    4. * 此队列是临时的,随机的,一旦我们断开消费者,队列会立即被删除
    5. * 随机队列名,如amq.gen-jzty20brgko-hjmujj0wlg
    6. */
    7. String queueName = channel.queueDeclare().getQueue();
    1. /*
    2. * 将队列跟交换器进行绑定
    3. * queue:队列名称
    4. * exchange:交换机名称
    5. * routingKey:队列跟交换机绑定的键值
    6. */
    7. channel.queueBind(queueName, EXCHANGE_NAME, "black");