rabbitMq
1, 建交换机 deal.direct 建queues deal.queue 绑定到交换机 2, 消息发送,只是发送到exchange,routingKey上 queue会绑定exchange,routingKey 3, exchange类型有: direct直连类型 queue需要一一逐个绑定routingKey test.aa test.bb topic主题类型 queue只需要模糊匹配绑定就行 test.# 4, direct交换机: 不同系统的消费者 绑定同一个exchange 队列queue不同 即可保证不同系统消费到同一消息
1,单个消费者,同一个队列,一个消息处理阻塞,后面排队处理 队列特性,逐个取消息
2,多个监听消费者(不同队列),多线程消费
@Service public class OrderItemServiceImpl { /** * https://blog.csdn.net/aetawt/article/details/128957417 * 监听方式获取消息 消息只消费一次,其他消费者消费后,本消费者不再消费 * @RabbitHandler:标注在方法上 * @RabbitListener: 标注在类、方法上 * 使用 @RabbitHandler + @RabbitListener 接受不同类型的消息 */ @RabbitListener(queues = {MqConstant.SEARCH_DATA_QUEUE}) public void recieveOrderMessage(Message message, Channel channel) throws IOException { System.out.println("收到了消息了--->" + message + " ====》内容:" + new String(message.getBody())); System.out.println("渠道数量:" + channel.getChannelNumber()); MessageProperties messageProperties = message.getMessageProperties(); System.out.println("消息处理完成---------------------------------"); //消息顺序,自增 long deliveryTag = messageProperties.getDeliveryTag(); System.out.println(deliveryTag); //回复,签收消息, fasle表示只签收当前消息,true签收所有 channel.basicAck(deliveryTag, false); } /** * RabbitTemplate 拉取的方式获取消息 */ @Component public class RabbitListenerConfig { @Autowired private RabbitTemplate rabbitTemplate; @PostConstruct public void receive(){ Thread thread = new Thread(){ public void run(){ while (true){ System.out.println("*************ready"); String message = (String)rabbitTemplate.receiveAndConvert(MqConstant.SEARCH_DATA_QUEUE,1000*2); System.out.println("*************receive:"+message); } } }; thread.start(); } @Autowired private RabbitTemplate rabbitTemplate; public void produce(String searchData) { log.info("消息生产:{}", searchData); rabbitTemplate.convertAndSend(MqConstant.xxx_DATA_EXCHANGE, MqConstant.xxx_DATA_QUEUE, searchData); } spring: rabbitmq: port: 5672 host: 192.168.xxx username: admin password: xxx virtual-host: sxxx publisher-confirm-type: correlated publisher-returns: true listener: direct: acknowledge-mode: manual simple: acknowledge-mode: manual retry: enabled: true <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> <version>2.6.8</version> </dependency>
// @RabbitHandler
// public void recieveOrderItemMessage(Message message, String orderItemEntity, Channel channel){
// System.out.println("收到了消息了--->" + message + " ====》内容:" + orderItemEntity);
// System.out.println("渠道数量:" + channel.getChannelNumber());
// }
自定义多线程处理 @RabbitListener(queues = {MqConstant.DEAL_TOBE_HANDLE})//,containerFactory = "batchQueueRabbitListenerContainerFactory" @Bean("batchQueueRabbitListenerContainerFactory") public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory){ SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setMessageConverter(new Jackson2JsonMessageConverter()); //确认方式,manual为手动ack. factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); //每次处理数据数量,提高并发量 //factory.setPrefetchCount(250); //设置线程数 //factory.setConcurrentConsumers(30); //最大线程数 //factory.setMaxConcurrentConsumers(50); /* setConnectionFactory:设置spring-amqp的ConnectionFactory。 */ factory.setConnectionFactory(connectionFactory); factory.setConcurrentConsumers(1); factory.setPrefetchCount(1); //factory.setDefaultRequeueRejected(true); //使用自定义线程池来启动消费者。 factory.setTaskExecutor(taskExecutor()); return factory; } @Bean("correctTaskExecutor") @Primary public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(100); // 设置最大线程数 executor.setMaxPoolSize(100); // 设置队列容量 executor.setQueueCapacity(0); // 设置线程活跃时间(秒) executor.setKeepAliveSeconds(300); // 设置默认线程名称 executor.setThreadNamePrefix("thread-rabbitmq"); // 设置拒绝策略rejection-policy:当pool已经达到max size的时候, 调用者执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 等待所有任务结束后再关闭线程池 executor.setWaitForTasksToCompleteOnShutdown(true); return executor; }