Rabbitmq를 사용하여 지연 큐

구성 :

봄 : 
  rabbitmq : 
    주소 : 192.168 . 108.128 : 5672 
    연결 -timeout : 15000 
    이름 : 게스트 
    비밀번호 : 손님 
    게시자 -confirms : 진정한 
    게시자 -returns : 사실

의존 :

  <! - rabbitmq -> 
        <의존성> 
            <의 groupId> org.springframework.boot </의 groupId> 
            <artifactId를> 스프링 부팅 스타터 AMQP </ artifactId를> 
        </ 의존성>
<의존성> 
<의 groupId> org.projectlombok </의 groupId>
<artifactId를> 람 </ artifactId를>
</ 의존성>

구성 클래스 :

com.jds.rabbitmq 패키지; 

수입 com.jds.common.constant.QueueEnum; 
수입 org.springframework.amqp.core. * ; 
수입 org.springframework.context.annotation.Bean; 
수입 org.springframework.context.annotation.Configuration; 

수입 java.util.HashMap에; 
수입 java.util.Map; 

@Configuration 
공공  클래스 MQConfig { 
    
    공공  정적 최종 문자열 RBA_QUEUE = " rba.queue " ;
/ *     공공 정적 최종 문자열 QUEUE = "큐"; 
    공공 정적 최종 문자열 TOPIC_QUEUE1 = "topic.queue1"; 
    공공 정적 최종 문자열 TOPIC_QUEUE2 = "topic.queue2";
    공공 정적 최종 문자열 HEADER_QUEUE = "header.queue";
    공공 정적 최종 문자열 TOPIC_EXCHANGE = "topicExchage"; 
    공공 정적 최종 문자열 FANOUT_EXCHANGE = "fanoutxchage"; 
    공공 정적 최종 문자열 HEADERS_EXCHANGE = "headersExchage"; 
    
    * // * * 
     * 직접模式交换机교환 
     * * // * 
    @Bean 
    공개 큐 () {큐 
        새 대기열 반환 (QUEUE를, TRUE); 
    } 
    
    * // * * 
     * 주제模式交换机교환 
     * * // * 
    @Bean 
    공개 큐 topicQueue1 () { 
        새로운 큐 (TOPIC_QUEUE1, true)를 반환; 
    } 
    @Bean
    공개 큐 topicQueue2 () {  
        새로운 큐 (TOPIC_QUEUE2, true)를 반환; 
    }
    @Bean 
    공공 TopicExchange topicExchage는 () { 
        새로운 TopicExchange (TOPIC_EXCHANGE)을 반환; 
    } 
    @Bean 
    공공 바인딩 topicBinding1 () { 
        반환 BindingBuilder.bind (topicQueue1 ())에 (topicExchage () () "topic.key1")와 함께..; 
    } 
    @Bean 
    공공 바인딩 topicBinding2 () { 
        반환 BindingBuilder.bind (topicQueue2 ())에 (topicExchage () () "항목 #.")와 함께..; 
    } 
    * // * * 
     * 팬 아웃模式交换机교환 
     * * // * 
    @Bean 
    공공 FanoutExchange fanoutExchage () { 
        새로운 FanoutExchange (FANOUT_EXCHANGE)을 반환;
    }  
    @Bean 
    FanoutBinding1 바인딩 공공 () {
        리턴 BindingBuilder.bind (topicQueue1 () 내지 fanoutExchage ()).; 
    } 
    @Bean 
    FanoutBinding2 ()를 공개 바인딩 { 
        창 BindingBuilder.bind (topicQueue2 () 내지 fanoutExchage ()).; 
    } 
    * // * * 
     * 헤더模式交换机교환 
     * * // * 
    @Bean 
    공공 HeadersExchange headersExchage () { 
        새로운 HeadersExchange (HEADERS_EXCHANGE)을 반환; 
    } 
    @Bean 
    공개 큐 headerQueue1 () { 
        새로운 큐 (사실 HEADER_QUEUE)을 반환; 
    } 
    @Bean 
    공공 바인딩 headerBinding () { 
        지도 <문자열, 개체>지도 = 새의 HashMap <문자열, 개체> (); 
        map.put ( "HEADER1", "값 1"); 
        map.put ( "HEADER2", "값 2"); 
        .. BindingBuilder.bind 리턴 (headerQueue1 ())에 (headersExchage ()) whereAll ( 지도) .match (); 
    } * / 

    / * * 
     큐 * 주문 메시지가 실제 소비 결합 스위치 
     * / 
    @Bean 
    DirectExchange orderDirect () { 
        반환 (DirectExchange) ExchangeBuilder 
                .directExchange (QueueEnum.QUEUE_ORDER_CANCEL.getExchange ()) 
                . (내구성 true로는 ) 
                .build () 
    } 

    / * * 
     * 라인 지연 스위치 큐 결합 
     * / 
    @Bean 
    DirectExchange orderTtlDirect () {
         (DirectExchange) ExchangeBuilder
                .directExchange (QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange ()) 
                (.durable true로 ) 
                .build () 
    } 

    / * * 
     순서 큐의 실제 소비 * 
     * / 
    @Bean 
    공중 큐 OrderQueue는 () {
         돌아가  새로운 새로운 대기열 (QueueEnum.QUEUE_ORDER_CANCEL.getName ()) 
    } 

    / * * 
     * 라인 지연 큐 (데드 레터 큐) 
     * / 
    @Bean 
    공개 큐 orderTtlQueue () {
         QueueBuilder 
                .durable (QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName ()) 
                .withArgument (" X-데드 - 레터 교환 " , QueueEnum.QUEUE_ORDER_CANCEL.getExchange ()) // 전달로 인해 스위치 
                .withArgument ( " X-데드 - 레터 라우팅 - 키 " , QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey ()) / / 포워딩 라우팅 키 만료 
                .build () 
    } 

    / * * 
     * 순서 큐 전환 결합 
     * / 
    @Bean 
    결합 orderBinding (DirectExchange orderDirect 큐 OrderQueue) { 
        Return을 BindingBuilder 
                .bind (OrderQueue) 
                .TO (orderDirect ) 
                .with (QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey ()) 
    } 

    / ** 
     스위치에 결합 * 라인 지연 큐 
     * / 
    @Bean 
    바인딩 orderTtlBinding (DirectExchange orderTtlDirect 큐 orderTtlQueue) { 
        반환 BindingBuilder 
                .bind (orderTtlQueue) 
                .TO (orderTtlDirect) 
                .with (QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey ()); 
    } 

    
    
}

보낸 사람 :

com.jds.rabbitmq 패키지; 

/ * * 
 * @program : 빨간색 가방 - 활동 -> CancelOrderSender 
 * @description : 
 * @author : CXY 
 *의 @create : 2019년 12월 20일 17시 57분 
 * * / 

수입 com.jds.common.constant.QueueEnum; 
수입 org.slf4j.Logger; 
수입 org.slf4j.LoggerFactory; 
수입 org.springframework.amqp.AmqpException; 
수입 org.springframework.amqp.core.AmqpTemplate; 
수입 org.springframework.amqp.core.Message; 
수입 org.springframework.amqp.core.MessagePostProcessor; 
수입 org.springframework.beans.factory.annotation.Autowired; 
수입 org.springframework.stereotype.Component; 

/ * *  
 *取消订单消息的发出者
 * 
 * /
@Component 
공용  클래스 CancelOrderSender {
     개인  정적 로거 LOGGER = LoggerFactory.getLogger (CancelOrderSender. 클래스 ); 
    @Autowired 
    개인 AmqpTemplate amqpTemplate; 

    공공  무효 sendMessage 첨부 (긴 OrderID를 최종 delayTimes) {
         // 给延迟队列发送消息 
        amqpTemplate.convertAndSend (QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange (), QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey (), OrderID를, 새로운 위해 MessagePostProcessor () { 
            @Override 
            공공메시지 postProcessMessage (메시지 메시지) AmqpException을 던졌습니다 {
                 // 给消息设置延迟毫秒值
                message.getMessageProperties () setExpiration (한 String.valueOf (delayTimes를)).;
                반환 메시지를; 
            } 
        }); 
        LOGGER.info ( " 전송 지연 메시지 ORDERID : {} " , ORDERID); 
    } 
}

받는 사람 :

com.jds.rabbitmq 패키지; 

수입 org.slf4j.Logger; 
수입 org.slf4j.LoggerFactory; 
수입 org.springframework.amqp.rabbit.annotation.RabbitHandler; 
수입 org.springframework.amqp.rabbit.annotation.RabbitListener; 
수입 org.springframework.beans.factory.annotation.Autowired; 
수입 org.springframework.stereotype.Component; 

/ * * 
 *取消订单消息的处理
 * / 
@Component 
@RabbitListener (큐 = " mall.order.cancel " )
 공용  클래스 CancelOrderReceiver {
     개인  정적 로거 LOGGER = LoggerFactory.getLogger (CancelOrderReceiver. 클래스 );

    @RabbitHandler 
    공공  무효 핸들 (긴 ORDERID) { 
        System.err.println을 (에 System.currentTimeMillis ()); 
        LOGGER.info는 ( " 지연 메시지에 OrderID가 나타납니다 {} " , ORDERID을); 
        System.err.println을 (에 System.currentTimeMillis ()); 
        System.err.println을 (ORDERID); 
        체계. 밖으로 .println ( " 大傻逼222222 " ); 
    } 
}

전화를 클래스를 구성 :

com.jds.controller 패키지; 

수입 com.jds.rabbitmq.CancelOrderSender; 
수입 org.springframework.beans.factory.annotation.Autowired; 
수입 org.springframework.web.bind.annotation. * ; 

/ * * 
 * @program : 빨간색 가방 - 활동 -> DelayQController 
 * @description : 
 * @author : CXY 
 *의 @create : 2019년 12월 20일 18시 
 * * / 
@RestController 
공공  클래스 DelayQController { 
    @Autowired 
    CancelOrderSender cancelOrderSender; 
    @RequestMapping (값 = " / ID " , METHOD = RequestMethod.GET) 
    @ResponseBody
    공개  공극 상세히 () {
          delayTimes = 3 * 1000 ;
        // 发送延迟消息 
        cancelOrderSender.sendMessage ( 12333333L , delayTimes); 
        체계. 아웃 .println ( 12333333L ); 
        System.err.println을 (delayTimes); 
        체계. 아웃 .println (에 System.currentTimeMillis ()); 

        체계. 밖으로 .println ( "   大傻逼" ); 



        } 
}

테스트 결과 :

2019 - 12 - 20  21 : 48 : 44.932 | -info [HTTP-nio- 8082 -exec- 1 ] com.jds.rabbitmq.CancelOrderSender [ 40 ] - | 송신 지연 메시지 ORDERID : 12,333,333 
12,333,333 
1,576,849,724,932 
  大傻逼
3000 
1,576,849,727,975 
2019 - 12 - 20  21 : 48 : 47.975 | -info [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer # 0 - 1 ] com.jds.rabbitmq.CancelOrderReceiver [ 21] - | 지연 메시지에 OrderID가 나타납니다 12333333 
1576849727975 
大傻逼222222 
12333333을

전화 :

에 http : // localhost를 : 8082 / 아이디, 당신은 시간이 3 초 동안 지연 될 것입니다 볼 수 있습니다.

주요 장소를 달성하기 위해 :

새로운 새로운 위해 MessagePostProcessor는 () { 
            @Override 
            공공 메시지 postProcessMessage (메시지 메시지) AmqpException {발생
                 // 지연 메시지 밀리 세트 
                message.getMessageProperties ()를 setExpiration (한 String.valueOf (delayTimes을));
                 리턴 메시지; 
            }

지연 시간 매개 변수를 설정하려면

추천

출처www.cnblogs.com/xiufengchen/p/12075223.html