
# 测试RabbitMQ生产速率和消费速率
本章节从实例规格、是否开启SSL、生产者/消费者数量、队列数量、队列类型、Exchange类型的维度进行分布式消息服务RabbitMQ版的性能测试，对比客户端消息生产速率和消费速率，得出性能测试结果。
- 测试场景一（实例规格）：相同Exchange、队列、生产者数量、消费者数量、不同的实例规格
- 测试场景二（是否开启SSL）：相同Exchange、队列、生产者数量、消费者数量、实例规格，开启SSL和未开启SSL的实例
- 测试场景三（生产者/消费者数量）：相同Exchange、队列、实例规格，不同数量的生产者和消费者
- 测试场景四（单队列和多队列）：相同Exchange、生产者数量、消费者数量、实例规格，不同的队列数量
- 测试场景五（队列类型）：相同Exchange、生产者数量、消费者数量、实例规格，不同的队列类型
- 测试场景六（Fanout Exchange）：相同实例规格、Fanout Exchange、队列数量，不同生产者数量、消费者数量
![](https://support.huaweicloud.com/usermanual-rabbitmq/public_sys-resources/note_3.0-zh-cn.png)
由于网络环境的影响和客户端的不同，测试结果可能会有差异。
#### 测试环境
进行性能测试前，您需要先构建如下的测试环境：
1. 购买如[表1]所示RabbitMQ 3.8.35版本的集群实例，购买方法请参考[购买RabbitMQ实例](https://support.huaweicloud.com/usermanual-rabbitmq/rabbitmq-ug-180604004.html)。
   ![](https://support.huaweicloud.com/usermanual-rabbitmq/public_sys-resources/caution_3.0-zh-cn.png)
   - 设置连接**RabbitMQ密码** 时，建议**不要使用特殊字符**。如果使用特殊字符，在使用测试脚本时，需要对特殊字符进行转义处理，否则会报错。
   
   - 购买"rabbitmq-2u4g"实例时，请**开启公网访问** ，并在安全组中入方向规则中**放通15672端口**，以便在浏览器中访问WebUI界面。
    
    表1实例参数 
   | 名称              | 代理数量 | 规格                      | 是否开启SSL | 磁盘类型  |
   |:---|:---|:---|:---|:---|
   | rabbitmq-ssl    | 3    | rabbitmq.2u4g.cluster   | 是       | 超高I/O |
   | rabbitmq-2u4g   | 3    | rabbitmq.2u4g.cluster   | 否       | 超高I/O |
   | rabbitmq-4u8g   | 3    | rabbitmq.4u8g.cluster   | 否       | 超高I/O |
   | rabbitmq-8u16g  | 3    | rabbitmq.8u16g.cluster  | 否       | 超高I/O |
   | rabbitmq-16u32g | 3    | rabbitmq.16u32g.cluster | 否       | 超高I/O |
      
   购买完成后，在实例详情页获取RabbitMQ实例的内网连接地址，并记录购买实例时设置的用户名和密码。如果是"rabbitmq-2u4g"实例，除了内网连接地址、用户名和密码外，还需要记录Web界面UI地址，此地址在后续登录WebUI界面设置镜像队列和惰性队列时需要使用。
   ![](https://support.huaweicloud.com/usermanual-rabbitmq/zh-cn_image_0000002017098405.png)
   
2. 在"rabbitmq-2u4g"实例中，[登录WebUI](https://support.huaweicloud.com/usermanual-rabbitmq/rabbitmq-ug-180801003.html)，并设置[镜像队列](https://support.huaweicloud.com/usermanual-rabbitmq/rabbitmq-ug-200219001.html)、[惰性队列](https://support.huaweicloud.com/usermanual-rabbitmq/rabbitmq_ug_0009.html)和[仲裁队列](https://support.huaweicloud.com/usermanual-rabbitmq/rabbitmq_ug_0016.html)。
3. 在"rabbitmq-2u4g"实例的"/"Vhost下，创建"fanout"类型的Exchange，具体步骤请参考[创建RabbitMQ Exchange](https://support.huaweicloud.com/usermanual-rabbitmq/rabbitmq_ug_0027.html)。
4. 获取测试工具[rabbitmq-perf-test-2.18.0-bin.tar.gz](https://github.com/rabbitmq/rabbitmq-perf-test/releases/download/v2.18.0/rabbitmq-perf-test-2.18.0-bin.tar.gz)。
5. 购买客户端服务器。 购买区域、可用区、虚拟私有云、子网、安全组与RabbitMQ实例保持一致，规格为16U32G，Linux系统的ECS服务器，具体步骤请参考[购买弹性云服务器](https://support.huaweicloud.com/usermanual-ecs/ecs_03_7002.html)。
   购买完成ECS后，需要在ECS中完成以下配置：
   - 安装[Java JDK](https://www.oracle.com/java/technologies/javase-downloads.html)，并配置JAVA_HOME与PATH环境变量。
     ```
     export JAVA_HOME=/root/jdk1.8.0_231 
     export PATH=$JAVA_HOME/bin:$PATH
     ```
     
   
   - 下载[rabbitmq-perf-test-2.18.0-bin.tar.gz](https://github.com/rabbitmq/rabbitmq-perf-test/releases/download/v2.18.0/rabbitmq-perf-test-2.18.0-bin.tar.gz)，并解压。
     ```
     tar -zxvf rabbitmq-perf-test-2.18.0-bin.tar.gz
     ```
     
    
 
#### 测试脚本
![](https://support.huaweicloud.com/usermanual-rabbitmq/public_sys-resources/caution_3.0-zh-cn.png)
- 测试脚本自动创建的Exchange类型为"**direct** "，队列特性为**非持久化、自动删除** ，在测试fanout类型Exchange和仲裁队列时，需要在脚本后增加"**--predeclared**"，表示使用自己定义的Exchange和队列参数。
- 测试**开启SSL的实例** 时，需要将"**amqp://** "修改为"**amqps://**"，表示以加密形式传输数据。
 
**单队列测试脚本：**
```
./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -u {队列名称} -x {生产者个数} -y {消费者个数} -z {运行时间}
```
表2测试脚本参数说明 
| 参数名称       | 说明                                                     |
|:---|:---|
| 实例用户名      | [购买实例]时设置的用户名。    |
| 实例密码       | [购买实例]时设置的密码。     |
| 内网连接地址     | [购买实例]后获取的内网连接地址。 |
| Exchange名称 | 待测试的Exchange名称。                                        |
| 队列名称       | 待测试的队列名称。                                              |
| 生产者个数      | 生产者的数量。                                                |
| 消费者个数      | 消费者的数量。                                                |
| 运行时间       | 脚本的运行时间，单位为秒。                                          |
   
**多队列测试脚本：**
```
./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -x {生产者个数} -y {消费者个数} -z {运行时间} --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to x
```
表3测试脚本参数说明 
| 参数名称       | 说明                                                                                                                                                                                                                                 |
|:---|:---|
| 实例用户名      | [购买实例]时设置的用户名。                                                                                                                                                                                |
| 实例密码       | [购买实例]时设置的密码。                                                                                                                                                                                 |
| 内网连接地址     | [购买实例]后获取的内网连接地址。                                                                                                                                                                             |
| Exchange名称 | 待测试的Exchange名称。                                                                                                                                                                                                                    |
| 生产者个数      | 生产者的数量。                                                                                                                                                                                                                            |
| 消费者个数      | 消费者的数量。                                                                                                                                                                                                                            |
| 运行时间       | 脚本的运行时间，单位为秒。                                                                                                                                                                                                                      |
| queue-%d   | 表示多个队列，队列名称前缀为queue-，%d表示变量，取值为从--queue-pattern-from数值到--queue-pattern-to数值的连续整数。 例如：--queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to 3，表示3个队列，队列名称为queue-1、queue-2、queue-3。 |
   
#### 测试步骤
1. 登录客户端服务器，进入"rabbitmq-perf-test-2.18.0/bin"目录下。
2. 运行以下脚本，测试并记录不同实例规格下的生产速率和消费速率。 
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -u {队列名称} -x 3 -y 3 -z 300
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-direct -s 1024 -u queue-1 -x 3 -y 3 -z 300
   ```
   
   
3. 运行以下脚本，测试并记录rabbitmq-ssl实例在不同生产者数量、消费者数量、队列数量的生产速率和消费速率。 
   **单队列** 测试脚本：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqps://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -u {队列名称} -x {生产者个数} -y {消费者个数} -z 300
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqps://test:******@192.168.0.150:5671 -e exchange-direct -s 1024 -u queue-1 -x 1 -y 1 -z 300
   ```
   **多队列**测试脚本：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqps://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -x 3 -y 3 -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to x
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqps://test:******@192.168.0.150:5671 -e exchange-direct -s 1024 -x 3 -y 3 -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to 3
   ```
   
   
4. 运行以下脚本，测试并记录rabbitmq-2u4g实例在不同生产者数量、消费者数量、队列数量的生产速率和消费速率。 
   **单队列** 测试脚本：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -u {队列名称} -x {生产者个数} -y {消费者个数} -z 300
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-direct -s 1024 -u queue-1 -x 1 -y 1 -z 300
   ```
   **多队列**测试脚本：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -x {生产者个数} -y {消费者个数} -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to x
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-direct -s 1024 -x 3 -y 3 -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to 3
   ```
   
   
5. 运行以下脚本，测试并记录rabbitmq-2u4g实例在不同生产者数量、消费者数量、队列数量、队列类型的生产速率和消费速率，其中队列类型分别为"惰性"、"镜像"和"仲裁"。 
   **单队列** 测试脚本（不包括仲裁队列）：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -u {队列名称} -x {生产者个数} -y {消费者个数} -z 300
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-direct -s 1024 -u queue-1 -x 1 -y 1 -z 300
   ```
   **多队列**测试脚本（不包括仲裁队列）：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -x {生产者个数} -y {消费者个数} -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to x
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-direct -s 1024 -x 3 -y 3 -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to 3
   ```
   **单队列** 测试脚本（仲裁队列）：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -u {队列名称} -x {生产者个数} -y {消费者个数} -z 300 --predeclared
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-direct -s 1024 -u queue-1 -x 1 -y 1 -z 300 --predeclared
   ```
   **多队列**测试脚本（仲裁队列）：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -x {生产者个数} -y {消费者个数} -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to x --predeclared
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-direct -s 1024 -x 3 -y 3 -z 300 --queue-pattern 'queue-%d' --queue-pattern-from 1 --queue-pattern-to 3 --predeclared
   ```
   
   
6. 运行以下脚本，测试并记录rabbitmq-2u4g实例的Fanout Exchange在不同消费者数量、队列数量的生产速率和消费速率。 
   **单队列**测试脚本：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://{实例用户名}:{实例密码}@{内网连接地址} -e {Exchange名称} -s 1024 -u {队列名称} -x {生产者个数} -y {消费者个数} -z 300 --predeclared
   ```
   示例如下：
   ```
   ./runjava com.rabbitmq.perf.PerfTest -h amqp://test:******@192.168.0.150:5672 -e exchange-fanout -s 1024 -u queue-1 -x 1 -y 3 -z 300 --predeclared
   ```
   
   
 
#### 测试结果
以下介绍六个测试场景对应的测试结果。
#### 测试场景一（实例规格）：相同Exchange、队列、生产者数量、消费者数量、不同的实例规格
**测试参数如下：**
- Exchange：类型为"direct"，非持久化，不会自动删除。
- 队列：类型"经典队列"，数量为"3"，非持久化，会自动删除。
- 生产者：数量为"3"。
- 消费者：数量为"3"。
表4测试结果 
| 实例规格                    | 磁盘类型  | 代理数量 | 生产速率  | 消费速率  |
|:---|:---|:---|:---|:---|
| rabbitmq.2u4g.cluster   | 超高I/O | 3    | 32052 | 25219 |
| rabbitmq.4u8g.cluster   | 超高I/O | 3    | 53774 | 47370 |
| rabbitmq.8u16g.cluster  | 超高I/O | 3    | 54727 | 45730 |
| rabbitmq.16u32g.cluster | 超高I/O | 3    | 66896 | 51061 |
   
通过上表的测试结果，得出以下结论，仅供参考：**实例规格越大，实例性能越高** **。**
#### 测试场景二（是否开启SSL）：相同Exchange、队列、生产者数量、消费者数量、实例规格，开启SSL和未开启SSL的实例
**测试参数如下：**
- 实例规格：rabbitmq.2u4g.cluster\*3。
- Exchange：类型为"direct"，非持久化，不会自动删除。
- 队列：类型"经典队列"，非持久化，会自动删除。
表5测试结果 
| 是否开启SSL | 生产者数量 | 消费者数量 | 队列数量 | 生产速率  | 消费速率  |
|:---|:---|:---|:---|:---|:---|
| 是       | 1     | 1     | 1    | 7631  | 6291  |
| 否       | 1     | 1     | 1    | 17104 | 17091 |
| 是       | 3     | 3     | 1    | 21819 | 21819 |
| 否       | 3     | 3     | 1    | 26050 | 26050 |
| 是       | 6     | 6     | 1    | 19617 | 19617 |
| 否       | 6     | 6     | 1    | 24720 | 24720 |
| 是       | 1     | 3     | 1    | 13909 | 13909 |
| 否       | 1     | 3     | 1    | 18732 | 18732 |
| 是       | 1     | 6     | 1    | 20006 | 20006 |
| 否       | 1     | 6     | 1    | 20371 | 20371 |
| 是       | 3     | 1     | 1    | 7537  | 5472  |
| 否       | 3     | 1     | 1    | 28743 | 28743 |
| 是       | 6     | 1     | 1    | 7813  | 5310  |
| 否       | 6     | 1     | 1    | 26663 | 26662 |
| 是       | 3     | 3     | 3    | 32052 | 25219 |
| 否       | 3     | 3     | 3    | 39951 | 37790 |
| 是       | 3     | 3     | 6    | 32972 | 26440 |
| 否       | 3     | 3     | 6    | 38686 | 37464 |
| 是       | 3     | 3     | 10   | 31778 | 25375 |
| 否       | 3     | 3     | 10   | 39809 | 37912 |
   
通过上表的测试结果，得出以下结论，仅供参考：**使用SSL连接RabbitMQ实例可以提供更高的安全性，但是生产速率和消费速率明显下降。**建议使用更高规格的资源以弥补SSL加密解密带来的性能开销。合理的增加生产者数量、消费者数量和队列数，可以缓解SSL连接带来的性能下降。
#### 测试场景三（生产者/消费者数量）：相同Exchange、队列、实例规格，不同数量的生产者和消费者
**测试参数如下：**
- 实例规格：rabbitmq.2u4g.cluster\*3。
- Exchange：类型为"direct"，非持久化，不会自动删除。
- 队列：类型"经典队列"，数量"1"，非持久化，会自动删除。
表6测试结果 
| 生产者数量 | 消费者数量 | 生产速率  | 消费速率  |
|:---|:---|:---|:---|
| 1     | 1     | 17104 | 17091 |
| 3     | 3     | 26050 | 26050 |
| 6     | 6     | 24720 | 24720 |
| 1     | 3     | 18732 | 18732 |
| 1     | 6     | 20371 | 20371 |
| 3     | 1     | 28743 | 28743 |
| 6     | 1     | 26663 | 26662 |
   
通过上表的测试结果，得出以下结论，仅供参考：**适量增加生产者数量和消费者数量，可以提高生产速率和消费速率。**在本测试中，1个消费者时，3个生产者的生产速率最高，当生产者增加到6个，生产速率略微下降，这是由于资源竞争和内存高水位会导致性能瓶颈。
#### 测试场景四（单队列和多队列）：相同Exchange、生产者数量、消费者数量、实例规格，不同的队列数量
**测试参数如下：**
- 实例规格：rabbitmq.2u4g.cluster\*3。
- Exchange：类型为"direct"，非持久化，不会自动删除。
- 队列：类型"经典队列"，非持久化，会自动删除。
表7测试结果 
| 生产者数量 | 消费者数量 | 队列数量 | 生产速率  | 消费速率  |
|:---|:---|:---|:---|:---|
| 3     | 3     | 1    | 26050 | 26050 |
| 3     | 3     | 3    | 39951 | 37790 |
| 3     | 3     | 6    | 38686 | 37464 |
| 3     | 3     | 10   | 39809 | 37912 |
| 6     | 6     | 1    | 24720 | 24720 |
| 6     | 6     | 10   | 54768 | 45847 |
   
通过上表的测试结果，得出以下结论，仅供参考：**在生产者数量和消费者数量相同时，多队列的生产效率和消费效率高于单队列。**这是由于队列之间的负载均衡减少了单个队列的压力，提高了消息处理效率。
#### 测试场景五（队列类型）：相同Exchange、生产者数量、消费者数量、实例规格，不同的队列类型
**测试参数如下：**
- 实例规格：rabbitmq.2u4g.cluster\*3。
- Exchange：类型为"direct"，非持久化，不会自动删除。
- 队列：经典队列、惰性队列和镜像队列设置为非持久化，会自动删除。仲裁队列设置为持久化、不会自动删除。
表8测试结果 
| 生产者数量 | 消费者数量 | 队列数量 | 队列类型 | 生产速率  | 消费速率  |
|:---|:---|:---|:---|:---|:---|
| 3     | 3     | 1    | 经典   | 26050 | 26050 |
| 3     | 3     | 1    | 惰性   | 12291 | 12291 |
| 3     | 3     | 1    | 镜像   | 16513 | 16100 |
| 3     | 3     | 1    | 仲裁   | 6771  | 15568 |
| 3     | 3     | 10   | 经典   | 39809 | 37912 |
| 3     | 3     | 10   | 惰性   | 30543 | 29991 |
| 3     | 3     | 10   | 镜像   | 11130 | 8220  |
| 3     | 3     | 10   | 仲裁   | 52466 | 51772 |
| 6     | 6     | 1    | 经典   | 24720 | 24720 |
| 6     | 6     | 1    | 惰性   | 9934  | 8728  |
| 6     | 6     | 1    | 镜像   | 16000 | 14888 |
| 6     | 6     | 1    | 仲裁   | 6318  | 26841 |
| 6     | 6     | 10   | 经典   | 54768 | 45847 |
| 6     | 6     | 10   | 惰性   | 42556 | 33994 |
| 6     | 6     | 10   | 镜像   | 54625 | 45853 |
| 6     | 6     | 10   | 仲裁   | 47133 | 41011 |
   
通过上表的测试结果，得出以下结论，仅供参考：
- 惰性队列：**惰性队列性能低于经典队列** **，增加队列数后，性能明显提高。**
- 镜像队列：**镜像队列的生产速率低于经典队列**，因为在每次发布消息时，镜像队列需要将消息复制到所有镜像节点，过程中增加了网络传输和节点处理的负担。
- 仲裁队列：**单队列时，消费速率高于生产速率，** 可能是因为仲裁队列需要在每次写入时进行一致性检查，从而影响了生产速率。**多队列时，相比于单队列生产速率和消费速率明显提高，**适合高一致性和高并发场景。
 
#### 测试场景六（Fanout Exchange）：相同实例规格、Fanout Exchange、队列数量，不同生产者数量、消费者数量
**测试参数如下：**
- 实例规格：rabbitmq.2u4g.cluster\*3。
- Exchange：类型为"fanout"，非持久化，不会自动删除。
- 队列：类型"经典队列"，数量"1"，非持久化，会自动删除。
表9测试结果 
| 生产者数量 | 消费者数量 | 生产速率  | 消费速率  |
|:---|:---|:---|:---|
| 1     | 1     | 17233 | 17232 |
| 3     | 3     | 35539 | 35231 |
| 6     | 6     | 32635 | 31682 |
| 1     | 3     | 27864 | 27864 |
| 1     | 6     | 31518 | 31518 |
   
通过上表的测试结果，得出以下结论，仅供参考：**适量增加生产者数量和消费者数量，可以提高生产速率和消费速率** **。**
