RabbitMQ-工作模式
第一种:简单模式
一、生产者
public static void main(String[] args) throws IOException, TimeoutException {
//1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2.设置参数
connectionFactory.setHost("127.0.0.1");//ip,默认localhost
connectionFactory.setPort(5672);//端口,默认5672
connectionFactory.setVirtualHost("/");//虚拟机,默认/
connectionFactory.setUsername("guest");//用户名,默认guest
connectionFactory.setPassword("guest");//密码,默认guest
//3.创建连接
Connection connection = connectionFactory.newConnection();
//4.创建channel
Channel channel = connection.createChannel();
//5.创建队列
/**
* queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
* 参数:1、queue:队列名称
* 2、durable:是否持久化
* 3、exclusive:是否独占,只有一个消费者监听队列,当connection关闭时,是否删除队列
* 4、autoDelete:是否自动删除,当没有consumer时,自动删除掉
* 5、arguments:相关参数,一般为null
*/
channel.queueDeclare("hello_world",true,false,false,null);
//6.发送消息
/**
* basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
* 参数:1、exchange:交换机名称
* 2、routingKey:路由键,绑定规则,如果交换机类型为Fanout,设置为空
* 3、props:配置信息
* 4、body:发送消息数据
*/
String body="hello rabbitmq...";
channel.basicPublish("","hello_world",null,body.getBytes());
//7.释放资源
channel.close();
connection.close();
}
二、消费者
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置参数
connectionFactory.setHost("127.0.0.1");//ip,默认localhost
connectionFactory.setPort(5672);//端口,默认5672
connectionFactory.setVirtualHost("/");//虚拟机,默认/
connectionFactory.setUsername("guest");//用户名,默认guest
connectionFactory.setPassword("guest");//密码,默认guest
//创建连接
Connection connection = connectionFactory.newConnection();
//创建channel
Channel channel = connection.createChannel();
//接收消息
Consumer consumer=new DefaultConsumer(channel){
/**
* 回调方法,收到消息自动执行
* @param consumerTag 标识
* @param envelope 获取交换机,路由key等信息
* @param properties 配置信息
* @param body 获取的消息
* @throws IOException
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("consumerTag:"+consumerTag);
System.out.println("envelope:"+envelope);
System.out.println("properties:"+properties);
System.out.println("body:"+new String(body));
}
};
/**
* 参数: 1、队列名称
* 2、是否自动确认
* 3、回调对象
*/
channel.basicConsume("hello_world",true,consumer);
}
三、测试结果
第二种:Work Queues工作队列模式
与简单模式相比,多了一个或一些消费端,多个消费端共同消费一个队列中的消息。对于任务过重或任务较多情况使用工作队列模式可以提高处理效率。例如:短信服务部署等。
第三种:Pub/Sub订阅模式,Fanout:广播模式,将消息交给所有绑定到交换机的队列。
在订阅模式中,多了Exchange角色,且过程稍有变化。
Exchange:交换机(X)。接收生产者发送的消息,根绝Exchange的类型,将消息递交给某个特别队列、所有队列或者将消息丢弃。常见类型有Fanout、Direct、Topic。
交换机只负责转发消息,不具备存储消息能力,如果没有任何队列与Exchange绑定或者没有符合路有规则的队列,那么消息将丢失!
生产者:
public static void main(String[] args) throws IOException, TimeoutException {
//1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2.设置参数
connectionFactory.setHost("127.0.0.1");//ip,默认localhost
connectionFactory.setPort(5672);//端口,默认5672
connectionFactory.setVirtualHost("/");//虚拟机,默认/
connectionFactory.setUsername("guest");//用户名,默认guest
connectionFactory.setPassword("guest");//密码,默认guest
//3.创建连接
Connection connection = connectionFactory.newConnection();
//4.创建channel
Channel channel = connection.createChannel();
//5.创建交换机
String exchangeName="test_fanout";
/**
* exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
* 参数:1、exchange:交换机名称
* 2、type:交换机类型
* DIRECT("direct"),
* FANOUT("fanout"),
* TOPIC("topic"),
* HEADERS("headers");
* 3、durable:是否持久化
* 4、autoDelete:是否自动删除
* 5、internal:内部使用,一般为false
* 6、arguments:参数
*/
channel.exchangeDeclare(exchangeName,BuiltinExchangeType.FANOUT,true,false,false,null);
//6.创建队列
String queueName1="hello_PubSub_Fanout1";
String queueName2="hello_PubSub_Fanout2";
/**
* queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
* 参数:1、queue:队列名称
* 2、durable:是否持久化
* 3、exclusive:是否独占,只有一个消费者监听队列,当connection关闭时,是否删除队列
* 4、autoDelete:是否自动删除,当没有consumer时,自动删除掉
* 5、arguments:相关参数,一般为null
*/
channel.queueDeclare(queueName1,true,false,false,null);
channel.queueDeclare(queueName2,true,false,false,null);
//7.绑定队列和交换机
/**
* queueBind(String queue, String exchange, String routingKey)
* 参数:1、queue:队列名称
* 2、exchange:交换机名称
* 3、routingKey:路由键,绑定规则,如果交换机类型为Fanout,设置为空
*/
channel.queueBind(queueName1,exchangeName,"");
channel.queueBind(queueName2,exchangeName,"");
//8.发送消息
/**
* basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
* 参数:1、exchange:交换机名称
* 2、routingKey:路由键,绑定规则,如果交换机类型为Fanout,设置为空
* 3、props:配置信息
* 4、body:发送消息数据
*/
String body="Hello PubSub_Fanout...";
channel.basicPublish(exchangeName,"",null,body.getBytes());
//9.释放资源
channel.close();
connection.close();
}
第四种 Routing路由模式,Direct:定向模式,将消息交给符合指定routing key的队列。
与Fanout大致一样,不同的地方在于交换机类型为Direct,绑定队列与交换机,发送消息时需指定routingKey。
channel.queueBind(queueName1,exchangeName,"routingKey");
channel.basicPublish(exchangeName,"routingKey",null,body.getBytes());
第五种 Topics:通配符模式,将消息交给符合routing pattern的队列。
匹配规则:
绑定键binding key也必须是这种形式。以特定路由键发送的消息将会发送到所有绑定键与之匹配的队列中。但绑定键有两种特殊的情况:
①*(星号)仅代表一个单词
②#(井号)代表任意个单词
示例:
以上图为例:
*.orange.* : 匹配以 任意一个单词字符开头中间包含 .orange. 以任意一个单词字符结尾 的字符串。比如 a.orange.b, sdfsd.orange.fdsfsdf 等(注意是一个单词)。
lay.# :只要一lay.开头的都匹配,他可以匹配lay.a, lay.a.b, lay.b.c等。