我们有SpringBoot(1.5.4.RELEASE)控制器,它为内存中的GET请求提供服务,记录事实并发布到RMQ(RabbitTemplate.convertAndSend())。
我们按如下方式配置CachingConnectionFactory:
...
connectionFactory.setRequestedHeartBeat(240); //seconds
connectionFactory.setConnectionTimeout(600); //seconds
connectionFactory.setCacheMode(CacheMode.CHANNEL);
connectionFactory.setChannelCacheSize(32768);
...
我们提高了每个用户打开文件描述符和进程的限制,因此Tomcat可以轻松处理> 10 K并发请求。但是,当Tomcat的服务线程也必须发布到RMQ时,我们从CachingConnectionFactory获得“Channel shutdown:connection error”,然后RMQ客户端开始抛出:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:95)
at java.io.DataOutputStream.writeByte(DataOutputStream.java:153)
at com.rabbitmq.client.impl.Frame.writeTo(Frame.java:185)
at com.rabbitmq.client.impl.SocketFrameHandler.writeFrame(SocketFrameHandler.java:171)
at com.rabbitmq.client.impl.AMQConnection.writeFrame(AMQConnection.java:542)
at com.rabbitmq.client.impl.AMQCommand.transmit(AMQCommand.java:104)
at com.rabbitmq.client.impl.AMQChannel.quiescingTransmit(AMQChannel.java:337)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:313)
at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:686)
...
当apache bench用于触发> = 5000个并发请求时会发生这种情况。
我的问题是:
由于msg吞吐量(保持<200 msgs / s),但由于并发请求/ Tomcat发布者的数量庞大,这似乎没有中断。
如果不是让Tomcat线程直接发布到RMQ,而是首先写入内存队列,让几百个专门的RMQ发布者从那里开始,我不会遇到这样的问题,但团队担心在这种情况下会丢失消息所以必须与服务GET请求同步发布到RMQ。