一.Pub/Sub 订阅模式
1.模式说明
2.生产者代码
交换机用的是广播:所以路由键为" "
package com.cd;
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 Producer_PubSub {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——简单模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
//创建交换机
/*
*exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
* 参数:
* 1.exchange:交换机名称
* 2.type:交换机类型:有String,也有枚举:四个类型
* DIRECT("direct"), 定向:把消息交给符合指定routing key的队列
FANOUT("fanout"), 广播:发送消息到每一个与之绑定的队列
TOPIC("topic"), 通配符的方式:把消息交给符合routing pattern(路由模式)的队列
HEADERS("headers"); 参数匹配的方式
* 3.是否持久化 如果持久化的话,会被写到Erlang自带的数据库里面去:即mq重启后还在
* 4.是否自动删除 当没有Consumer时,自动删除掉
* 5.internal:内部使用,一般为false
* 6.arguments:参数:配置的一些怎么删队列的一些参数
* */
String exchangeName = "test_fanout";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT,true,false,false,null);
//创建队列
String queue1Name = "test_fanout_queue1";
String queue2Name = "test_fanout_queue2";
channel.queueDeclare(queue1Name,true,false,false,null);
channel.queueDeclare(queue2Name,true,false,false,null);
//绑定队列和交换机
/*
* queueBind(String queue, String exchange, String routingKey)
* 参数:
* 1.queue:队列名称
* 2.exchange:交换机名称
* 3.routingKey:路由键,绑定规则
* 如果交换机的类型为fanout,默认为""
* */
channel.queueBind(queue1Name,exchangeName,"");
channel.queueBind(queue2Name,exchangeName,"");
//发送消息
String body = "日志信息:张三调用了fingAll方法...日志级别为:info...";
channel.basicPublish(exchangeName,"",null,body.getBytes());
//释放资源
channel.close();
connection.close();
}
}
2个消费者
package com.cd;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_PubSub2 {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——简单模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
String queue1Name = "test_fanout_queue1";
String queue2Name = "test_fanout_queue2";
//接收消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 参数:
* 1.queue:队列名称
* 2.autoAck:是否自动确认:消费者消息一旦收到,自动给mq说这个消息收到了
* 3.callback:回调对象:监听这一些方法,自动的执行这些方法
* */
Consumer 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("consumerTag: "+consumerTag);
// System.out.println("Exchange: "+envelope.getExchange());
// System.out.println("RoutingKey: "+envelope.getRoutingKey());
// System.out.println("properties: "+properties);
System.out.println("body: "+new String(body));
System.out.println("将日志信息保存数据库...");
}
};
channel.basicConsume(queue2Name,true,consumer);
//关闭资源? 不关:因为消费者就相当于一个监听程序一直要监听有没有消息发过来
}
}
package com.cd;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_PubSub1 {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——简单模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
String queue1Name = "test_fanout_queue1";
String queue2Name = "test_fanout_queue2";
//接收消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 参数:
* 1.queue:队列名称
* 2.autoAck:是否自动确认:消费者消息一旦收到,自动给mq说这个消息收到了
* 3.callback:回调对象:监听这一些方法,自动的执行这些方法
* */
Consumer 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("consumerTag: "+consumerTag);
// System.out.println("Exchange: "+envelope.getExchange());
// System.out.println("RoutingKey: "+envelope.getRoutingKey());
// System.out.println("properties: "+properties);
System.out.println("body: "+new String(body));
System.out.println("将日志信息打印到控制台...");
}
};
channel.basicConsume(queue1Name,true,consumer);
//关闭资源? 不关:因为消费者就相当于一个监听程序一直要监听有没有消息发过来
}
}
二.Routing 路由模式
1.模式说明
即P->X发送消息需要一个RoutingKey. X(交换机)->队列 也需要一个RoutingKey
交换机类型为定向:DIRECT
2.生产者代码
package com.cd;
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 Producer_Routing {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——路由模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
//创建交换机
/*
*exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
* 参数:
* 1.exchange:交换机名称
* 2.type:交换机类型:有String,也有枚举:四个类型
* DIRECT("direct"), 定向:把消息交给符合指定routing key的队列
FANOUT("fanout"), 广播:发送消息到每一个与之绑定的队列
TOPIC("topic"), 通配符的方式:把消息交给符合routing pattern(路由模式)的队列
HEADERS("headers"); 参数匹配的方式
* 3.是否持久化 如果持久化的话,会被写到Erlang自带的数据库里面去:即mq重启后还在
* 4.是否自动删除 当没有Consumer时,自动删除掉
* 5.internal:内部使用,一般为false
* 6.arguments:参数:配置的一些怎么删队列的一些参数
* */
String exchangeName = "test_direct";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT,true,false,false,null);
//创建队列
String queue1Name = "test_direct_queue1";
String queue2Name = "test_direct_queue2";
channel.queueDeclare(queue1Name,true,false,false,null);
channel.queueDeclare(queue2Name,true,false,false,null);
//绑定队列和交换机
/*
* queueBind(String queue, String exchange, String routingKey)
* 参数:
* 1.queue:队列名称
* 2.exchange:交换机名称
* 3.routingKey:路由键,绑定规则
* 如果交换机的类型为fanout,默认为""
* */
//队列一绑定error
channel.queueBind(queue1Name,exchangeName,"error");
//队列二绑定info error warning
channel.queueBind(queue2Name,exchangeName,"info");
channel.queueBind(queue2Name,exchangeName,"error");
channel.queueBind(queue2Name,exchangeName,"warning");
//发送消息
String body = "日志信息:张三调用了fingAll方法...日志级别为:info...";
channel.basicPublish(exchangeName,"info",null,body.getBytes());
//释放资源
channel.close();
connection.close();
}
}
3.消费者代码
package com.cd; import com.rabbitmq.client.*; import java.io.IOException; import java.util.concurrent.TimeoutException; public class Consumer_Routing1 { public static void main(String[] args) throws IOException, TimeoutException { //六模式——简单模式 //创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置参数 factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost factory.setPort(5672); //设置端口 默认值:5672 factory.setVirtualHost("/"); //虚拟机 默认值:/ factory.setUsername("guest"); //用户名 默认值:guest factory.setPassword("guest"); //密码 默认值:guest //创建连接 Connection connection = factory.newConnection(); //创建Channel Channel channel = connection.createChannel(); String queue1Name = "test_direct_queue1"; String queue2Name = "test_direct_queue2"; //接收消息 /* * basicConsume(String queue, boolean autoAck, Consumer callback) * 参数: * 1.queue:队列名称 * 2.autoAck:是否自动确认:消费者消息一旦收到,自动给mq说这个消息收到了 * 3.callback:回调对象:监听这一些方法,自动的执行这些方法 * */ Consumer 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("consumerTag: "+consumerTag); // System.out.println("Exchange: "+envelope.getExchange()); // System.out.println("RoutingKey: "+envelope.getRoutingKey()); // System.out.println("properties: "+properties); System.out.println("body: "+new String(body)); System.out.println("将日志信息打印到控制台..."); } }; channel.basicConsume(queue2Name,true,consumer); //关闭资源? 不关:因为消费者就相当于一个监听程序一直要监听有没有消息发过来 } }
package com.cd;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_Routing2 {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——简单模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
String queue1Name = "test_direct_queue1";
String queue2Name = "test_direct_queue2";
//接收消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 参数:
* 1.queue:队列名称
* 2.autoAck:是否自动确认:消费者消息一旦收到,自动给mq说这个消息收到了
* 3.callback:回调对象:监听这一些方法,自动的执行这些方法
* */
Consumer 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("consumerTag: "+consumerTag);
// System.out.println("Exchange: "+envelope.getExchange());
// System.out.println("RoutingKey: "+envelope.getRoutingKey());
// System.out.println("properties: "+properties);
System.out.println("body: "+new String(body));
System.out.println("将日志信息保存数据库...");
}
};
channel.basicConsume(queue1Name,true,consumer);
//关闭资源? 不关:因为消费者就相当于一个监听程序一直要监听有没有消息发过来
}
}
三.Topics 通配符模式
1.模式说明
解释:*.orange.*: 其中*表示匹配一个单词 P->X(交换机)发送消息给了一个路由键:a.orange.c就能够匹配 *.orange.*这个交换机与队列绑定时的RoutingKey.
#:表示匹配零个或多个单词
交换机类型为:Topic
2.生产者代码
package com.cd;
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 Producer_Topics {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——通配符模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
//创建交换机
/*
*exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
* 参数:
* 1.exchange:交换机名称
* 2.type:交换机类型:有String,也有枚举:四个类型
* DIRECT("direct"), 定向:把消息交给符合指定routing key的队列
FANOUT("fanout"), 广播:发送消息到每一个与之绑定的队列
TOPIC("topic"), 通配符的方式:把消息交给符合routing pattern(路由模式)的队列
HEADERS("headers"); 参数匹配的方式
* 3.是否持久化 如果持久化的话,会被写到Erlang自带的数据库里面去:即mq重启后还在
* 4.是否自动删除 当没有Consumer时,自动删除掉
* 5.internal:内部使用,一般为false
* 6.arguments:参数:配置的一些怎么删队列的一些参数
* */
String exchangeName = "test_topic";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,false,false,null);
//创建队列
String queue1Name = "test_topic_queue1";
String queue2Name = "test_topic_queue2";
channel.queueDeclare(queue1Name,true,false,false,null);
channel.queueDeclare(queue2Name,true,false,false,null);
//绑定队列和交换机
/*
* queueBind(String queue, String exchange, String routingKey)
* 参数:
* 1.queue:队列名称
* 2.exchange:交换机名称
* 3.routingKey:路由键,绑定规则
* 如果交换机的类型为fanout,默认为""
* */
//队列一: routing key 系统名称.日志级别
//需求: 所有error级别的日志存入数据库,所有order系统的日志存入数据库
channel.queueBind(queue1Name,exchangeName,"#.error");
channel.queueBind(queue1Name,exchangeName,"order.*");
//队列二
channel.queueBind(queue2Name,exchangeName,"#.*");
//发送消息
String body = "日志信息:张三调用了fingAll方法...日志级别为:info...";
channel.basicPublish(exchangeName,"info",null,body.getBytes());
//释放资源
channel.close();
connection.close();
}
}
3.消费者
package com.cd;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_Topic1 {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——通配符模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
String queue1Name = "test_topic_queue1";
String queue2Name = "test_topic_queue2";
//接收消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 参数:
* 1.queue:队列名称
* 2.autoAck:是否自动确认:消费者消息一旦收到,自动给mq说这个消息收到了
* 3.callback:回调对象:监听这一些方法,自动的执行这些方法
* */
Consumer 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("consumerTag: "+consumerTag);
// System.out.println("Exchange: "+envelope.getExchange());
// System.out.println("RoutingKey: "+envelope.getRoutingKey());
// System.out.println("properties: "+properties);
System.out.println("body: "+new String(body));
System.out.println("将日志信息打印到控制台...");
}
};
channel.basicConsume(queue2Name,true,consumer);
//关闭资源? 不关:因为消费者就相当于一个监听程序一直要监听有没有消息发过来
}
}
package com.cd;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer_Topic2 {
public static void main(String[] args) throws IOException, TimeoutException {
//六模式——通配符模式
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("10.10.26.129");//虚拟机上的ip:Rabbitmq我的安装在虚拟机上 默认值:localhost
factory.setPort(5672); //设置端口 默认值:5672
factory.setVirtualHost("/"); //虚拟机 默认值:/
factory.setUsername("guest"); //用户名 默认值:guest
factory.setPassword("guest"); //密码 默认值:guest
//创建连接
Connection connection = factory.newConnection();
//创建Channel
Channel channel = connection.createChannel();
String queue1Name = "test_topic_queue1";
String queue2Name = "test_topic_queue2";
//接收消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 参数:
* 1.queue:队列名称
* 2.autoAck:是否自动确认:消费者消息一旦收到,自动给mq说这个消息收到了
* 3.callback:回调对象:监听这一些方法,自动的执行这些方法
* */
Consumer 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("consumerTag: "+consumerTag);
// System.out.println("Exchange: "+envelope.getExchange());
// System.out.println("RoutingKey: "+envelope.getRoutingKey());
// System.out.println("properties: "+properties);
System.out.println("body: "+new String(body));
System.out.println("将日志信息存到数据库...");
}
};
channel.basicConsume(queue1Name,true,consumer);
//关闭资源? 不关:因为消费者就相当于一个监听程序一直要监听有没有消息发过来
}
}
4.小结