一个生产者,多个消费者,每个消费者获取的信息完全相同,发布订阅模式下,生产者和交换机打交道,由交换机将信息发送给对应绑定的队列
导入依赖
com.rabbitmq
amqp-client
5.7.3
首先创建工具类,用以生成连接,避免重复书写此段代码
public class RabbitMQUtil {
private static ConnectionFactory factory = new ConnectionFactory();
static{
//用户名
factory.setUsername("hello");
//密码
factory.setPassword("123456");
//虚拟机
factory.setVirtualHost("/myhost");
//IP地址,运行rabbitmq组件的主机ip地址
factory.setHost("192.168.31.14");
//端口
factory.setPort(5672);
}
public static Connection getConnection(){
Connection connection = null;
try {
connection = factory.newConnection();
return connection;
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return null;
}
}
生产者
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//获取连接
Connection connection = RabbitMQUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
/**
* 声明交换机
* 参数1:交换机名称
* 参数2:交换机类型:fanout、direct、topic、headers
*/
channel.exchangeDeclare("pubsub_exchange", BuiltinExchangeType.FANOUT);
//在发布订阅模式下,生产者不再和队列打交道,而是直接将消息发送到交换机
//参数1:是交换机的名称
//参数2:是路由key,暂时不用
//参数3:是额外的参数
//参数4:要发布的消息
channel.basicPublish("pubsub_exchange","",null,"发送信息".getBytes());
channel.close();
connection.close();
}
}
消费者
public class Customer1{
public static void main(String[] args) throws IOException {
//获取连接
Connection connection = RabbitMQUtil.getConnection();
//创建通道
final Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare("qn_queue",false,false,false,null);
//将对列与交换机进行绑定
//参数3是 路由key
channel.queueBind("qn_queue","pubsub_exchange","");
//消费
channel.basicConsume("qn_queue",false,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("customer1收到消息:"+new String(body));
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
}
}
public class Customer2{
public static void main(String[] args) throws IOException {
Connection connection = RabbitMQUtil.getConnection();
final Channel channel = connection.createChannel();
//声明一个对列
channel.queueDeclare("xc_queue",false,false,false,null);
//将队列与交换机进行绑定
//参数1:队列的名称
//参数2:交换机的名称
//参数3:是路由key ,暂时不用
channel.queueBind("xc_queue","pubsub_exchange","");
//签收消息:false表示手动编程的方式签收
channel.basicConsume("xc_queue",false,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("customer2接收的消息:"+new String(body));
//签收
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
}
}
注:生产者发送消息至交换机,交换机按照key分配给相应队列,这里测试时若先运行消费者端需要确保交换机被创建,故需要在消费者端声明交换机,此时生产者端不需要声明交换机,当然,如果先运行生产者端,则需要在生产者端先声明交换机,此时消费者端可以不用声明交换机,总之躯体情况具体分析,灵活运用,当然为了省事,可以一律声明。