持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
1、创建连接(Connection),获取通道(Channel)
ConnectionFactory factory = new ConnectionFactory();
//设置主机地址
factory.setHost(HOST_NAME);
//设置端口
factory.setPort(HOST_PORT);
//设置用户名
factory.setUsername(USERNAME);
//设置密码
factory.setPassword(PASSWORD);
//设置镜像集群
factory.setVirtualHost(VIRTUAL_HOST);
//创建连接
Connection connection = factory.newConnection();
//创建通道
Chamnel channel = connection.createChannel();
2、声明queue队列
在客户端声明的队列,如果服务端没有,会自动在服务端创建。但是如果服务端有了这个队列,那么声明的队列属性必须和服务端队列属性一致才行。
Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
Map<String, Object> arguments) throws IOException;
参数说明:
| 参数名 | 类型 | 说明 |
|---|---|---|
queue | String | 队列名称 |
durable | boolean | true表示声明一个持久队列(队列在服务器重启后仍然存在) |
exclusive | boolean | true表示声明一个独占队列(仅限于当前连接使用) |
autoDelete | boolean | true表示声明一个自动删除队列(服务器将在不使用时删除) |
arguments | Map<String, Object> | 队列的一些其他属性 |
classic队列
注意:
arguments中x-queue-type默认值为classic,可以不用设置
//队列会在服务端自动创建。
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
quorum队列
注意:
arguments的x-queue-type参数值为quorumdurable参数必须是true,false会报错exclusice参数必须是false,true会报错
Map<String, Object> params = new HashMap<>();
params.put("x-queue-type", "quorum");
channel.queueDeclare(QUEUE_NAME, true, false, false, params);
Stream队列
注意:
arguments的x-queue-type参数值为streamdurable参数必须是true,false会报错exclusice参数必须是false,true会报错x-max-length-bytes表示日志文件的最大字节数,x-stream-max-segment-size-bytes表示每一个日志文件的最大大小,这两个是可选参数,通常为了防止stream的日志无限制累计,都会设置。
params.put("x-queue-type","stream");
// maximum stream size: 20 GB
params.put("x-max-length-bytes", 20_000_000_000L);
// size of segment files: 100 MB
params.put("x-stream-max-segment-size-bytes", 100_000_000);
channel.queueDeclare(QUEUE_NAME, true, false, false, params);
3、Producer根据应用场景发送消息到queue
void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;
参数说明:
| 参数名 | 类型 | 说明 |
|---|---|---|
exchange | String | 交换机 |
routingKey | String | 路由键 |
props | BasicProperties | 消息的其他属性-消息头等 |
body | byte[] | 消息正文 |
exchange是一个Producer与queue的中间交互机制。可以让消息按一定的规则发送到不同的queue ,不需要的话就传空字符串
4、Cousumer消费消息
定义消费者,消费消息进行处理,并向RabbitMQ进行消息确认。确认了之后就表明这个消息已经消费完了,否则RabbitMQ还会继续让别的消费者实例来处理。有两种消费模式。消费的时候,一般是启动一个一直挂起的线程来持续消费,因为消息是会不断的产生的。
被动消费模式
消费者等待服务器将消息推送(push)过来,然后再消费。
channel.basicConsume(String queue, boolean autoAck, Consumer callback);
参数说明:
| 参数名 | 类型 | 说明 |
|---|---|---|
queue | String | 队列名称 |
autoAck | Boolean | true表示自动确认,不需要写代码确认。flase则不自动确认,需要手动写代码确认,或者其他消费者确认。 |
callback | Consumer | 回调消费者消费的接口 |
主动消费模式
消费者主动去服务器将消息拉(pull)过来,然后再消费。
GetResponse response = channel.basicGet(QUEUE_NAME, boolean autoAck);
| 参数名 | 类型 | 说明 |
|---|---|---|
queue | String | 队列名称 |
autoAck | Boolean | true表示自动确认,不需要写代码确认。flase则不自动确认,需要手动写代码确认,或者其他消费者确认。 |
Stream队列消费
stream相对另外两种队列消费比较特殊,需要注意以下几点:
channel必须设置basicQos属性- 需要正确声明
Stream队列 - 消费时需要指定
offset
void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException;
| 参数名 | 类型 | 说明 |
|---|---|---|
prefetchSize | int | 预取大小服务器将传递的最大内容量(以八位字节为单位),如果不受限制,则为0。默认值:0 |
prefetchCount | int | 服务器一次请求将传递的最大邮件数,如果没有限制,则为0调用此方法时,该值必填。默认值:0 |
global | boolean | 是否将设置应用于整个频道,而不是每个消费者默认值:false,应用于本身(一个消费者)true:应用于整个频道 |
注意
- 要注意如果每个
Consumer一直未确认,会导致消息不停的被处理,不停的吞噬系统资源,最终造成宕机。 - 持续消费的过程中不要关闭
channel和connection连接
关闭资源
channel.close();
connection.close();