RabbitMQ性能调优测试(2)

接着昨天的说,我们启一个生产者一个消费者,这个时候会影响整个mq的收发效果,现在我们把业务的处理时间算进来,模拟处理一条消息需要10ms没看看是什么效果

测试七:

测试内容:

启动一个产者,一个消费者,Qos为10.默认Ack,接收到消息休眠10ms,用来模拟业务的处理时间

配置:

1
2
3
4
5
6
private static int producterConnection_size = 1; //消息生产者连接数
private static int consumerConnection_size = 1; //消费者连接数
private static final int consumer_size = 1;//每个消费者连接里面开启的consumer数量
private static int qos = 10; //Qos设置
private static long sleep_time = 10; //模拟每条消息的处理时间
private static boolean autoAck = true; //是否默认Ack

结果:

这里consume的性能急剧下降,只有100msg/s左右,计算一下1000ms/10ms=100msg/s,由于是单消费者处理,这个值也是合理的值,不过消费速率下来,生产速率飚上去了直逼15k/s,当然也是触发了流控.

现在问题来了,我们当然不能这样用MQ,需要加大消费速率,无非就是并行处理消息,那我们加大consumer的数量.

测试八:

测试内容:

启动一个产者,10个消费者,Qos为100(原因是可以计算出如果提前缓存消息的话,可以叠加网络传输的开销).默认Ack,接收到消息休眠10ms,用来模拟业务的处理时间

配置:

1
2
3
4
5
6
private static int producterConnection_size = 1; //消息生产者连接数
private static int consumerConnection_size = 1; //消费者连接数
private static final int consumer_size = 10;//每个消费者连接里面开启的consumer数量
private static int qos = 100; //Qos设置
private static long sleep_time = 10; //模拟每条消息的处理时间
private static boolean autoAck = true; //是否默认Ack

结果:

看来效果很明显,消费峰值也达到了1k多,但是大部分时间都是在850msg/s的性能,这说明一味的增加channel开启consumer应该是有瓶颈的,随着consumer的增加,消费效率应该也不会有太大的增加,接着测试

测试九:

测试内容:

启动一个产者,30个消费者,Qos为100.默认Ack,接收到消息休眠10ms,用来模拟业务的处理时间

配置:

1
2
3
4
5
6
private static int producterConnection_size = 1; //消息生产者连接数
private static int consumerConnection_size = 1; //消费者连接数
private static final int consumer_size = 30;//每个消费者连接里面开启的consumer数量
private static int qos = 100; //Qos设置
private static long sleep_time = 10; //模拟每条消息的处理时间
private static boolean autoAck = true; //是否默认Ack

结果:

折线图波动有点大,还是看日志输出比较准确
)

从结果来看,consumer增加了三倍,但是消费速率基本在1400左右,感觉要到瓶颈了.后面我尝试过consumer_size=50,也是这个值,直到consumer_size=17的时候就是1400/s,再增加consumer也不会增加效率了.

从数据上来看感觉是一个连接里面channel有一个上限值,再多也处理不完了,那可以考虑尝试增加connection来试试是否能够增加消费能力

测试10:

测试内容:

启动一个产者,3个连接,每个连接里面创建17个消费者,Qos为100.默认Ack,接收到消息休眠10ms,用来模拟业务的处理时间

配置:

1
2
3
4
5
6
private static int producterConnection_size = 1; //消息生产者连接数
private static int consumerConnection_size = 3; //消费者连接数
private static final int consumer_size = 17;//每个消费者连接里面开启的consumer数量
private static int qos = 100; //Qos设置
private static long sleep_time = 10; //模拟每条消息的处理时间
private static boolean autoAck = true; //是否默认Ack

结果:

折线图波动有点大,还是看日志输出比较准确
)

这回性能有了很大的提升,基本上4k+/s的消费能力,这样一来可以说明单个connection的channel还是有上限限制的,不能随意的增加channel来处理数据,

另外,也看到publish也对应的下降了,mq的流控还在继续,继续加大连接数看看结果

测试11:

测试内容:

启动一个产者,10个连接,每个连接里面创建17个消费者,Qos为100.默认Ack,接收到消息休眠10ms,用来模拟业务的处理时间

配置:

1
2
3
4
5
6
private static int producterConnection_size = 1; //消息生产者连接数
private static int consumerConnection_size = 3; //消费者连接数
private static final int consumer_size = 17;//每个消费者连接里面开启的consumer数量
private static int qos = 100; //Qos设置
private static long sleep_time = 10; //模拟每条消息的处理时间
private static boolean autoAck = true; //是否默认Ack

结果:

折线图波动有点大,还是看日志输出比较准确

终于达到了想要心理上的效果,但是生产者被打压得非常厉害才100msg/s,这里需要注意的生产者的代码里面需要有应对流控的处理,否则在这种情况下,系统会出现大量的延迟和超时.

由于mq上有4000万数据的积压,为了验证在没有积压的情况下会不会导致严重的生产者流控,先把Queue删除掉,再跑一次测试11,看看结果:

可以看出来生产出来的消息马上就能被消费掉.这个是在170个消费者对应1个生产者.
我也将生产者增加到3各,这个时候生产个消费能力都到达到了12000~13000/s的性能,这里就补贴图出来了

那有人会说了,如果生产的消息不堆积的话,是不是就不用开启那么多连接了,只需要17个消费者就可以了,我没做这个实验,但是我觉得做了测试也没多大意思,毕竟业务的运行过程中中有一定几率会产生消息堆积,总不可能在堆积的时候再去调整参数,所以我们只考虑堆积的时候能够快速的吧消息消费掉,当然spring对rabbitmq的封装里面对consumer进行了池化,会随着消费压力自动变化,只要设置到最大的consumer个数就好了.

总结

通过以上的测试,我们基本上得出以下几个结论:

>
1.生产者生产消息过快,无论是否有消费者,都会触发流控,不同的是流控强度随消费者个数加强.
2.一旦有消费者连接,就会对生产者的消息生产效率产生影响(在触发流控之后)
3.在每个连接里面在创建相应数量的consumer,可以增加消费能力,但是也是有上限的,我的测试中上限是17
4.创建多个连接,并且每个每个连接里面consumer设置到上限数量,可以进一步增加消费能力
5.在消息堆积的情况下,消费者数量与生产者的生产效率成反比
6.在没有消息堆积的情况下,设置得当的话,基本上可以做到生产与消费同步(测试的最大值为13000+/s,加大连接数可能还会提高)

坚持原创技术分享,您的支持将鼓励我继续创作!