1.概述
1.1 官方:
https://www.rabbitmq.com/tutorials/tutorial-one-java.html
RabbitMQ是消息代理:它接受并转发消息。您可以将其视为邮局:将要发布的邮件放在邮箱中时,可以确保Mailperson先生或女士最终将邮件传递给收件人。以此类推,RabbitMQ是一个邮箱,一个邮局和一个邮递员。
RabbitMQ与邮局之间的主要区别在于,它不处理纸张,而是接收,存储和转发数据消息的二进制斑点。
1.2 RabbitMQ和消息传递通常使用一些术语。
-
生产仅意味着发送。发送消息的程序是生产者:
-
队列是RabbitMQ内部的邮箱的名称。尽管消息流经RabbitMQ和您的应用程序,但它们只能存储在队列中。甲队列仅由主机的存储器&磁盘限制约束,它本质上是一个大的消息缓冲器。许多生产者可以发送进入一个队列的消息,许多消费者可以尝试从一个队列接收数据。这就是我们表示队列的方式:
-
消费与接收具有相似的含义。一个消费者是一个程序,主要是等待接收信息:
请注意,生产者,消费者和经纪人不必位于同一主机上。实际上,在大多数应用程序中它们不是。一个应用程序既可以是生产者,也可以是消费者。
2.代码示例
2.1 依赖:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.5.0</version>
</dependency>
2.2.连接工具类
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 创建连接工具类
*/
public class ConnectionUtil {
public static Connection getConnection() throws Exception{
//定义一个连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置服务地址
factory.setHost("192.168.236.128");
//Overview -- Listening ports
//amqp 5672
factory.setPort(5672);
factory.setUsername("test");
factory.setPassword("test");
//VirtualHost(admin--Virtual Hosts)
factory.setVirtualHost("/test");
return factory.newConnection();
}
}
2.3.发送者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.shm.demo.util.ConnectionUtil;
/**
* 消息发送者
*/
public class Sender {
private final static String QUEUE = "testhello";//队列名称
public static void main(String[] args) throws Exception {
//1.获取连接
Connection connection = ConnectionUtil.getConnection();
//2.创建通道
Channel channel = connection.createChannel();
//3.声名队列
//参数1:队列的名称
//参数2:是否持久化队列,我们的队列模式是在内存中的,如果RabbitMQ重启会丢失,如果设置为true,则会保存在erlang自带的数据库中,重启后恢复
//参数3:是否排外,有两个作用,第一个当我们的连接关闭后是否自动删除队列;第二,是否私有当前队列,如果私有,其它通道不可访问
//参数4:是否自动删除
//参数5:一些其它参数
channel.queueDeclare(QUEUE,false,false,false,null);
//4.发送消息
String msg = "这是我发送的消息!";
channel.basicPublish("",QUEUE,null,msg.getBytes());
//5.关闭连接
channel.close();
connection.close();
}
}
2.4.消费者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.shm.demo.util.ConnectionUtil;
/**
* 消息消费者
*/
public class Recv {
private final static String QUEUE = "testhello";//队列名称
public static void main(String[] args) throws Exception {
//1.获取连接
Connection connection = ConnectionUtil.getConnection();
//2.创建通道
Channel channel = connection.createChannel();
//3.声名队列
//参数1:队列的名称
//参数2:是否持久化队列,我们的队列模式是在内存中的,如果RabbitMQ重启会丢失,如果设置为true,则会保存在erlang自带的数据库中,重启后恢复
//参数3:是否排外,有两个作用,第一个当我们的连接关闭后是否自动删除队列;第二,是否私有当前队列,如果私有,其它通道不可访问
//参数4:是否自动删除
//参数5:一些其它参数
channel.queueDeclare(QUEUE,false,false,false,null);
//定义消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE,true,consumer);//参数2是自动确认
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String msg = new String(delivery.getBody());
System.out.println(msg);
}
}
3. 不足:
耦合性高,生产者一一对应消费者(不支持多个消费者)