Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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 SimpleMessageListenerContainer正在中止无效消息_Java_Spring_Rabbitmq_Spring Rabbit - Fatal编程技术网

Java RabbitMQ的Spring SimpleMessageListenerContainer正在中止无效消息

Java RabbitMQ的Spring SimpleMessageListenerContainer正在中止无效消息,java,spring,rabbitmq,spring-rabbit,Java,Spring,Rabbitmq,Spring Rabbit,我正在使用springs SimpleMessageListenerContainer来使用RabbitMQ队列中的消息。一切正常,但当向队列发送无效消息(例如无效json)时,侦听器只是中止,关闭工作进程,不接受任何进一步的消息 是否可以将其配置为丢弃已断开的消息并继续侦听其他消息 我正在使用sprint-rabbit-1.6.1.RELEASE.jar 我的配置如下所示: @Bean public SimpleMessageListenerContainer container(Connec

我正在使用springs SimpleMessageListenerContainer来使用RabbitMQ队列中的消息。一切正常,但当向队列发送无效消息(例如无效json)时,侦听器只是中止,关闭工作进程,不接受任何进一步的消息

是否可以将其配置为丢弃已断开的消息并继续侦听其他消息

我正在使用sprint-rabbit-1.6.1.RELEASE.jar

我的配置如下所示:

@Bean
public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
                                                MessageListenerAdapter listenerAdapter,
                                                MessageConverter messageConverter) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setQueueNames("my.queue");
    container.setMessageListener(listenerAdapter);
    container.setMessageConverter(messageConverter);
    return container;
}

@Bean
public MessageConverter messageConverter() {
    return new Jackson2JsonMessageConverter();
}

@Bean
MessageListenerAdapter listenerAdapter(Worker worker) {
    MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(worker, "processMessage");
    messageListenerAdapter.setMessageConverter(new Jackson2JsonMessageConverter());
    return messageListenerAdapter;
}
my listener方法的声明:

   public void processMessage(Map<String, String> message) {
SimpleMessageListenerContainer中的致命异常在此处引发:

catch (ListenerExecutionFailedException ex) {
                    // Continue to process, otherwise re-throw
                    if (ex.getCause() instanceof NoSuchMethodException) {
                        throw new FatalListenerExecutionException("Invalid listener", ex);
                    }
                }
因此,如果容器配置了一个不存在的方法,那么它似乎应该关闭。但是,在消息中断的情况下,它试图使用错误的参数类型调用该方法,这也会导致NoSuchMethodException。这意味着任何制作人都可以用一条坏消息杀死我的消费者


谢谢你的建议

有趣;我能够复制你的问题;事实证明,如果消息不包含
\uuuuu TypeID\uuuu
头(转换提示),它只会以字符串形式返回“坏”json

我可以通过向转换器中注入自定义类映射器来解决这个问题

您还可以让发送系统设置类型标头

然后,消息被拒绝,因为我们得到了
MessageConversionException

package com.example;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.support.converter.ClassMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.amqp.support.converter.SimpleMessageConverter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class So39264965Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So39264965Application.class, args);
        RabbitTemplate template = context.getBean(RabbitTemplate.class);
        template.convertAndSend("my.queue", new Foo());
        context.getBean(Worker.class).latch.await(60, TimeUnit.SECONDS);

        // bad json
        template.setMessageConverter(new SimpleMessageConverter());
        template.convertAndSend("", "my.queue", "\"routeId\":\"7\"}", m -> {
            m.getMessageProperties().setContentType("application/json");
            return m;
        });


        Thread.sleep(60000);
        context.close();
    }

    @Bean
    public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
            MessageListenerAdapter listenerAdapter, MessageConverter messageConverter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("my.queue");
        container.setMessageListener(listenerAdapter);
        container.setMessageConverter(messageConverter);
        return container;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter());
        return rabbitTemplate;
    }

    @Bean
    public Queue queue() {
        return new Queue("my.queue");
    }

    @Bean
    public MessageConverter messageConverter() {
        Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
        jackson2JsonMessageConverter.setClassMapper(new ClassMapper() {

            @Override
            public Class<?> toClass(MessageProperties properties) {
                return Foo.class;
            }

            @Override
            public void fromClass(Class<?> clazz, MessageProperties properties) {

            }

        });
        return jackson2JsonMessageConverter;
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Worker worker) {
        MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(worker, "processMessage");
        messageListenerAdapter.setMessageConverter(messageConverter());
        return messageListenerAdapter;
    }

    @Bean
    public Worker worker() {
        return new Worker();
    }

    public static class Worker {

        private final CountDownLatch latch = new CountDownLatch(1);

        public void processMessage(Foo foo) {
            System.out.println(foo);
            this.latch.countDown();
        }

    }

    public static class Foo {

        private String bar = "bar";

        public String getBar() {
            return this.bar;
        }

        public void setBar(String bar) {
            this.bar = bar;
        }

        @Override
        public String toString() {
            return "Foo [bar=" + this.bar + "]";
        }

    }

}
package.com.example;
导入java.util.concurrent.CountDownLatch;
导入java.util.concurrent.TimeUnit;
导入org.springframework.amqp.core.MessageProperties;
导入org.springframework.amqp.core.Queue;
导入org.springframework.amqp.rabbit.connection.ConnectionFactory;
导入org.springframework.amqp.rabbit.core.RabbitTemplate;
导入org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
导入org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
导入org.springframework.amqp.support.converter.ClassMapper;
导入org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
导入org.springframework.amqp.support.converter.MessageConverter;
导入org.springframework.amqp.support.converter.SimpleMessageConverter;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.springframework.context.ConfigurableApplicationContext;
导入org.springframework.context.annotation.Bean;
@SpringBoot应用程序
公共类SO39264965应用程序{
公共静态void main(字符串[]args)引发异常{
ConfigurableApplicationContext上下文=SpringApplication.run(So39264965Application.class,args);
RabbitTemplate=context.getBean(RabbitTemplate.class);
convertAndSend(“my.queue”,new Foo());
getBean(Worker.class).lack.await(60,TimeUnit.SECONDS);
//错误的json
setMessageConverter(新的SimpleMessageConverter());
template.convertAndSend(“,”my.queue“,“\”routeId\“:\”7\“}”,m->{
m、 getMessageProperties().setContentType(“应用程序/json”);
返回m;
});
睡眠(60000);
context.close();
}
@豆子
公共SimpleMessageListenerContainer容器(ConnectionFactory ConnectionFactory,
MessageListenerAdapter listenerAdapter,MessageConverter MessageConverter){
SimpleMessageListenerContainer容器=新SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(“my.queue”);
setMessageListener(listenerAdapter);
container.setMessageConverter(messageConverter);
返回容器;
}
@豆子
公共RabbitTemplate RabbitTemplate(连接工厂连接工厂){
RabbitTemplate RabbitTemplate=新的RabbitTemplate(连接工厂);
setMessageConverter(messageConverter());
返回兔模板;
}
@豆子
公共队列(){
返回新队列(“my.Queue”);
}
@豆子
public MessageConverter MessageConverter(){
Jackson2JsonMessageConverter Jackson2JsonMessageConverter=新Jackson2JsonMessageConverter();
jackson2JsonMessageConverter.setClassMapper(新类映射器(){
@凌驾
公共类到类(MessageProperties属性){
返回Foo.class;
}
@凌驾
来自类的公共void(类clazz、MessageProperties){
}
});
返回jackson2JsonMessageConverter;
}
@豆子
MessageListenerAdapter listenerAdapter(工作者){
MessageListenerAdapter MessageListenerAdapter=newmessagelisteneradapter(worker,“processMessage”);
messageListenerAdapter.setMessageConverter(messageConverter());
返回消息listeneradapter;
}
@豆子
公职人员(){
返回新工人();
}
公共静态类工作者{
专用最终倒计时闩锁=新倒计时闩锁(1);
公共无效处理消息(Foo-Foo){
系统输出打印项次(foo);
这个.latch.countDown();
}
}
公共静态类Foo{
私有字符串bar=“bar”;
公共字符串getBar(){
返回此.bar;
}
公共空心立根杆(弦杆){
这个.bar=bar;
}
@凌驾
公共字符串toString(){
返回“Foo[bar=“+this.bar+”]”;
}
}
}

我不确定您所说的
是什么意思,但如果消息中断,它试图使用错误的参数类型调用该方法,这也会导致NoSuchMethodException。
。您需要显示完整的堆栈跟踪,而不是已编辑的堆栈跟踪,您使用的是什么版本?通常,错误的JSON会导致
MessageConversionExceptio
package com.example;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.support.converter.ClassMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.amqp.support.converter.SimpleMessageConverter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class So39264965Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So39264965Application.class, args);
        RabbitTemplate template = context.getBean(RabbitTemplate.class);
        template.convertAndSend("my.queue", new Foo());
        context.getBean(Worker.class).latch.await(60, TimeUnit.SECONDS);

        // bad json
        template.setMessageConverter(new SimpleMessageConverter());
        template.convertAndSend("", "my.queue", "\"routeId\":\"7\"}", m -> {
            m.getMessageProperties().setContentType("application/json");
            return m;
        });


        Thread.sleep(60000);
        context.close();
    }

    @Bean
    public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
            MessageListenerAdapter listenerAdapter, MessageConverter messageConverter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("my.queue");
        container.setMessageListener(listenerAdapter);
        container.setMessageConverter(messageConverter);
        return container;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter());
        return rabbitTemplate;
    }

    @Bean
    public Queue queue() {
        return new Queue("my.queue");
    }

    @Bean
    public MessageConverter messageConverter() {
        Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
        jackson2JsonMessageConverter.setClassMapper(new ClassMapper() {

            @Override
            public Class<?> toClass(MessageProperties properties) {
                return Foo.class;
            }

            @Override
            public void fromClass(Class<?> clazz, MessageProperties properties) {

            }

        });
        return jackson2JsonMessageConverter;
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Worker worker) {
        MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(worker, "processMessage");
        messageListenerAdapter.setMessageConverter(messageConverter());
        return messageListenerAdapter;
    }

    @Bean
    public Worker worker() {
        return new Worker();
    }

    public static class Worker {

        private final CountDownLatch latch = new CountDownLatch(1);

        public void processMessage(Foo foo) {
            System.out.println(foo);
            this.latch.countDown();
        }

    }

    public static class Foo {

        private String bar = "bar";

        public String getBar() {
            return this.bar;
        }

        public void setBar(String bar) {
            this.bar = bar;
        }

        @Override
        public String toString() {
            return "Foo [bar=" + this.bar + "]";
        }

    }

}