1.模型
解读:该模式下生产者向交换机发送消息要带路由key,队列绑定交换机时也要声明路由key,这样交换机会把消息发往对应路由key的队列。
2.实例:
生产者
import java.io.IOException; import java.util.concurrent.TimeoutException; import com.demo.rabbitMQ.util.ConnectionUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; { private static final String EXCHANGE_NAME="test_exchange_direct"; public static void main(String[] args) throws IOException, TimeoutException { //获取连接 Connection connection = ConnectionUtils.getConnection(); //创建通道 Channel channel = connection.createChannel(); //声明交换机 channel.exchangeDeclare(EXCHANGE_NAME, "direct"); String msg="info direct"; String routingKey="info"; channel.basicPublish(EXCHANGE_NAME, routingKey,null, msg.getBytes()); System.out.println("消息已发送:"+msg); channel.close(); connection.close(); } } |
消费者1:
import java.io.IOException; import java.util.concurrent.TimeoutException; import com.demo.rabbitMQ.util.ConnectionUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.Envelope; import com.rabbitmq.client.AMQP.BasicProperties; public class Consumer1 { //队列 private static final String QUEUE_NAME="test_queues_direct2"; //交换机 private static final String EXCHANGE_NAME="test_exchange_direct"; public static void main(String[] args) throws IOException, TimeoutException { //获取连接 Connection connection = ConnectionUtils.getConnection(); //创建对列 Channel channel = connection.createChannel(); //声明队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); //绑定路由和交换机 channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "error"); channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "info"); channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "warning"); //保证一次只分发一个 channel.basicQos(1); //定义一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { //一旦有消息就会触发该方法 @Override public void handleDelivery(String consumerTag,Envelope envelope,BasicProperties basicProperties,byte[] body) throws IOException { String msg=new String(body,"utf-8"); System.out.println("消费者1===========:"+msg); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println("=================consumer1 over================"); //手动应答 channel.basicAck(envelope.getDeliveryTag(), false); } } }; //关闭自动应答 boolean autoAck=false; //监听队列 channel.basicConsume(QUEUE_NAME, autoAck, defaultConsumer); } } |
消费者2:
import java.io.IOException; import java.util.concurrent.TimeoutException; import com.demo.rabbitMQ.util.ConnectionUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.Envelope; import com.rabbitmq.client.AMQP.BasicProperties; public class Consumer2 { //队列 private static final String QUEUE_NAME="test_queues_direct1"; //交换机 private static final String EXCHANGE_NAME="test_exchange_direct"; public static void main(String[] args) throws IOException, TimeoutException { //获取连接 Connection connection = ConnectionUtils.getConnection(); //创建对列 Channel channel = connection.createChannel(); //声明队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); //绑定路由和交换机 channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "error"); //保证一次只分发一个 channel.basicQos(1); //定义一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { //一旦有消息就会触发该方法 @Override public void handleDelivery(String consumerTag,Envelope envelope,BasicProperties basicProperties,byte[] body) throws IOException { String msg=new String(body,"utf-8"); System.out.println("消费者2===========:"+msg); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }finally { System.out.println("=================consumer2 over================"); //手动应答 channel.basicAck(envelope.getDeliveryTag(), false); } } }; //关闭自动应答 boolean autoAck=false; //监听队列 channel.basicConsume(QUEUE_NAME, autoAck, defaultConsumer); } } |