我的容器化Java RabbitMQ使用者停止使用

时间:2018-04-09 07:45:59

标签: java docker spring-boot rabbitmq

我使用Spring Boot编写了一个Java RabbitMQ,并将其作为Docker容器进行了容器化。当我在MacBook上运行容器时,它可以很好地消耗所有排队的消息及其32个并发消费者。但是,当我部署相同的Docker镜像并在我们的生产服务器上运行时,它会在一段时间后停止使用。

enter image description here

上面的图片已经停止了。我已经将RabbitMQ客户端配置为使用32个并发消费者,预取计数为8,这解释了8 * 32 = 256个未经消息的消息。

listener:
  simple:
    concurrency: 32
    max-concurrency: 64
    prefetch: 8
    retry:
      enabled: true
      multiplier: 2
      max-attempts: 20
      stateless: true
      initial-interval: 1s
      max-interval: 30s
    acknowledge-mode: auto
    default-requeue-rejected: true

我可以确认cpu上没有任何负载,并且消费者实现并没有导致线程等到我所知。我也尝试将重试启用为false,看看是否有帮助,但它没有。

当我在MacBook上运行它时,它完全正常工作,在这种情况下我也在本地运行RabbitMQ图像。生产服务器在CentOS Linux release 7.4.1708 (Core)上运行,Docker Java容器的基本映像为openjdk:8-jre-alpine

生产服务器使用rabbitmq:3.7-management-alpine网络模式在其上托管RabbitMQ映像--net=host和Java容器化应用程序。还使用具有默认HTTP / HTTPS Web服务器配置的CSF防火墙配置生产服务器。

我还找到了答案,指的是服务器上允许的最大打开文件设置,但使用ulimit更改硬文件限制也没有任何效果。 Alpine docker容器的硬文件限制为1048576,因此应该足够了。在我的MacBook上,它是unlimited

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

事实证明问题不是由于RabbitMQ的内部工作,网络或文件描述符限制所致。

在使用SSH本地端口转发进行一些远程调试之后,证明在Docker容器内调用了SecureRandom.getInstanceStrong()罪魁祸首。显然,这无限期地阻止,没有进一步指示发生了什么。将其更改为new SecureRandom()会使问题消失。

这是我的Dockerfile进一步表明我的随机性来源:

FROM openjdk:8-jre-alpine
VOLUME /tmp
ADD libs/app-0.1.0.jar app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n", "-jar", "/app.jar"]

我认为使用SecureRandom.getInstanceStrong()会绕过urandom的使用并恢复为random,从而表现出阻止行为。关于/dev/./random/dev/./urandom之间差异的一些更有趣的读物可以在这里找到:http://www.thezonemanager.com/2015/07/whats-so-special-about-devurandom.html