Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用rabbitmq的Spring引导故障转移重试程序:未能调用目标方法_Java_Spring Boot_Rabbitmq_Spring Rabbit - Fatal编程技术网

Java 使用rabbitmq的Spring引导故障转移重试程序:未能调用目标方法

Java 使用rabbitmq的Spring引导故障转移重试程序:未能调用目标方法,java,spring-boot,rabbitmq,spring-rabbit,Java,Spring Boot,Rabbitmq,Spring Rabbit,实际上,我正在尝试使用rabbit mq实现故障转移重试器功能 因此,要求是从队列中获取消息并对其进行处理。如果出现任何问题,则需要再次重试该消息3次 谁能帮我解决这个问题 这是我的密码 POJO package com.poc.failoverretryer.model; import java.io.Serializable; public class User implements Serializable { private String firstname; pr

实际上,我正在尝试使用rabbit mq实现故障转移重试器功能

因此,要求是从队列中获取消息并对其进行处理。如果出现任何问题,则需要再次重试该消息3次

谁能帮我解决这个问题

这是我的密码

POJO

package com.poc.failoverretryer.model;

import java.io.Serializable;

public class User implements Serializable {

    private String firstname;
    private String lastname;
    private String dob;

    public User(String firstname, String lastname, String dob) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.dob = dob;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getDob() {
        return dob;
    }

    public void setDob(String dob) {
        this.dob = dob;
    }

    @Override
    public String toString() {
        return "User{" +
                "firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", dob='" + dob + '\'' +
                '}';
    }
}

配置文件

package com.poc.failoverretryer.config;

import com.poc.failoverretryer.model.User;
import com.poc.failoverretryer.receiver.Receiver;
import com.poc.failoverretryer.receiver.ReceiverTwo;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.io.Serializable;

@Configuration
public class RMQConfiguration implements Serializable {

    @Value("${data.incoming.x}")
    String EXCHANGE_NAME;
    @Value("${data.dl.x}")
    String DEAD_LETTER_EXCHANGE_NAME;
    @Value("${incoming.queue}")
    String INCOMING_QUEUE_NAME;
    @Value("${data.incoming.two}")
    String INCOMING_QUEUE_TWO_NAME;
    @Value("${data.dl}")
    String DEAD_LETTER_QUEUE_NAME;
    @Value("${data.dl.two}")
    String DEAD_LETTER_QUEUE_TWO_NAME;
    @Value("${data.parking}")
    String PARKING_LOT_QUEUE_NAME;
    @Value("${retry.delay:3000}")
    public long DELAYED_RETRY_TIME;
    @Value("${max.retry:3}")
    public int MAX_RETRY_ATTEMPTS;

    @Primary
    @Bean
    Queue queue() {
        return QueueBuilder.durable(INCOMING_QUEUE_NAME)
                .deadLetterExchange(DEAD_LETTER_EXCHANGE_NAME)
                .build();
    }

    @Bean
    Queue queueTwo() {
        return QueueBuilder.durable(INCOMING_QUEUE_TWO_NAME)
                .deadLetterExchange(DEAD_LETTER_EXCHANGE_NAME)
                .build();
    }

    @Bean
    Queue deadLetterQueue() {
        return QueueBuilder.durable(DEAD_LETTER_QUEUE_NAME)
                .deadLetterExchange(EXCHANGE_NAME)
                .withArgument("x-message-ttl", DELAYED_RETRY_TIME)
                .build();
    }

    @Bean
    Queue deadLetterTwoQueue() {
        return QueueBuilder.durable(DEAD_LETTER_QUEUE_TWO_NAME)
                .deadLetterExchange(EXCHANGE_NAME)
                .withArgument("x-message-ttl", DELAYED_RETRY_TIME)
                .build();
    }

    @Bean
    Queue parkingLotQueue() {
        return new Queue(PARKING_LOT_QUEUE_NAME, true);
    }

    @Bean
    DirectExchange exchange() {
        return new DirectExchange(EXCHANGE_NAME);
    }

    @Bean
    DirectExchange deadLetterExchange() {
        return new DirectExchange(DEAD_LETTER_EXCHANGE_NAME);
    }

    @Bean
    Binding binding(@Qualifier("queue") Queue queue, @Qualifier("exchange") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(INCOMING_QUEUE_NAME);
    }

    @Bean
    Binding bindingTwo(@Qualifier("queueTwo") Queue queue, @Qualifier("exchange") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(INCOMING_QUEUE_TWO_NAME);
    }

    @Bean
    Binding deadLetterBinding(@Qualifier("deadLetterQueue") Queue queue, @Qualifier("deadLetterExchange") DirectExchange exchange) {
        return BindingBuilder
                .bind(queue)
                .to(exchange).with(INCOMING_QUEUE_NAME);
    }

    @Bean
    Binding deadLetterTwoBinding(@Qualifier("deadLetterTwoQueue") Queue queue, @Qualifier("deadLetterExchange") DirectExchange exchange) {
        return BindingBuilder
                .bind(queue)
                .to(exchange).with(INCOMING_QUEUE_TWO_NAME);
    }

    @Bean
    @Qualifier("myRabbitListenerContainer")
    SimpleMessageListenerContainer myRabbitListenerContainer(ConnectionFactory connectionFactory, @Qualifier("messageListenerAdapter") MessageListenerAdapter listenerAdapter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(INCOMING_QUEUE_NAME);
        container.setMessageListener(listenerAdapter);
        return container;
    }

    @Bean
    @Qualifier("myRabbitListenerTwoContainer")
    SimpleMessageListenerContainer myRabbitListenerTwoContainer(ConnectionFactory connectionFactory, @Qualifier("messageListenerTwoAdapter") MessageListenerAdapter listenerAdapter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(INCOMING_QUEUE_TWO_NAME);

        container.setMessageListener(listenerAdapter);
        return container;
    }

    @Primary
    @Bean
    MessageListenerAdapter messageListenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    MessageListenerAdapter messageListenerTwoAdapter(ReceiverTwo receiverTwo) {
        return new MessageListenerAdapter(receiverTwo, "receiveMessageTwo");
    }
}

**听众呢**

package com.poc.failoverretryer.receiver;

import com.poc.failoverretryer.config.RMQConfiguration;
import com.poc.failoverretryer.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Optional;

@Component
public class Receiver {
    Logger logger = LoggerFactory.getLogger(Receiver.class);
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Value("${max.retry:3}")
    public int MAX_RETRY_ATTEMPTS;

    @Value("${data.parking}")
    String PARKING_LOT_QUEUE_NAME;

    public void receiveMessage(Message message, @Header(required = false, name = "x-death") List<Map<String, Object>> xDeath) throws InterruptedException {
        System.out.println("Received <" + message + ">");

        logger.info(String.valueOf(xDeath));

        if (message == null) {
            System.out.println("The message is null");
            return;
        }
        try {
            process(message.getBody());
        } catch (Exception e) {
            if (checkIfNeedToRetry(xDeath))
                throw new AmqpRejectAndDontRequeueException("Failed to process message");
            else
                rabbitTemplate.convertAndSend(PARKING_LOT_QUEUE_NAME, message);
        }
    }

    private void process(byte[] message) throws Exception {
        throw new Exception("Test");
    }

    private boolean checkIfNeedToRetry(List<Map<String, Object>> xDeath) {
        long retryCount = 0L;
        if (xDeath != null) {
            Optional<Long> count = xDeath.stream()
                    .flatMap(m -> m.entrySet().stream())
                    .filter(e -> e.getKey().equals("count"))
                    .findFirst().map(e -> (Long) e.getValue());

            retryCount = count.map(Long::longValue).orElse(retryCount);
//            if (count.isPresent()) {
//                retryCount = count.get().longValue();
//                System.out.println("Retry: " + retryCount);
//            } else {
//
//            }
        }

        System.out.println(retryCount);

        if (retryCount <= MAX_RETRY_ATTEMPTS) {
            System.out.println("Retrying");

            return true;
        } else {
            System.out.println("exceed max retry " + retryCount + " -> sending to parking lot");
            return false;
        }
    }
}
public void receiveMessage(Message Message,@Header(required=false,name=“x-death”)列表xDeath)引发中断异常{
您不能将
@Header
与旧式侦听器适配器一起使用,后者只能与
@RabbitListener
方法一起使用

无论如何都不需要它;您可以从

message.getMessageProperties().getXDeathHeader();
public void receiveMessage(消息消息,@Header(required=false,name=“x-death”)List xDeath)引发中断异常{
您不能将
@Header
与旧式侦听器适配器一起使用,后者只能与
@RabbitListener
方法一起使用

无论如何都不需要它;您可以从

message.getMessageProperties().getXDeathHeader();

是否有可能使用自定义对象并使用旧侦听器获取xDeath?
public void receiveMessage(用户)抛出InterruptedException
,因为配置中与
SimpleMessageListenerContainer
一起使用的
@Header
抛出相同的转换错误否;对于旧适配器,您要么获得完整的消息,要么仅获得转换后的有效负载。您必须使用
@RabbitListener
进行丰富的参数映射。是否存在是否有可能使用自定义对象并使用旧侦听器获取xDeath?
public void receiveMessage(用户)抛出InterruptedException
,因为配置中与
SimpleMessageListenerContainer
一起使用的
@Header
抛出相同的转换错误否;对于旧适配器,您要么得到完整的消息,要么只得到转换后的负载。必须使用
@RabbitListener
进行丰富的参数映射。