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;
    }

 

posted @ 2023-08-24 17:29  XUMT111  阅读(9)  评论(0编辑  收藏  举报