RabbitMQ本质上是队列,遵循FIFO(先进先出),在队列中存放的是message,是一种跨进程的通信机制,用于上下游传递消息。
1、拉取rabbitmq镜像
docker pull rabbitmq:3.8.3-management
2、启动rabbitmq镜像
docker run --name rabbitmq -d -p 15672:15672 -p 5672:5672 rabbit:3.8.3-management
3、设置rabbitmq开机自启
docker update rabbitmq --restart=always
4、访问rabbitmq。打开浏览器输入 IP:端口,默认用户是guest,密码也是guest,也可以在启动容器的时候增加参数
-e RABBITMQ_DEFAULT_USER=admin -e RABIT_DEFAULT_PASS=123456
原理:
RabbitMQ是一个消息代理,它接收并转发消息,相当于了一个邮政信箱,一个邮局和一个信件载体。它接收、存储和转发数据的二进制blob消息。
三大核心:
1、producer(生产者):生产只意味着发送,发送消息的程序就是生产者。
2、queue(队列):队列是RabbitMQ中邮箱的名称,尽管消息流经RabbitMQ和你的应用程序,但它只能存储在队列中,队列仅受主机内存和磁盘限制的约束,它本质上是一个大型的消息缓冲区,许多生产者可以发送到一个队列的消息,许多使用者可以尝试从一个队列接收数据,这就是我们表示队列的方式。
3、consumer(消费者):消费与接受的含义相似,使用者是一个主要等待接受消息的程序。
public class FanoutExchangeTest {
public static final String EXCHANGE_NAME = "helloFanoutExchange";
ConnectionFactory factory;
@Before
public void init() {
factory = new ConnectionFactory();
factory.setHost("8.146.204.254");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
}
@Test
public void producer() throws Exception {
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 声明交换机类型
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
// 声明队列
String queueName = channel.queueDeclare().getQueue();
// 绑定交换机与队列
channel.queueBind(queueName, EXCHANGE_NAME, "");
System.out.println("等待接收信息,把接收的消息打印在荧幕上。。。");
DeliverCallback deliverCallback = (consumerTag, message) -> {
System.out.println("消费者1的消息:" + new String(message.getBody()));
};
CancelCallback cancelCallback = consumerTag -> {
System.out.println("消费消息被中断");
};
// 接受消息
channel.basicConsume(queueName, true, deliverCallback, cancelCallback);
Thread.sleep(1000000);
}
}
public class DirectExchangeTest {
public static final String EXCHANGE_NAME = "helloDirectExchange";
ConnectionFactory factory;
@Before
public void init() {
factory = new ConnectionFactory();
factory.setHost("8.146.204.254");
}
@Test
public void producer() throws Exception {
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 创建交换机
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
String message = "";
String sendType = "";
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
sendType = "orange";
System.out.println("我是orange级的消息类型:" + i);
} else {
sendType = "black";
System.out.println("我是black级的消息类型:" + i);
}
System.out.println("[send]:" + message + "," + sendType);
channel.basicPublish(EXCHANGE_NAME, sendType, null, message.getBytes(StandardCharsets.UTF_8));
Thread.sleep(5 * i);
}
}
@Test
public void consumer1() throws Exception {
String queueName = "Q1";
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(queueName, false, false, false, null);
channel.queueBind(queueName, EXCHANGE_NAME, "orange");
System.out.println("等待接收消息,把接收的消息打印到屏幕上.......");
DeliverCallback deliverCallback = (consumerTag, message) -> {
System.out.println("消费者1消费的消息:" + new String(message.getBody()));
};
CancelCallback cancelCallback = consumerTag -> {
System.out.println("消费消息被中断");
};
channel.basicConsume(queueName,true,deliverCallback,cancelCallback);
Thread.sleep(1000000);
}
@Test
public void consumer2() throws Exception {
String queueName = "Q2";
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(queueName, false, false, false, null);
channel.queueBind(queueName, EXCHANGE_NAME, "black");
channel.queueBind(queueName, EXCHANGE_NAME, "green");
System.out.println("等待接收消息,把接收的消息打印到屏幕上.......");
DeliverCallback deliverCallback = (consumerTag, message) -> {
System.out.println("消费者2消费的消息:" + new String(message.getBody()));
};
CancelCallback cancelCallback = consumerTag -> {
System.out.println("消费消息被中断");
};
channel.basicConsume(queueName,true,deliverCallback,cancelCallback);
Thread.sleep(1000000);
}
}