Java Code Examples for com.rabbitmq.client.Channel#basicAck()

The following examples show how to use com.rabbitmq.client.Channel#basicAck() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MyAckReceiver2.java    From springboot-learn with MIT License 6 votes vote down vote up
@RabbitHandler
public void process(String sendMsg, Channel channel, Message message) {

    System.out.println("AckReceiver  : 收到发送消息 " + sendMsg.toString() + ",收到消息时间"
            + LocalDateTime.now(ZoneId.systemDefault()));

    MessageObj messageObj = JSON.parseObject(sendMsg, MessageObj.class);
    System.out.println(messageObj.toString());
    try {
        //告诉服务器收到这条消息已经被当前消费者消费了,可以在队列安全删除,这样后面就不会再重发了,
        //否则消息服务器以为这条消息没处理掉,后续还会再发
        //第二个参数是消息的标识,false只确认当前一个消息收到,true确认所有consumer获得的消息
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        System.out.println("receiver success");
    } catch (Exception e) {
        System.out.println("receiver fail");
        e.printStackTrace();
    }

}
 
Example 2
Source File: ReceiveService.java    From seed with Apache License 2.0 6 votes vote down vote up
@RabbitListener(queues="${spring.rabbitmq.queues}", containerFactory="jadyerRabbitListenerContainerFactory")
public void receive(UserMsg userMsg, Channel channel, Message message){
    try {
        LogUtil.getLogger().info("收到消息-->[{}]", ReflectionToStringBuilder.toString(userMsg));
        //确认消费成功(第一个参数:消息编号。第二个参数:是否确认多条消息,false为确认当前消息,true为确认deliveryTag编号以前的所有消息)
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }catch(Exception e){
        LogUtil.getLogger().error("消息处理异常,消息ID={}, 消息体=[{}]", message.getMessageProperties().getCorrelationId(), JSON.toJSONString(userMsg), e);
        try {
            //拒绝当前消息,并把消息返回原队列(第三个参数:是否将消息放回队列,true表示放回队列,false表示丢弃消息)
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            //basicReject只能拒绝一条消息,而basicNack能够拒绝多条消息
            //channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        } catch (IOException e1) {
            LogUtil.getLogger().error("消息basicNack时发生异常,消息ID={}", message.getMessageProperties().getCorrelationId(), e);
        }
    }
}
 
Example 3
Source File: BookHandler.java    From springboot-learning-experience with Apache License 2.0 6 votes vote down vote up
/**
 * <p>TODO 该方案是 spring-boot-data-amqp 默认的方式,不太推荐。具体推荐使用  listenerManualAck()</p>
 * 默认情况下,如果没有配置手动ACK, 那么Spring Data AMQP 会在消息消费完毕后自动帮我们去ACK
 * 存在问题:如果报错了,消息不会丢失,但是会无限循环消费,一直报错,如果开启了错误日志很容易就吧磁盘空间耗完
 * 解决方案:手动ACK,或者try-catch 然后在 catch 里面讲错误的消息转移到其它的系列中去
 * spring.rabbitmq.listener.simple.acknowledge-mode=manual
 * <p>
 *
 * @param book 监听的内容
 */
@RabbitListener(queues = {RabbitConfig.DEFAULT_BOOK_QUEUE})
public void listenerAutoAck(Book book, Message message, Channel channel) {
    // TODO 如果手动ACK,消息会被监听消费,但是消息在队列中依旧存在,如果 未配置 acknowledge-mode 默认是会在消费完毕后自动ACK掉
    final long deliveryTag = message.getMessageProperties().getDeliveryTag();
    try {
        log.info("[listenerAutoAck 监听的消息] - [{}]", book.toString());
        // TODO 通知 MQ 消息已被成功消费,可以ACK了
        channel.basicAck(deliveryTag, false);
    } catch (IOException e) {
        try {
            // TODO 处理失败,重新压入MQ
            channel.basicRecover();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}
 
Example 4
Source File: ProducerExchangeConsumer_Direct.java    From util4j with Apache License 2.0 6 votes vote down vote up
public void consumer1() throws Exception {
	//1、获取连接
       Connection connection =RabbitMqConnectionFactoy.getConnection();
       //2、声明通道
       Channel channel = connection.createChannel();
       //3、声明队列
       channel.queueDeclare(QUEUE_NAME1, false, false, false, null);
       //绑定队列到交换机
       channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME,ROUTER_KEY_1);
       //同一时刻服务器只会发送一条消息给消费者(如果设置为N,则当客户端堆积N条消息后服务端不会推送给客户端了)
       //channel.basicQos(1);//每次处理1个
       //4、定义队列的消费者
       //定义消费者
       DefaultConsumer consumer = new DefaultConsumer(channel) {
           @Override
           public void handleDelivery(String consumerTag, Envelope envelope,BasicProperties properties, byte[] body)
                   throws IOException {
               //获取并转成String
               String message = new String(body, "UTF-8");
               System.out.println("-->消费者1号,收到消息,msg :"+message+",header:"+properties.getHeaders().toString());
               channel.basicAck(envelope.getDeliveryTag(), false);
           }
       };
       channel.basicConsume(QUEUE_NAME1, autoAck,consumer);
}
 
Example 5
Source File: ProducerExchangeConsumer_Topic.java    From util4j with Apache License 2.0 6 votes vote down vote up
public void consumer2() throws Exception {
	//1、获取连接
       Connection connection =RabbitMqConnectionFactoy.getConnection();
       //2、声明通道
       Channel channel = connection.createChannel();
       //3、声明队列
       channel.queueDeclare(QUEUE_NAME2, false, false, false, null);
       //绑定队列到交换机
       channel.queueBind(QUEUE_NAME2, EXCHANGE_NAME,"test.#");//基数偶数都接收
       //同一时刻服务器只会发送一条消息给消费者(如果设置为N,则当客户端堆积N条消息后服务端不会推送给客户端了)
       //channel.basicQos(1);//每次只从服务器取1个处理
       //4、定义队列的消费者
       DeliverCallback deliverCallback = (consumerTag, delivery) -> {
           String message = new String(delivery.getBody(), "UTF-8");
           System.out.println("-->消费者2号,收到消息,msg :"+message+",header:"+delivery.getProperties().getHeaders().toString());
           channel.basicAck( delivery.getEnvelope().getDeliveryTag(), false);
       };
       channel.basicConsume(QUEUE_NAME2, autoAck, deliverCallback, consumerTag -> { });
}
 
Example 6
Source File: DirectQueueOneHandler.java    From spring-boot-demo with MIT License 6 votes vote down vote up
@RabbitHandler
public void directHandlerManualAck(MessageStruct messageStruct, Message message, Channel channel) {
    //  如果手动ACK,消息会被监听消费,但是消息在队列中依旧存在,如果 未配置 acknowledge-mode 默认是会在消费完毕后自动ACK掉
    final long deliveryTag = message.getMessageProperties().getDeliveryTag();
    try {
        log.info("直接队列1,手动ACK,接收消息:{}", JSONUtil.toJsonStr(messageStruct));
        // 通知 MQ 消息已被成功消费,可以ACK了
        channel.basicAck(deliveryTag, false);
    } catch (IOException e) {
        try {
            // 处理失败,重新压入MQ
            channel.basicRecover();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}
 
Example 7
Source File: ProducerExchangeConsumer_Direct.java    From util4j with Apache License 2.0 6 votes vote down vote up
public void consumer2() throws Exception {
	//1、获取连接
       Connection connection =RabbitMqConnectionFactoy.getConnection();
       //2、声明通道
       Channel channel = connection.createChannel();
       //3、声明队列
       channel.queueDeclare(QUEUE_NAME2, false, false, false, null);
       //绑定队列到交换机
       channel.queueBind(QUEUE_NAME2, EXCHANGE_NAME,ROUTER_KEY_2);
       channel.queueBind(QUEUE_NAME2, EXCHANGE_NAME,ROUTER_KEY_22);
       //同一时刻服务器只会发送一条消息给消费者(如果设置为N,则当客户端堆积N条消息后服务端不会推送给客户端了)
       //channel.basicQos(1);//每次只从服务器取1个处理
       //4、定义队列的消费者
       DeliverCallback deliverCallback = (consumerTag, delivery) -> {
           String message = new String(delivery.getBody(), "UTF-8");
           System.out.println("-->消费者2号,收到消息,msg :"+message+",header:"+delivery.getProperties().getHeaders().toString());
           channel.basicAck( delivery.getEnvelope().getDeliveryTag(), false);
       };
       channel.basicConsume(QUEUE_NAME2, autoAck, deliverCallback, consumerTag -> { });
}
 
Example 8
Source File: MQAwareListener.java    From lemon-rabbitmq with Apache License 2.0 6 votes vote down vote up
@Override
  public void onMessage(Message message, Channel channel) throws IOException {
      System.out.println("----- received" + message.getMessageProperties());
try {
	Object msg = messageConverter.fromMessage(message);
	if (!appId.equals(message.getMessageProperties().getAppId())){
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        throw new SecurityException("非法应用appId:" + message.getMessageProperties().getAppId());
	}
	Object service = ctx.getBean(message.getMessageProperties().getHeaders().get("ServiceName").toString());
	String serviceMethodName = message.getMessageProperties().getHeaders().get("ServiceMethodName").toString();
	Method method = service.getClass().getMethod(serviceMethodName, msg.getClass());
       method.invoke(service, msg);
       //确认消息成功消费
       channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
	System.out.println("------ err"+ e.getMessage());
       channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
}
  }
 
Example 9
Source File: ProducerExchangeConsumer_Fanout.java    From util4j with Apache License 2.0 6 votes vote down vote up
public void consumer1() throws Exception {
	//1、获取连接
       Connection connection =RabbitMqConnectionFactoy.getConnection();
       //2、声明通道
       Channel channel = connection.createChannel();
       //3、声明队列
       channel.queueDeclare(QUEUE_NAME1, false, false, false, null);
       //绑定队列到交换机
       channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, "");
       //同一时刻服务器只会发送一条消息给消费者(如果设置为N,则当客户端堆积N条消息后服务端不会推送给客户端了)
       //channel.basicQos(1);//每次处理1个
       //4、定义队列的消费者
       //定义消费者
       DefaultConsumer consumer = new DefaultConsumer(channel) {
           @Override
           public void handleDelivery(String consumerTag, Envelope envelope,BasicProperties properties, byte[] body)
                   throws IOException {
               //获取并转成String
               String message = new String(body, "UTF-8");
               System.out.println("-->消费者1号,收到消息,msg :"+message+",header:"+properties.getHeaders().toString());
               channel.basicAck(envelope.getDeliveryTag(), false);
           }
       };
       channel.basicConsume(QUEUE_NAME1, autoAck,consumer);
}
 
Example 10
Source File: MongodbReceiver.java    From ChengFeng1.5 with MIT License 6 votes vote down vote up
@RabbitListener(queues = ChengfengConstant.RabbitMQ.QUEUE_NAME_MONGODB)
public void process(String init,Message message, Channel channel){
    try{
        log.info(init+"消息收到"+"初始化数据库内容到mongodb");
        List<Journalism> journalisms = journalismMapper.selectAllJournalisms();
        journalisms.stream().parallel().forEach(journalism -> {
            journalism.setCommentNums(0);
            Random random=new Random();

            journalism.setStarNums(random.nextInt(300));
            mongoRepository.save(journalism);
        });
    }finally {
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
 
Example 11
Source File: RabbitEventArgListener.java    From bird-java with MIT License 6 votes vote down vote up
@Override
public void onMessage(Message message, Channel channel) throws Exception {
    Class<?> clazz;
    String className = message.getMessageProperties().getReceivedExchange();
    try {
        clazz = Class.forName(className);
        if (!IEventArg.class.isAssignableFrom(clazz)) {
            log.error("事件处理失败:" + className + "不是IEventArg的子类");
        }
    } catch (ClassNotFoundException ex) {
        log.error("事件处理失败:", ex);
        return;
    }

    String body = new String(message.getBody(), Charset.forName("utf8"));
    IEventArg eventArg = (IEventArg) JSON.parseObject(body,clazz);

    dispatcher.enqueue(eventArg);
    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费
}
 
Example 12
Source File: RabbitMQTest.java    From james-project with Apache License 2.0 5 votes vote down vote up
private void incrementCountForConsumerAndAckMessage(AtomicInteger firstRegisteredConsumerMessageCount, Delivery message, Channel channel2) throws IOException {
    try {
        firstRegisteredConsumerMessageCount.incrementAndGet();
        TimeUnit.SECONDS.sleep(1);
        channel2.basicAck(message.getEnvelope().getDeliveryTag(), false);
    } catch (InterruptedException e) {
        //do nothing
    }
}
 
Example 13
Source File: Consumer.java    From rabbitmq-tutorial with MIT License 5 votes vote down vote up
public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException, IOException, InterruptedException {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setUri("amqp://guest:guest@localhost");
    factory.setConnectionTimeout(300000);
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();
    channel.queueDeclare("my-queue", true, false, false, null);

    QueueingConsumer consumer = new QueueingConsumer(channel);
    channel.basicConsume("my-queue", false, consumer);

    while (true) {
        QueueingConsumer.Delivery delivery = consumer.nextDelivery();

        if (delivery != null) {
            try {
                String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
                System.out.println("Message consumed: " + message);
                // Interact with IO
                channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
            } catch (Exception e) {
                channel.basicReject(delivery.getEnvelope().getDeliveryTag(), true);
            }
        }
    }

}
 
Example 14
Source File: MessageAckListener.java    From spring-cloud-gray with Apache License 2.0 5 votes vote down vote up
@StreamListener(TestSourceInput.INPUT)
    public void receive(Object msg, @Header(AmqpHeaders.CHANNEL) Channel channel,
                        @Header(AmqpHeaders.DELIVERY_TAG) Long deliveryTag) throws IOException {
        log.info("Received3:" + msg);
        boolean request = false;//true=重新发送
//        channel.basicReject(deliveryTag, request);
        channel.basicAck(deliveryTag, false);
    }
 
Example 15
Source File: AbstractMqListener.java    From spring-cloud-shop with MIT License 5 votes vote down vote up
@Override
public void basicAck(Channel channel, long deliveryTag) {
    try {
        log.info("消息确认成功已消费");
        channel.basicAck(deliveryTag, false);
    } catch (IOException e) {
        log.error("消息确认失败未消费");
        try {
            // 重新接收消息,不消费此消息
            channel.basicNack(deliveryTag, false, true);
        } catch (IOException e1) {
            log.error("重新发送消息失败。。。");
        }
    }
}
 
Example 16
Source File: RpcTest.java    From util4j with Apache License 2.0 5 votes vote down vote up
public void rpcServer() throws Exception {
 	//1、获取连接
       Connection connection = RabbitMqConnectionFactoy.getConnection();
       //2、声明信道
       Channel channel = connection.createChannel();
       //3、声明队列
       channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null);
       channel.basicQos(1);
       DefaultConsumer consumer = new DefaultConsumer(channel) {
           @Override
           public void handleDelivery(String consumerTag, Envelope envelope,BasicProperties properties, byte[] body)
                   throws IOException {
               //获取并转成String
               String message = new String(body, "UTF-8");
               String cid=properties.getCorrelationId();
               System.out.println("server-->收到消息,msg :"+message+",cid:"+cid);
               String rsp=message+" rsp";
               // 返回处理结果队列
                  channel.basicPublish("", properties.getReplyTo(), properties,rsp.getBytes("UTF-8"));
                  //  确认消息,已经收到后面参数 multiple:是否批量.true:将一次性确认所有小于envelope.getDeliveryTag()的消息。
                  channel.basicAck(envelope.getDeliveryTag(), false);
           }
       };
       channel.basicConsume(RPC_QUEUE_NAME, autoAck,consumer);
       Thread.sleep(1000000);
       //6、关闭通道
       channel.close();
       //7、关闭连接
       connection.close();
}
 
Example 17
Source File: OrderCancelConsumer.java    From gpmall with Apache License 2.0 4 votes vote down vote up
@RabbitListener(queues = RabbitMqConfig.DELAY_QUEUE)
public void process(String context,Message message,Channel channel)throws  IOException{
   try {
	log.info("开始执行订单[{}]的支付超时订单关闭......", context);
	Order order=new Order();
	order.setOrderId(context);
	//先查询订单是否是待支付状态
	Order order1=orderMapper.selectByPrimaryKey(order);
	//未付款才去走逻辑
	if(order1.getStatus()==0){
		order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
		//将订单状态改为取消
		orderMapper.updateByPrimaryKey(order);
		//将订单商品的库存状态改为释放
		orderItemMapper.updateStockStatus(2,context);
		//将库存还回去
		List<OrderItem> list=orderItemMapper.queryByOrderId(context);
		List<Long> itemIds=list.stream().map(OrderItem::getItemId).sorted().collect(Collectors.toList());
		//锁 itemIds
		List<Stock> stocks=stockMapper.findStocksForUpdate(itemIds);
		stocks.forEach(stock -> {
			list.forEach(one->{
				if(Objects.equals(one.getItemId(),stock.getItemId())){
					stock.setLockCount(-one.getNum());
					stock.setStockCount(one.getNum().longValue());
					//释放库存
					stockMapper.updateStock(stock);
					return;
				}
			});
		});
	}
	channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
	log.info("超时订单{}处理完毕",context);
}catch (Exception e){
   	log.error("超时订单处理失败:{}",context);
   	e.printStackTrace();
   	//这里会不断消费吗?
   	channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
}
 }
 
Example 18
Source File: Worker.java    From neo4j-mazerunner with Apache License 2.0 4 votes vote down vote up
public void doMain(String[] args) throws Exception {

        CmdLineParser parser = new CmdLineParser(this);

        // if you have a wider console, you could increase the value;
        // here 80 is also the default
        parser.setUsageWidth(80);

        try {
            // parse the arguments.
            parser.parseArgument(args);

            if(sparkMaster == "" || hadoopHdfs == "")
                throw new CmdLineException(parser, "Options required: --hadoop.hdfs <url>, --spark.master <url>");

            ConfigurationLoader.getInstance().setHadoopHdfsUri(hadoopHdfs);
            ConfigurationLoader.getInstance().setSparkHost(sparkMaster);
            ConfigurationLoader.getInstance().setAppName(sparkAppName);
            ConfigurationLoader.getInstance().setExecutorMemory(sparkExecutorMemory);
            ConfigurationLoader.getInstance().setDriverHost(driverHost);
            ConfigurationLoader.getInstance().setRabbitmqNodename(rabbitMqHost);

        } catch( CmdLineException e ) {
            // if there's a problem in the command line,
            // you'll get this exception. this will report
            // an error message.
            System.err.println(e.getMessage());
            System.err.println("java -cp $CLASSPATH [<spark-config-options>] <main-class> [<mazerunner-args>]");
            // print the list of available options
            parser.printUsage(System.err);
            System.err.println();

            // print option sample. This is useful some time
            System.err.println("  Example: java -cp $CLASSPATH org.mazerunner.core.messaging.Worker"+parser.printExample(ALL));

            return;
        }

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(ConfigurationLoader.getInstance().getRabbitmqNodename());
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);

        channel.basicQos(20);

        // Initialize spark context
        GraphProcessor.initializeSparkContext();

        QueueingConsumer consumer = new QueueingConsumer(channel);
        channel.basicConsume(TASK_QUEUE_NAME, false, consumer);

        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());

            System.out.println(" [x] Received '" + message + "'");

            // Deserialize message
            Gson gson = new Gson();
            ProcessorMessage processorMessage = gson.fromJson(message, ProcessorMessage.class);

            // Run PageRank
            GraphProcessor.processEdgeList(processorMessage);

            System.out.println(" [x] Done '" + message + "'");
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
    }
 
Example 19
Source File: BatchWriterService.java    From neo4j-mazerunner with Apache License 2.0 4 votes vote down vote up
@Override
protected void runOneIteration() throws Exception {
    logger.info("Connecting to RabbitMQ processor queue...");

    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost(ConfigurationLoader.getInstance().getRabbitmqNodename());
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

    channel.basicQos(1);

    QueueingConsumer consumer = new QueueingConsumer(channel);
    channel.basicConsume(TASK_QUEUE_NAME, false, consumer);

    while (true) {
        QueueingConsumer.Delivery delivery = null;
        try {
            delivery = consumer.nextDelivery(40000L);

            if(delivery != null) {
                String message = new String(delivery.getBody());

                System.out.println(" [x] Received processor message '" + message + "'");

                // Deserialize the processor message
                Gson gson = new Gson();
                ProcessorMessage processorMessage = gson.fromJson(message, ProcessorMessage.class);

                // Open the node property update list file from HDFS
                BufferedReader bufferedReader = FileUtil.readGraphAdjacencyList(processorMessage);

                switch (processorMessage.getMode()) {
                    case Partitioned:
                        PartitionedAnalysis.updatePartition(processorMessage, bufferedReader, graphDb);
                        break;
                    case Unpartitioned:
                        if (Objects.equals(processorMessage.getAnalysis(), JobRequestType.COLLABORATIVE_FILTERING.toString().toLowerCase())) {
                            Writer.asyncImportCollaborativeFiltering(bufferedReader, graphDb);
                        } else {
                            // Stream the the updates as parallel transactions to Neo4j
                            Writer.asyncUpdate(processorMessage, bufferedReader, graphDb);
                        }
                        break;
                }

                // Close the stream
                bufferedReader.close();

                System.out.println(" [x] Done");

                channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Waiting...");

            // Hold on error cycle to prevent high throughput writes to console log
            Thread.sleep(5000);
            System.out.println("Recovered...");

            if(delivery != null)
                channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
    }
}
 
Example 20
Source File: MessageAdapterHandler.java    From shine-mq with Apache License 2.0 4 votes vote down vote up
@Override
public void onMessage(Message message, Channel channel) throws Exception {
    EventMessage em = null;
    Coordinator coordinator = null;
    long tag = message.getMessageProperties().getDeliveryTag();
    String msgId = message.getMessageProperties().getMessageId();
    try {
        ProcessorWrap wrap;
        em = JSON.parseObject(message.getBody(), EventMessage.class);
        if (MqConstant.DEAD_LETTER_EXCHANGE.equals(message.getMessageProperties().getReceivedExchange()) &&
                MqConstant.DEAD_LETTER_ROUTEKEY.equals(message.getMessageProperties().getReceivedRoutingKey())) {
            wrap = map.get(MqConstant.DEAD_LETTER_EXCHANGE + "_" + MqConstant.DEAD_LETTER_ROUTEKEY +
                    "_" + SendTypeEnum.DLX);
        } else {
            wrap = map.get(em.getExchangeName() + "_" + em.getRoutingKey() + "_" + em.getSendTypeEnum());
        }
        //如果是分布式事务的消息,sdk提供ack应答,无须自己手动ack
        if (SendTypeEnum.DISTRIBUTED.toString().equals(em.getSendTypeEnum())) {
            Objects.requireNonNull(em.getCoordinator(),
                    "Distributed transaction message error: coordinator is null.");
            coordinator = (Coordinator) applicationContext.getBean(em.getCoordinator());
            wrap.process(em.getData(), message, channel);
            channel.basicAck(tag, false);
        } else {
            wrap.process(em.getData(), message, channel);
        }
    } catch (Exception e) {
        log.error("MessageAdapterHandler error, message: {} :", em, e);
        if (em != null && coordinator != null && SendTypeEnum.DISTRIBUTED.toString().equals(em.getSendTypeEnum())) {
            Double resendCount = coordinator.incrementResendKey(MqConstant.RECEIVE_RETRIES, msgId);
            if (resendCount >= rabbitmqFactory.getConfig().getDistributed().getReceiveMaxRetries()) {
                if (Strings.isNullOrEmpty(em.getRollback())) {
                    // 放入死信队列
                    channel.basicNack(tag, false, false);
                } else {
                    em.setSendTypeEnum(SendTypeEnum.ROLLBACK.toString());
                    em.setRoutingKey(em.getRollback());
                    rabbitmqFactory.setCorrelationData(msgId, em.getCoordinator(), em,
                            null);
                    coordinator.setRollback(msgId, em);
                    rabbitmqFactory.getTemplate().send(em, 0, 0, SendTypeEnum.ROLLBACK);
                    channel.basicAck(tag, false);
                }
                coordinator.delResendKey(MqConstant.RECEIVE_RETRIES, msgId);
            } else {
                // 重新放入队列 等待消费
                channel.basicNack(tag, false, true);
            }
        } else {
            throw e;
        }
    }
}