Rabbitmq基础知识
文章目录
黑马
看到第26集
mq的基本概念
mq的优势和劣势
应用解耦
异步提速
消峰填谷
消峰填谷
mq的劣势
常见的mq的产品
RabbitMq简介
JMS
安装
进入到rabbitmq的sbin目录,双击rabbitmq-server.bat,如果出现如下页面则代表启动成功
进入管理控制台
在浏览器地址栏中输入:http://localhost:15672,看到如下页面则代表启动成功
初始化:用户名和密码均为guest
简单队列的代码演示
provider
结合下面这张图写代码
// 1.创建连接工厂
ConnectionFactory factory=new ConnectionFactory();
// 2.设置参数
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("hjx");
factory.setPassword("123456");
// 3.创建连接
Connection connection =factory.newConnection();
// 4.创建channel
Channel channel=connection.createChannel();
// 5.创建队列
/*
durable:持久的
exclusive:1.该队列是否只能有一个消费者对其进行监听 2.当连接关闭时是否删除队列
autoDelete:是否自动删除(当没有消费者时,是否自动删除)
queueDeclare(String queue, boolean durable, boolean exclusive
, boolean autoDelete, Map<String, Object> arguments)
*/
// 如果没有hjx_quene的队列则会创建该队列,否则不会进行创建
channel.queueDeclare("hjx_queue",true,false,false,null);
// 6.发送消息
/*
1.exchange:交换机名称 (简单模式下使用默认的交换机,即设置为空字符串即可。
2.routingKey:路由键,只要routingKey和队列名称一样,该消息就会发送到该队列中
3.props:配置信息
4.发送的内容
basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
*/
String message="hello world,欢迎跟着黑马大神一起学习rabbitmq";
channel.basicPublish("","hjx_quene",null,message.getBytes());
// 释放资源
channel.close();
connection.close();
consumer
// 1.创建连接工厂
ConnectionFactory factory=new ConnectionFactory();
// 2.设置参数
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("hjx");
factory.setPassword("123456");
// 3.创建连接
Connection connection =factory.newConnection();
// 4.创建channel
/*
1.quene:队列名称
2.autoAck:是否确认(消费者收到消息了后自动给队列回复收到了)
3.callback:回调函数
basicConsume(String queue, boolean autoAck, Consumer callback)
*/
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.getExchange());
System.out.println("properties:"+properties);
System.out.println("body:"+new String(body));
}
};
channel.basicConsume("hjx_queue",true,consumer);
// 注意:消费者不要关闭资源,如果资源被关闭了,它就无法对队列中的消息进行监听了
}
常见的几种消息策略
交换机类型
type:交换机类型
* DIRECT("direct"):定向
* FANOUT("fanout") 扇形(也就是广播,发送到每个队列)
* TOPIC("topic"), 通配符的方式
* HEADERS("headers"); 通过参数匹配 (很少用)
工作模式
这里为了测试,需要创建2个consumer,然后启动consumer和provider。当consumer监听到有消息时就会将对应的消息打印出来。代码如下:
provider
public void sendMs() throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory=new ConnectionFactory();
// 2.设置参数
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("hjx");
factory.setPassword("123456");
// 3.创建连接
Connection connection =factory.newConnection();
// 4.创建channel
Channel channel=connection.createChannel();
// 5.创建队列
/*
durable:持久的
exclusive:1.该队列是否只能有一个消费者对其进行监听 2.当连接关闭时是否删除队列
autoDelete:是否自动删除(当没有消费者时,是否自动删除)
queueDeclare(String queue, boolean durable, boolean exclusive
, boolean autoDelete, Map<String, Object> arguments)
*/
// 如果没有hjx_quene的队列则会创建该队列,否则不会进行创建
channel.queueDeclare("hjx_queue",true,false,false,null);
// 6.发送消息
/*
1.exchange:交换机名称 (简单模式下使用默认的交换机,即设置为空字符串即可。
2.routingKey:路由键,只要routingKey和队列名称一样,该消息就会发送到该队列中
3.props:配置信息
4.发送的内容
basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
*/
// 这里为了测试方便,发送10条消息,因为时工作模式下的消息队列嘛
for(int i=0;i<10;i++){
String message="hello world,欢迎跟着黑马大神一起学习rabbitmq"+(i+1);
channel.basicPublish("","hjx_quene",null,message.getBytes());
}
// 释放资源
channel.close();
connection.close();
}
consumer
注意:这里的consumer,创建2个内容一模一样的就可以了。只要文件名不一样就行。
public void Test1() throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory=new ConnectionFactory();
// 2.设置参数
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("hjx");
factory.setPassword("123456");
// 3.创建连接
Connection connection =factory.newConnection();
// 4.创建channel
/*
1.quene:队列名称
2.autoAck:是否确认(消费者收到消息了后自动给队列回复收到了)
3.callback:回调函数
basicConsume(String queue, boolean autoAck, Consumer callback)
*/
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.getExchange());
System.out.println("properties:"+properties);*/
System.out.println("body:"+new String(body));
}
};
channel.basicConsume("hjx_queue",true,consumer);
// 注意:消费者不要关闭资源,如果资源被关闭了,它就无法对队列中的消息进行监听了
}
订阅模式
生产者
@Test
public void test() throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory=new ConnectionFactory();
// 2.设置参数
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("hjx");
factory.setPassword("123456");
// 3.创建连接
Connection connection =factory.newConnection();
// 4.创建channel
/*
1.quene:队列名称
2.autoAck:是否确认(消费者收到消息了后自动给队列回复收到了)
3.callback:回调函数
basicConsume(String queue, boolean autoAck, Consumer callback)
*/
/**
* exchange:交换机名称
* type:交换机类型
* DIRECT("direct"):定向
* FANOUT("fanout") 扇形(也就是广播,发送到每个队列)
* TOPIC("topic"), 通配符的方式
* HEADERS("headers"); 通过参数匹配
* durable:是否持久化
* autoDelete:是否自动删除
* internal:内部使用。一般为false
* arguments:参数
*
* exchangeDeclare(String exchange, BuiltinExchangeType type,
* boolean durable, boolean autoDelete, Map<String, Object> arguments)
*
*
*/
Channel channel=connection.createChannel();
String exchangeName="fanout_exchange";
channel.exchangeDeclare(exchangeName,BuiltinExchangeType.FANOUT,true,false,false,null);
String quueName1="quue_1";
String quueName2="quue_2";
/*
durable:持久的
exclusive:1.该队列是否只能有一个消费者对其进行监听 2.当连接关闭时是否删除队列
autoDelete:是否自动删除(当没有消费者时,是否自动删除)
queueDeclare(String queue, boolean durable, boolean exclusive
boolean autoDelete, Map<String, Object> arguments)
*/
// 声明队列,这里需要声明多个队列
channel.queueDeclare(quueName1,true,false,false,null);
channel.queueDeclare(quueName2,true,false,false,null);
// 绑定队列和交换机的关系
/**
* queue:队列的名称
* exchange:交换机的名称
* routingKey:路由key 如果交换机的类型为fanout,则routingKey=""
*
* queueBind(String queue, String exchange, String routingKey)
*/
channel.queueBind(quueName1,exchangeName,"");
channel.queueBind(quueName2,exchangeName,"");
// 发送消息
/*
1.exchange:交换机名称 (简单模式下使用默认的交换机,即设置为空字符串即可。
2.routingKey:路由键,只要routingKey和队列名称一样,该消息就会发送到该队列中
3.props:配置信息
4.发送的内容
basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
*/
String message="日志信息";
//这样交换机就会将消息转发给对应的2个队列
channel.basicPublish(exchangeName,"",null,message.getBytes());
// 释放资源
channel.close();
connection.close();
}
消费者
consumer1
@Test
public void test