安装 rabbitmq:
brew install rabbitmq
创建远程访问用户:
进入rabbitmq 目录下的 plugins 目录执行添加用户,添加用户权限,设置用户角色操作
添加用户
./rabbitmqctl add_user admin admin
添加用户权限
./rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
设置用户角色
./rabbitmqctl set_user_tags admin administrator
1 安装erlang
brew install erlang
2 安装插件
-
第一步: 下载插件
-
第二步:把下载好的插件解压到rabbitmq 目录下的 plugins 目录
/usr/local/Cellar/rabbitmq/3.7.3/plugins
-
第三步:启动插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
3 rabbitmq 页面新建Exchange时看到 type 多出一项 x-delayed-message 表示安装成功
rabbitmq插件实现延时队列代码:
application.yml:
rabbitmq:
host: 192.168.1.237
port: 5672
username: admin
password: admin
publisher-confirms: true #消息发送到交换机确认机制,是否确认回调
publisher-returns: true #消息失败返回,比如路由不到队列时触发回调
listener:
simple:
acknowledge-mode: manual #设置消费着的手动确认 ack
RabbitConfig:
@Configuration
public class RabbitConfig {
private static final Logger log = LoggerFactory.getLogger(RabbitConfig.class);
@Resource
private RabbitTemplate rabbitTemplate;
@Bean
public AmqpTemplate amqpTemplate() {
Logger log = LoggerFactory.getLogger(RabbitTemplate.class);
// 消息发送失败返回到队列中,yml需要配置 publisher-returns: true
rabbitTemplate.setMandatory(true);
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
log.info("ReturnCallback回调消息:{} 发送失败, 应答码:{} 原因:{} 交换机: {} 路由键: {}", message, replyCode, replyText, exchange, routingKey);
});
// 消息确认,yml需要配置 publisher-confirms: true
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
if (ack) {
log.info("消息发送到exchange成功,id: {}", correlationData);
} else {
log.info("消息发送到exchange失败,原因: {}", cause);
}
});
return rabbitTemplate;
}
/**
* 自定义的交换机类型
* @return
*/
@Bean
CustomExchange delayedExchange() {
Map<String,Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
return new CustomExchange("delayedExchange","x-delayed-message",true,false,args);
}
/**
* 创建一个队列
* @return
*/
@Bean
public Queue delayedQueue() {
return new Queue("delayedQueue",true);
}
/**
* 绑定队列到自定义交换机
* @return
*/
@Bean
public Binding bindingNotify() {
return BindingBuilder.bind(delayedQueue()).to(delayedExchange()).with("delayedQueue").noargs();
}
}
生产者:
@Component
public class DelayedSender {
@Autowired
private AmqpTemplate rabbitTemplate;
public void send(String msg, long time) {
System.out.println("DelayedSender 发送时间: " + LocalDateTime.now() + " msg内容:" + msg);
MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setHeader("x-delay", time);
return message;
}
};
this.rabbitTemplate.convertAndSend("delayedExchange", "delayedQueue", msg, messagePostProcessor);
}
}
消费者:
@Component
public class DelayedReceiver {
@RabbitListener(queues = "delayedQueue")
@RabbitHandler
public void process(String msg, Message message, Channel channel) throws IOException {
System.out.println("DelayedReceiver 接受时间: " + LocalDateTime.now() + " msg内容:" + msg);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
}
}
测试:
@RestController
@RequestMapping("/rabbit")
public class RabbitTest {
@Autowired
private DelayedSender delayedSender;
@GetMapping("/delayedTest")
public String delayedTest() {
System.out.println("----延时任务启动成功----");
delayedSender.send("20秒延时任务-----", 1000*20);
delayedSender.send("10秒延时任务-----", 1000*10);
delayedSender.send("5秒延时任务-----", 1000*5);
return "延时任务启动成功: "+ new Date();
}
}
基础配置信息:
rabbitmq:
host: ${mq.host}
port: ${mq.port}
username: ${mq.user}
password: ${mq.passwd}
publisher-confirms: true #消息发送到交换机确认机制,是否确认回调
publisher-returns: true #消息失败返回,比如路由不到队列时触发回调
listener:
simple:
acknowledge-mode: manual #设置消费者的手动确认 ack
配置全局手动 ack+设置多线程消费者
// 1 在RabbitmqConfig.java添加配置
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory, MessageConverter messageConverter) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);//设置手动 ack
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(messageConverter);
factory.setConcurrentConsumers(10); //设置线程数
factory.setMaxConcurrentConsumers(10); //最大线程数
configurer.configure(factory,connectionFactory);
return factory;
}
@Bean
public MessageConverter messageConverter() {
return new ContentTypeDelegatingMessageConverter(new Jackson2JsonMessageConverter());
}
@Bean
public RabbitAdmin rabbitTemplate(ConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
//2 在@RabbitListener注解中指定容器工厂
@RabbitListener(queues = {"监听队列名"},containerFactory = "customContainerFactory")