基本特性规范
|
|-1.spring(建议4.2以上,mq支持注解)+RabbitMQ1.6.6
|
|-2.默认配置的连接是5个,当rabbit服务器重启后,会自动重连
|
|-3.所有队列、路由默认是持久化的,当rabbit服务器重启后,会自动恢复创建
|
|-4.优先级队列级别设置建议为10(权重越大表示优先执行)
|
|-5.所有接收器设置其ack为手动响应,且在listener使用后必须回写,防止队列阻塞
|
|-6.所有数据发送采用字符串,且存储数据信息尽量小于10K(已配置使用默认的json转换器)
|
|-7.队列、路由在创建后,属性不可更改,如有需要,需申请运维协助(建议使用新的队列,旧的队列数据处理完后可以删除)
命名规范
|
|-容器名称.[队列特点or路由特点].使用的平台名称.作用
|
|-容器名称:queue、exchange
|
|-队列特点:非持久化标记(undurable)、延时队列(delay)、优先级队列(priority)
|
|-路由特点:direct、topic、fanout、headers
|
|-使用的平台名称:xiangshang、xiangqian
|
|-作用:干什么的
|
|-eg|--queue.xiangshang.message
| |--queue.delay.xiangshang.message
| |--exchange.direct.xiangshang.common
| |--exchange.direct.xiangshang.common
Spring整合RabbitMQ
|
|-加依赖|--<dependency>
| |-- <groupId>org.springframework.boot</groupId>
| |-- <artifactId>spring-boot-starter-amqp</artifactId>
| |--</dependency>
|
|-加配置|--rabbitmq-config.properties|---#RabbitMQ服务器参数设置
| | |---rmq.addresses=10.200.0.150:5672
| | |---rmq.username=root
| | |---rmq.password=123456
| | |---#MQ或路由配置
| | |---rmq.queue.xiangshang.test=queue.xiangshang.test
| | |---rmq.queue.undurable.xiangshang.test=queue.undurable.xiangshang.test
| | |---rmq.queue.priority.xiangshang.test=queue.priority.xiangshang.test
| | |---rmq.queue.delay.xiangshang.test=queue.delay.xiangshang.test
| | |---rmq.exchange.direct.xiangshang.test=exchange.direct.xiangshang.test
| | |---rmq.exchange.fanout.xiangshang.test=exchange.fanout.xiangshang.test
| | |---rmq.exchange.headers.xiangshang.test=exchange.headers.xiangshang.test
| |
| |--rabbitConfiguration.xml:略
|
|-代码编写
生产者代码示例
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.BeansException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DirectQueueTest {
private static String RMQ_QUEUE_XIANGSHANG_TEST = "queue.xiangshang.test";
private static String RMQ_QUEUE_UNDURABLE_XIANGSHANG_TEST = "queue.undurable.xiangshang.test";
private static String RMQ_QUEUE_PRIORITY_XIANGSHANG_TEST = "queue.priority.xiangshang.test";
private static String RMQ_QUEUE_DELAY_XIANGSHANG_TEST = "queue.delay.xiangshang.test";
private static String RMQ_EXCHANGE_DIRECT_XIANGSHANG_TEST = "exchange.direct.xiangshang.test";
private static String RMQ_EXCHANGE_FANOUT_XIANGSHANG_TEST = "exchange.fanout.xiangshang.test";
private static String RMQ_EXCHANGE_HEADERS_XIANGSHANG_TEST = "exchange.headers.xiangshang.test";
private static ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("rabbitConfiguration.xml");
private static AmqpTemplate rabbitTemplate = context.getBean("rabbitTemplate", AmqpTemplate.class);
public static void main(String[] args) {
demo1();
}
/**
* 对队列发送消息
*/
public static void demo1() {
String sendMsg = "队列消息." + String.valueOf(new Random().nextDouble());
MessageProperties mp1 = new MessageProperties()setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
Message msg1 = new Message(sendMsg.getBytes(), mp1);
rabbitTemplate.convertAndSend(RMQ_QUEUE_XIANGSHANG_TEST, msg1);
rabbitTemplate.convertAndSend(RMQ_EXCHANGE_DIRECT_XIANGSHANG_TEST, RMQ_QUEUE_XIANGSHANG_TEST, msg1);// 效果同上
rabbitTemplate.convertAndSend(RMQ_QUEUE_UNDURABLE_XIANGSHANG_TEST, msg1);
rabbitTemplate.convertAndSend(RMQ_QUEUE_XIANGSHANG_TEST, sendMsg);
rabbitTemplate.convertAndSend(RMQ_QUEUE_UNDURABLE_XIANGSHANG_TEST, sendMsg);
}
/**
* 发送广播:此时广播下所有队列均可接收到数据
*/
public static void demo2() {
String sendMsg = "广播消息." + String.valueOf(new Random().nextDouble());
rabbitTemplate.convertAndSend(RMQ_EXCHANGE_FANOUT_XIANGSHANG_TEST, RMQ_QUEUE_UNDURABLE_XIANGSHANG_TEST, sendMsg);
}
/**
* 优先级队列
*/
public static void demo3() {
for (int i = 0; i < 10; i++) {
int priority = new Random().nextInt(10);
String sendMsg = "队列消息." + String.valueOf(new Random().nextDouble()) + "[" + priority + "]";
System.out.println(sendMsg);
Message msg = new Message(sendMsg.getBytes(), new MessageProperties().setPriority(priority));
rabbitTemplate.convertAndSend(RMQ_QUEUE_PRIORITY_XIANGSHANG_TEST, msg);
}
}
/**
* 延迟消息队列
* 1.当前rabbitMQ没有自动排序的队列,它所支持的队列是无序的
* 2.队列遵守先进先出,因此它执行的顺序是确认第一条数据过期时间为基准,如果第二条过期时间在第一条之前,第二条不会在第一条之前执行
* eg:队列数据过期时间依次为 30s后、10秒后、20秒后,此时必须等到30秒后队列才出数据
* 3.因此,延迟消息功能需要规范以下几点:
* 3.1 每个延迟业务申明独有的路由、队列,并标注业务使用说明
* 3.2 延迟队列最好设置消息的最大过期时间,到期后要转发的路由和队列
* 3.3 header采用全部匹配,路由中需匹配与生产端header相同
*/
public static void demo4() {
for (int i = 0; i < 3; i++) {
int delay = (i + 1) * 2 * 1000;
String sendMsg = "队列消息." + String.valueOf(new Random().nextDouble()) + "[" + delay + "]";
System.out.println(sendMsg);
MessageProperties mp = new MessageProperties();
mp.setExpiration(String.valueOf(delay));// 设置消息过期时间
mp.setHeader("operator", "xsjf");
mp.setHeader("sex", "male");
Message msg = new Message(sendMsg.getBytes(), mp);
rabbitTemplate.convertAndSend(RMQ_EXCHANGE_HEADERS_XIANGSHANG_TEST, "", msg);
}
}
}
消费者代码示例
package com.xiangshang.mq.listener;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import com.rabbitmq.client.Channel;
public class DirectListener implements ChannelAwareMessageListener {
/* (non-Javadoc)
* @see org.springframework.amqp.core.MessageListener#onMessage(org.springframework.amqp.core.Message)
*/
@Override
public void onMessage(Message message, Channel channel) throws Exception {
System.out.println("DirectListener 获取的消息内容:" + new String(message.getBody()));
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);// 返回成功ack
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);// 返回失败ack,并且数据重新入队
Thread.currentThread().sleep(1000);
}
}