Spring AMQP客户端挂起

时间:2018-02-09 05:20:26

标签: rabbitmq spring-amqp spring-rabbit

RabbitMQ服务器中存在一种行为,即当它达到水印值时它将不再接受后续连接/操作,直到它重新平衡自身为止。 当连接超时后发生这种情况时,RabbitMQ客户端优雅地获得超时,但我们正在使用Spring AMQP它继续挂起。

重现步骤

o创建RabbitMQ HA集群

o创建一个生成和使用消息的简单程序

  • a)使用Spring AMQP
  • b)使用RabbitMQ客户端

o使RabbitMQ服务器在内存中达到高水位值,以便它不能接受任何新连接或执行任何操作,比如10分钟

o创建Q,从

发送消息
  • a)Spring AMQP(它会挂起)
  • b)RabbitMQ客户端(它将超时)在1分钟后说如果连接超时设置为1分钟。

Spring二进制版本

a)spring-rabbit-1.6.7.RELEASE.jar

b)spring-core-4.3.6.RELEASE.jar

c)spring-amqp-1.6.7.RELEASE.jar

我们尝试升级到Spring Rabbit和AMQP 2.0.2版本,但它没有帮助。

1 个答案:

答案 0 :(得分:1)

您无法描述您的" RabbitMQ客户端"是,但java amqp-client默认使用经典套接字。因此,您应该同时获得相同的行为(因为Spring AMQP使用该客户端)。也许你指的是其他语言客户端。

使用java Socket s,当连接被阻止时,线程会被"卡住"在套接字写入中,它是不可中断的,也不会超时。

要处理这种情况,您必须使用the 4.0 client or above并使用NIO。

以下是演示该技术的示例应用程序。

@SpringBootApplication
public class So48699178Application {

    private static Logger logger = LoggerFactory.getLogger(So48699178Application.class);

    public static void main(String[] args) {
        SpringApplication.run(So48699178Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(RabbitTemplate template, CachingConnectionFactory ccf) {
        ConnectionFactory cf = ccf.getRabbitConnectionFactory();
        NioParams nioParams = new NioParams();
        nioParams.setWriteEnqueuingTimeoutInMs(20_000);
        cf.setNioParams(nioParams);
        cf.useNio();
        return args -> {
            Message message = MessageBuilder.withBody(new byte[100_000])
                    .andProperties(MessagePropertiesBuilder.newInstance()
                            .setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT)
                            .build())
                    .build();
            while (true) {
                try {
                    template.send("foo", message);
                }
                catch (Exception e) {
                    logger.info(e.getMessage());
                }
            }

        };

    }

    @Bean
    public Queue foo() {
        return new Queue("foo");
    }

}

  

2018-02-09 12:00:29.803 INFO 9430 --- [main] com.example.So48699178Application:java.io.IOException:帧排队失败

     

2018-02-09 12:00:49.803 INFO 9430 --- [main] com.example.So48699178应用程序:java.io.IOException:帧排队失败

     

2018-02-09 12:01:09.807 INFO 9430 --- [main] com.example.So48699178应用程序:java.io.IOException:帧入队失败