RabbitMQ使用
一、基于普通maven项目使用:
1)依赖:
<dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.5.1</version> </dependency>
2)列队模式:
1、简单列队:
2、work列队:
3、发布/订阅模式:
4、路由模式:
5、通配符模式:
二、简单模式:
简单模式,接受消息还未处理完成就自动回复,推送一百个消息后,两个消费者一人一半;
(1)生产者:
public class RabbitProvider { private static final String QUEUE_NAME = "simple_queue"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); // 声明列队;参数:列队名,是否持久,是否独占,是否自动删除,其它; channel.queueDeclare(QUEUE_NAME, true, false, false, null); // 发送消息; for (int i = 0; i < 100; i++) { String message = "hello motor"+i; channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); } System.out.println("消息发送成功!"); } }
(2)消费者:
public class RabbitConsumer1 { private static final String QUEUE_NAME = "simple_queue"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, true, false, false, null); //Lambda:官网这么写的; //处理消息 DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody(), "UTF-8"); System.out.println(" [x] Received '" + message + "'"); }; //监听对列 channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { }); } }
public class RabbitConsumer2 { private static final String QUEUE_NAME = "simple_queue"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, true, false, false, null); //非Lambda; //处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); } }; //监听队列 channel.basicConsume(QUEUE_NAME,true,consumer); } }
三、work模式:
work模式一次处理一个消息,完成后手动回复;实现能者多劳;
(1)生产者:
public class RabbitProvider { private static final String QUEUE_NAME = "work_queue"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); // 声明列队;参数:列队名,是否持久,是否独占,是否自动删除,其它; channel.queueDeclare(QUEUE_NAME, true, false, false, null); // 发送消息; for (int i = 0; i < 100; i++) { String message = "hello motor"+i; channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); } System.out.println("消息发送成功!"); } }
(2)消费:
设置消费者一次处理一个消除,且不自动回复,每次完成后都手动回复;
public class RabbitConsumer1 { private static final String QUEUE_NAME = "work_queue"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //一次只处理一个消息,避免消息堆积 channel.basicQos(1); channel.queueDeclare(QUEUE_NAME, true, false, false, null); //处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //手动回复 :处理完成 channel.basicAck(envelope.getDeliveryTag(),false); } }; //监听队列 // 不自动回复 channel.basicConsume(QUEUE_NAME,false,consumer); } }
public class RabbitConsumer2 { private static final String QUEUE_NAME = "work_queue"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); // 一次只处理一个消息,避免消息堆积 channel.basicQos(1); channel.queueDeclare(QUEUE_NAME, true, false, false, null); // 处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); //手动回复 :处理完成 channel.basicAck(envelope.getDeliveryTag(),false); } }; // 监听队列 // 不自动回复 channel.basicConsume(QUEUE_NAME,false,consumer); } }
四、发布订阅模式:
将消息发送给交换机fanout,交换机绑定多个队列,每个队列都能得到该消息。
(1)生产者:
生产者声明交换机,消费者绑定交换机;
public class RabbitProvider { private static final String QUEUE_NAME = "subscribe_queue"; private static final String EXCHANGE_NAME="fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME,"fanout"); // 发送消息; for (int i = 0; i < 100; i++) { String message = "hello motor"+i; //channel.basicPublish("",QUEUE_NAME,null,message.getBytes()); channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes()); } System.out.println("消息发送成功!"); } }
(2)消费者:
public class RabbitConsumer1 { private static final String QUEUE_NAME = "subscribe_queue1"; private static final String EXCHANGE_NAME="fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //声明队列 channel.queueDeclare(QUEUE_NAME,true,false,false,null); //将队列绑定在交换机上 channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ""); //处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); } }; //监听队列 channel.basicConsume(QUEUE_NAME,true,consumer); } }
public class RabbitConsumer2 { private static final String QUEUE_NAME = "subscribe_queue2"; private static final String EXCHANGE_NAME="fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //声明队列 channel.queueDeclare(QUEUE_NAME,true,false,false,null); //将队列绑定在交换机上 channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ""); //处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); } }; //监听队列 channel.basicConsume(QUEUE_NAME,true,consumer); } }
五、路由模式:
交换机类型为direct,发给指定的ROUTING_KEY;
(1)生产者:
public class RabbitProvider { private static final String EXCHANGE_NAME = "direct_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //声明交换机-- 改变交换机类型为“direct” channel.exchangeDeclare(EXCHANGE_NAME, "direct"); // 发送消息; channel.basicPublish(EXCHANGE_NAME, "routing_key1", null, "routing_key1_message".getBytes()); channel.basicPublish(EXCHANGE_NAME, "routing_key2", null, "routing_key2_message".getBytes()); System.out.println("消息发送成功!"); } }
(2)消费者:
public class RabbitConsumer { private static final String QUEUE_NAME = "direct_queue"; private static final String EXCHANGE_NAME="direct_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //声明队列 channel.queueDeclare(QUEUE_NAME,true,false,false,null); //将队列绑定在交换机上,并指明路由key; channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "routing_key1"); channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "routing_key2"); //处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); } }; //监听队列 channel.basicConsume(QUEUE_NAME,true,consumer); } }
六、通配符模式:
交换机类型为topic
(1)生产者:
public class RabbitProvider { private static final String EXCHANGE_NAME="topic_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //声明交换机-- 改变交换机类型为“topic” channel.exchangeDeclare(EXCHANGE_NAME, "topic"); //指明路由key channel.basicPublish(EXCHANGE_NAME,"product.add",null,"添加商品".getBytes()); channel.basicPublish(EXCHANGE_NAME,"product.del",null,"删除商品".getBytes()); channel.basicPublish(EXCHANGE_NAME,"product.del.other",null,"删除商品".getBytes()); System.out.println("发送消息成功"); } }
(2)消费者:
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"product.*");
收到:"product.add"/"product.del"
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"product.#");
收到:"product.add"/"product.del"/"product.del.other"
public class RabbitConsumer1 { private static final String QUEUE_NAME = "topic_queue1"; private static final String EXCHANGE_NAME="topic_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //声明队列 channel.queueDeclare(QUEUE_NAME,true,false,false,null); //将队列绑定在交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"product.*"); //处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); } }; //监听队列 channel.basicConsume(QUEUE_NAME,true,consumer); } }
public class RabbitConsumer2 { private static final String QUEUE_NAME = "topic_queue2"; private static final String EXCHANGE_NAME="topic_exchange"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.80.140"); connectionFactory.setPort(5672); //connectionFactory.setVirtualHost("qf"); connectionFactory.setUsername("rabbit"); connectionFactory.setPassword("123456"); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); //声明队列 channel.queueDeclare(QUEUE_NAME,true,false,false,null); //将队列绑定在交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"product.#"); //处理消息 Consumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body,"utf-8"); System.out.println("接收到的消息:"+message); } }; //监听队列 channel.basicConsume(QUEUE_NAME,true,consumer); } }