1、发送消息
使用Channel的basicPublish方法,向RabbitMQ发送消息。
(1) void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;
// 连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 配置连接参数
factory.setHost("192.168.0.1");
factory.setPort(5672);
factory.setUsername("rabbitstudy");
factory.setPassword("123456");
Connection connection = factory.newConnection();// 创建连接
Channel channel = connection.createChannel();// 创建信道,在信道上传递消息
channel.exchangeDeclare(EXCHANGE_NAME, "direct");// 创建交换器
channel.queueDeclare(QUEUE_NAME, false,false,false,null);// 创建队列
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTINT_KEY);// 通过路由键绑定交换器与队列
// 发送消息给RabbitMQ
channel.basicPublish(EXCHANGE_NAME, ROUTINT_KEY,
MessageProperties.PERSISTENT_TEXT_PLAIN, "Hello World".getBytes());
// 关闭资源
channel.close();
connection.close();
(2) void basicPublish(String exchange, String routingKey, boolean mandatory, BasicProperties props, byte[] body) throws IOException;
(3) void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body) throws IOException;
其中一些参数具体作用:
exchange:交换器名称
routingKey:路由键值
props:消息的一些基本属性
body:消息体
mandatory与immediate:当消息无法路由到队列或者路由到的队列上没有消费者时,如何处理?
2、消费消息
消费消息有两种模式:推(basicConsume())/拉(basicGet())。
(一)推模式:
- String basicConsume(String queue, Consumer callback) throws IOException;
channel.basicConsume(QUEUE_NAME, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("消费者接收到:" + new String(body)); // 告诉服务器,我收到消息了 channel.basicAck(envelope.getDeliveryTag(), false); } });
- String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;
- String basicConsume(String queue, boolean autoAck, Map<String, Object> arguments, Consumer callback) throws IOException;
- String basicConsume(String queue, boolean autoAck, String consumerTag, Consumer callback) throws IOException;
- String basicConsume(String queue, boolean autoAck, String consumerTag, boolean noLocal, boolean exclusive, Map<String, Object> arguments, Consumer callback) throws IOException;
其中一些参数具体作用:
- autoAck:是否自动确认,false表示不自动确认;
- consumerTag:消费者标签,用来区分多个消费者;
- noLocal:设置为true则表示不能将同一个Connection中生产者的消息传送给这个Connection中的消费者;
- exclusive:设置是否排他;
- arguments:设置消费的其他参数;
- callback:设置消息的回调函数。用来处理RabbitMQ推送过来的消息
(二)拉模式
GetResponse basicGet(String queue, bollean autoAck) throws IOException;
Address[] addresses = new Address[] {new Address("192.168.0.1", 5672)};
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("rabbitstudy");
factory.setPassword("123456");
Connection connection = factory.newConnection(addresses);
Channel channel = connection.createChannel();
GetResponse basicGet = channel.basicGet(QUEUE_NAME, true);
System.out.println(new String(basicGet.getBody()));
channel.close();
connection.close();
Channel.basicGet()方法没有其他重载方法。其中queue代表队列名称,如果设置autoAck为false,那么同样需要调用cannel.basicAck来确认消息已被接收成功。
注意:
- channel.basicConsume()将Channel设置为接收模式,直到取消队列的订阅为止。在接收模式期间,RabbitMQ会不断地推送消息给消费者,当然推送消息的个数还是会受到Basic.Qos的限制。
- 拉模式每次只能获取到一条消息,如果有消息的话,会主动的去拉一条消息。它拉消息是一条一条的拉的,一次只能拉一条。basicGet不能用于for循环中代替basicConsume,因为这样性能非常的差。
(三)确认与拒绝
1、确认消息
basicAck(long deliveryTag, boolean multiple) throws IOException
deliveryTag:消息ID;
multiple:false,确认消费了该条消息;true,确认消费了该信道上这条消息之前的所有消息
GetResponse basicGet = channel.basicGet(QUEUE_NAME, false);
System.out.println(new String(basicGet.getBody()));
channel.basicAck(basicGet.getEnvelope().getDeliveryTag(), false);// 确认单条消息
2、拒绝消息
//拒绝单条消息
void basicReject(long deliveryTag, boolean requeue) throws IOException;
public static void main(String[] args) throws Exception {
Address[] addresses = new Address[] {new Address("192.168.0.1", 5672)};
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("rabbitstudy");
factory.setPassword("123456");
Connection connection = factory.newConnection(addresses);
Channel channel = connection.createChannel();
GetResponse basicGet = channel.basicGet(QUEUE_NAME, true);
System.out.println(new String(basicGet.getBody()));
// 拒绝单条消息
channel.basicReject(basicGet.getEnvelope().getDeliveryTag(), true);
channel.close();
connection.close();
}
//拒绝多条消息
void basicNack(long deliveryTag, boolean multiple, boolean requeue) throws IOException;
参数的意义:
multiple:false,表示拒绝编号为deliveryTag这条消息;
multiple:true,表示拒绝deliveryTag编号之前所有未被当前消费者确认的消息;
requeue:用于设置是否再次将该消息放入队列中重新发送给消费者。
注意:channel.basicReject() 或channel.basicNack()中的requeue设置为false,可以启用“死信队列”功能。