work模式下,还是使用默认交换机,一个队列。相当于信道与队列直连,但是消费者有多个, 多个消费者从同一个队列中取数据 consumer1:0,2,4,6 consumer2:1,3,5,7
注意:
- 在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争的关系。
- Work Queues 对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。例如:短信服务部署多个,只需要有一个节点成功发送即可。
生产者
public class Producer {
public static void main(String[] args) throws Exception{
//1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2. 设置参数
connectionFactory.setHost("localhost");//ip 默认值 localhost
connectionFactory.setPort(5672);//端口 默认值 5672
connectionFactory.setUsername("guest");//用户名 默认 guest
connectionFactory.setPassword("guest");//密码 默认值 guest
connectionFactory.setVirtualHost("/");//虚拟机 默认值
//3. 创建连接 Connection
Connection connection = connectionFactory.newConnection();
//4. 创建Channel
Channel channel = connection.createChannel();
//5. 创建队列Queue
channel.queueDeclare("work_queue", true, false, false, null);
for (int i = 0; i < 11; i++) {
String body = i + "hello rabbitmq~~~~~";
//6. 发送消息
channel.basicPublish("", "work_queue", null, body.getBytes());
}
//7.释放资源
channel.close();
connection.close();
}
}
此种模式下消费者有多个,其他消费者可以说除了类名不一样,其他都一样,因此在此就列举一个消费者。
消费者1
public class Consumer1 {
public static void main(String[] args) throws IOException, TimeoutException {
//1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2. 设置参数
connectionFactory.setHost("localhost");//ip 默认值 localhost
connectionFactory.setPort(5672);//端口 默认值 5672
connectionFactory.setUsername("guest");//用户名 默认 guest
connectionFactory.setPassword("guest");//密码 默认值 guest
connectionFactory.setVirtualHost("/");//虚拟机 默认值
//3. 创建连接 Connection
Connection connection = connectionFactory.newConnection();
//4. 创建Channel
Channel channel = connection.createChannel();
//5. 创建队列Queue
channel.queueDeclare("work_queue", true, false, false, null);
// 接收消息
DefaultConsumer consumer = new DefaultConsumer(channel){
/**
回调方法,当收到消息后,会自动执行该方法
1. consumerTag:标识
2. envelope:获取一些信息,交换机,路由key...
3. properties:配置信息
4. body:数据
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
// System.out.println("consumerTag1:"+consumerTag);
// System.out.println("Exchange1:"+envelope.getExchange());
// System.out.println("RoutingKey1:"+envelope.getRoutingKey());
// System.out.println("properties1:"+properties);
System.out.println("body1:"+new String(body));
}
};
/**
basicConsume(String queue, boolean autoAck, Consumer callback)
参数:
1. queue:队列名称
2. autoAck:是否自动确认 ,类似咱们发短信,发送成功会收到一个确认消息
3. callback:回调对象。我们这里使用回调对象打印有关信息,即调用handleDelivery方法
*/
// 消费者类似一个监听程序,主要是用来监听消息 autoAck:true表示自动签收所监听的队列中的信息
channel.basicConsume("work_queue", true, consumer);
}
}