学习笔记:
生产者
import com.rabbitmq.client.BuiltinExchangeType; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import java.io.IOException; import java.util.concurrent.TimeoutException; public class Publish { //队列名称 private static final String QUEUE_INFORM_EMAIL="queue_inform_email"; private static final String QUEUE_INFORM_SMS="queue_inform_sms"; private static final String EXCHANGE_FANOUT_INFORM="exchange_fanout_inform"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory=new ConnectionFactory(); connectionFactory.setHost("127.0.0.1"); connectionFactory.setPort(5672); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); //设置虚拟机,一个mq服务可以设置多个虚拟机,每个虚拟机就相当于一个mq connectionFactory.setVirtualHost("/"); Connection connection=null; Channel channel=null; try { //建立连接 connection=connectionFactory.newConnection(); //创建会话通道,生产者和mq服务所有通信都在channel中完成 channel = connection.createChannel(); //声明队列 /** * String queue,boolean durable,boolean exclusive,boolean autoDelete ,Map<String,Object> arguments</String,Object> * 参数明细 * 1.队列名称 * 2:是否持久化,如果持久化,mq重启队列还在 * 3: exclusive :是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列自动删除。如果将此参数设置true可用于临时u队列的创建 * 4:autoDelete:自动删除,队列不再使用时是否删除队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除) * 5:arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间 */ channel.queueDeclare(QUEUE_INFORM_SMS,true,false,false,null); channel.queueDeclare(QUEUE_INFORM_EMAIL,true,false,false,null); //声明一个交换机 /** * String exchange,String type; * exchange :接交换机的名称 * type: 交换机的类型 * fanout: 对应的rabbitmq的工作模式是 publis/subscribe * direct: 对应的Routing工作模式 * topic: 对应于Topics工作模式 * headers: 对应于headers工作模式 */ channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT); //进行交换机和队列进行绑定 /** * String queue,String exchange,String routingKey * 1 queue:队列名称 * 2:exchange :交换机的名称 * 3:routingKey: 路由key,作用是交换机根据路由key的值将消息转发到指定的队列中去 * 在发布订阅模式中定义为空字符串 */ channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_FANOUT_INFORM,""); channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_FANOUT_INFORM,""); /** * String exchange,String routingKey,BasicProperties,byte[] body * 1: exchange:交换机,如果不指定将使用mq的默认交换机 * 2:routingKey: 路由key,交换机根据路由key来将消息转发到指定的队列,如果使用默认交换机,ruotingkey设置为默认的队列名称 * 3:basicProperties: 消息的属性 * 4:body:消息内容 */ String msg="hello 你好!"; //发送多条消息 for(int i=0;i<6;i++){ //发送消息 channel.basicPublish(EXCHANGE_FANOUT_INFORM,"",null,msg.getBytes()); System.out.println("send to many users " +i); } } catch (IOException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); }finally { //关闭连接 //先关闭通道 通道在连接中 // channel.close(); // connection.close(); } } }
消费者1
import com.rabbitmq.client.*; import java.io.IOException; import java.util.concurrent.TimeoutException; public class Consumer_subscribe_sms { //队列名称 private static final String QUEUE_INFORM_SMS="queue_inform_sms"; private static final String EXCHANGE_FANOUT_INFORM="exchange_fanout_inform"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory=new ConnectionFactory(); connectionFactory.setHost("127.0.0.1"); connectionFactory.setPort(5672); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); //设置虚拟机,一个mq服务可以设置多个虚拟机,每个虚拟机就相当于一个mq connectionFactory.setVirtualHost("/"); Connection connection=null; Channel channel=null; //建立连接 connection=connectionFactory.newConnection(); //创建会话通道,生产者和mq服务所有通信都在channel中完成 channel = connection.createChannel(); //声明队列 /** * String queue,boolean durable,boolean exclusive,boolean autoDelete ,Map<String,Object> arguments</String,Object> * 参数明细 * 1.队列名称 * 2:是否持久化,如果持久化,mq重启队列还在 * 3: exclusive :是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列自动删除。如果将此参数设置true可用于临时u队列的创建 * 4:autoDelete:自动删除,队列不再使用时是否删除队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除) * 5:arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间 */ channel.queueDeclare(QUEUE_INFORM_SMS,true,false,false,null); //声明一个交换机 /** * String exchange,String type; * exchange :接交换机的名称 * type: 交换机的类型 * fanout: 对应的rabbitmq的工作模式是 publis/subscribe * direct: 对应的Routing工作模式 * topic: 对应于Topics工作模式 * headers: 对应于headers工作模式 */ channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT); //进行交换机和队列进行绑定 /** * String queue,String exchange,String routingKey * 1 queue:队列名称 * 2:exchange :交换机的名称 * 3:routingKey: 路由key,作用是交换机根据路由key的值将消息转发到指定的队列中去 * 在发布订阅模式中定义为空字符串 */ channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_FANOUT_INFORM,""); //实现消费者方法 DefaultConsumer defaultConsumer = new DefaultConsumer(channel){ //到接受消息后,此方法会被调用 /** * * @param consumerTag 消费者标签 用来标识消费者的,在监听队列时设置channel.basicConsume * @param envelope 信封 通过envelope * @param properties 消息属性 * @param body 消息内容 * @throws IOException */ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { //交换机 String exchange=envelope.getExchange(); //消息id.mq在channel中用来标识消息的id,可用于确消已接收 long deliveryTag = envelope.getDeliveryTag(); //消息内容 String s = new String(body, "utf-8"); System.out.println("receive message:"+s); } }; /** * String queue,boolean autoAck,Consumer callback * 1:queue 队列名称 * 2:autoAck 自动回复,当消费者接收到消息后要告诉mq消息一接收,如果将此参数设置为true表示会自动回复 * 如果设置为 false 要通过编程实现回复 * 3:callbacl 消费方法,当消费者接受到消息要执行的方法 */ //监听队列 channel.basicConsume(QUEUE_INFORM_SMS,true,defaultConsumer); } }
消费者2
import com.rabbitmq.client.*; import java.io.IOException; import java.util.concurrent.TimeoutException; public class Consumer_subscribe_email { //队列名称 private static final String QUEUE_INFORM_EMAIL="queue_inform_email"; private static final String EXCHANGE_FANOUT_INFORM="exchange_fanout_inform"; public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory connectionFactory=new ConnectionFactory(); connectionFactory.setHost("127.0.0.1"); connectionFactory.setPort(5672); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); //设置虚拟机,一个mq服务可以设置多个虚拟机,每个虚拟机就相当于一个mq connectionFactory.setVirtualHost("/"); Connection connection=null; Channel channel=null; //建立连接 connection=connectionFactory.newConnection(); //创建会话通道,生产者和mq服务所有通信都在channel中完成 channel = connection.createChannel(); //声明队列 /** * String queue,boolean durable,boolean exclusive,boolean autoDelete ,Map<String,Object> arguments</String,Object> * 参数明细 * 1.队列名称 * 2:是否持久化,如果持久化,mq重启队列还在 * 3: exclusive :是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列自动删除。如果将此参数设置true可用于临时u队列的创建 * 4:autoDelete:自动删除,队列不再使用时是否删除队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除) * 5:arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间 */ channel.queueDeclare(QUEUE_INFORM_EMAIL,true,false,false,null); //声明一个交换机 /** * String exchange,String type; * exchange :接交换机的名称 * type: 交换机的类型 * fanout: 对应的rabbitmq的工作模式是 publis/subscribe * direct: 对应的Routing工作模式 * topic: 对应于Topics工作模式 * headers: 对应于headers工作模式 */ channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT); //进行交换机和队列进行绑定 /** * String queue,String exchange,String routingKey * 1 queue:队列名称 * 2:exchange :交换机的名称 * 3:routingKey: 路由key,作用是交换机根据路由key的值将消息转发到指定的队列中去 * 在发布订阅模式中定义为空字符串 */ channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_FANOUT_INFORM,""); //实现消费者方法 DefaultConsumer defaultConsumer = new DefaultConsumer(channel){ //到接受消息后,此方法会被调用 /** * * @param consumerTag 消费者标签 用来标识消费者的,在监听队列时设置channel.basicConsume * @param envelope 信封 通过envelope * @param properties 消息属性 * @param body 消息内容 * @throws IOException */ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { //交换机 String exchange=envelope.getExchange(); //消息id.mq在channel中用来标识消息的id,可用于确消已接收 long deliveryTag = envelope.getDeliveryTag(); //消息内容 String s = new String(body, "utf-8"); System.out.println("receive message:"+s); } }; /** * String queue,boolean autoAck,Consumer callback * 1:queue 队列名称 * 2:autoAck 自动回复,当消费者接收到消息后要告诉mq消息一接收,如果将此参数设置为true表示会自动回复 * 如果设置为 false 要通过编程实现回复 * 3:callbacl 消费方法,当消费者接受到消息要执行的方法 */ //监听队列 channel.basicConsume(QUEUE_INFORM_EMAIL,true,defaultConsumer); } }