我们正在从 IBM MQ 迁移到 Amazon MQ,至少我们愿意这样做。问题是,与 IBM MQ 相比,使用 JMS 生产者将大消息放入队列时,Amazon MQ 的性能较差。
对于 IBM MQ,所有消息都是持久的,系统是高可用的,而 Amazon MQ 是多可用区。
如果我们将这种大小的 XML 文件放入 IBM MQ(2 cpu 和 8GB RAM HA 实例),我们将获得以下性能:
256 KB = 15ms
4,6 MB = 125ms
9,3 MB = 141ms
18,7 MB = 218ms
37,4 MB = 628ms
74,8 MB = 1463ms
如果我们将相同的文件放在 Amazon MQ(mq.m5.2xlarge = 8 CPU 和 32 GB RAM)或 ActiveMQ 上,我们将获得以下性能:
256 KB = 967ms
4,6 MB = 1024ms
9,3 MB = 1828ms
18,7 MB = 3550ms
37,4 MB = 8900ms
74,8 MB = 14405ms
我们还看到,IBM MQ 向队列发送消息和从队列获取消息的响应时间相同,而 Amazon MQ 在获取消息方面非常快(例如只需要 1 毫秒),但在发送时非常慢.
在 Amazon MQ 上,我们使用 OpenWire 协议。我们以 Terraform 样式使用此配置:
resource "aws_mq_broker" "default" {
broker_name = "bernardamazonmqtest"
deployment_mode = "ACTIVE_STANDBY_MULTI_AZ"
engine_type = "ActiveMQ
engine_version = "5.15.10"
host_instance_type = "mq.m5.2xlarge"
auto_minor_version_upgrade = "false"
apply_immediately = "false"
publicly_accessible = "false"
security_groups = [aws_security_group.pittensbSG-allow-mq-external.id]
subnet_ids = [aws_subnet.pittensbSN-public-1.id, aws_subnet.pittensbSN-public-3.id]
logs {
general = "true"
audit = "true"
}
我们通过 POM (Maven) 将 Java 8 与 JMS ActiveMQ 库一起使用:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.15.8</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.8</version>
</dependency>
在 JMS 中,我们有以下 Java 代码:
private ActiveMQConnectionFactory mqConnectionFactory;
private PooledConnectionFactory mqPooledConnectionFactory;
private Connection connection;
private Session session;
private MessageProducer producer;
private TextMessage textMessage;
private Queue queue;
this.mqConnectionFactory = new ActiveMQConnectionFactory();
this.mqPooledConnectionFactory = new PooledConnectionFactory();
this.mqPooledConnectionFactory.setConnectionFactory(this.mqConnectionFactory);
this.mqConnectionFactory.setBrokerURL("ssl://tag-1.mq.eu-west-1.amazonaws.com:61617");
this.mqPooledConnectionFactory.setMaxConnections(10);
this.connection = mqPooledConnectionFactory.createConnection());
this.connection.start();
this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
this.session.createQueue("ExampleQueue");
this.producer = this.session.createProducer(this.queue);
long startTimeSchrijf = 0;
startTimeWrite= System.currentTimeMillis();
producer.send("XMLFile.xml"); // here we send the files
logger.debug("EXPORTTIJD_PUT - Put to queue takes: " + (System.currentTimeMillis() - startTimeWrite));
// close session, producer and connection after 10 cycles
我们还作为单实例 AmazonMQ 运行了性能测试。但同样的结果。我们还使用 mq.m5.4xlarge(16 cpu,96 GB RAM)引擎运行了性能测试,但仍然没有改善糟糕的性能。
性能测试配置:我们首先将上述消息(XML文件)一个一个地推送到队列中。我们这样做了 5 次。5 次后,我们从队列中读取这些消息(XML 文件)。我们称之为 1 个周期。
我们一个接一个地运行 10 个周期,因此我们总共将 300 个文件推送到队列中,并且从队列中获取了 300 个文件。
我们并行运行 3 项测试:一项来自 AWS 地区伦敦,一项来自 AWS 地区法兰克福,位于不同的 VPC 中,1 项来自法兰克福,位于与 Amazon MQ 代理相同的 VPC 中且位于同一子网中。所有客户端都在 EC2 实例上运行:m4.xlarge。
如果我们仅使用一个 VPC 运行测试,例如仅与 AmazonMQ 代理位于同一子网中的本地 VPC,则性能会提高,我们会得到以下结果:
256 KB = 72ms
4,6 MB = 381ms
9,3 MB = 980ms
18,7 MB = 2117ms
37,4 MB = 3985ms
74,8 MB = 7781ms
客户端和服务器在同一个子网中,所以我们与防火墙等无关。
也许有人可以告诉我哪里出了问题,为什么我们的 Amazon MQ 或 ActiveMQ 性能如此糟糕?
额外信息:响应时间在 JMS Java 应用程序中测量,Java 开始时间在 producer.send('XML') 之前,结束时间在 producer.send('XML') 之后。差异是记录的时间。时间是超过 300 次呼叫的平均时间。
IBM MQ 服务器位于我们的数据中心,客户端应用程序在同一数据中心的服务器上运行。
额外信息测试:jms 应用程序开始创建 connectionFactory 队列会话。然后它将文件逐个上传到 MQ 1。这是一个循环,然后它在 for lus 中运行此循环 10 次,而不打开或关闭会话队列或连接工厂。然后从队列中读取所有 60 条消息并写入本地驱动器上的文件。然后它关闭连接工厂和会话以及生产者/消费者。这是一批。然后我们运行 5 个批次。因此在批次之间重新创建连接工厂、队列、会话。
作为对 Sam 的回应:当我也像 Sam 一样使用相同大小的文件执行测试时,我接近相同的响应时间,我将持久性模式也设置为 () 之间的 false 值:
500 KB = 30ms (6ms)
1 MB = 50ms (13ms)
2 MB = 100ms (24ms)
我删除了连接池并设置了 concurrentStoreAndDispatchQueues="false" 我使用的系统是代理:mq.m5.2xlarge 和客户端:m4.xlarge。
但如果我用更大的文件进行测试,这是响应时间:
256 KB = 72ms
4,6 MB = 381ms
9,3 MB = 980ms
18,7 MB = 2117ms
37,4 MB = 3985ms
74,8 MB = 7781ms
我有一个非常简单的要求。我有一个系统,它将消息放在队列中,并且消息是由另一个系统从队列中获取的,有时同时有时不是,有时系统上有 20 或 30 条消息在它们被卸载之前。这就是为什么我需要一个队列并且消息必须是持久的并且它必须是 Java JMS 实现。
我认为 Amazon MQ 可能是小文件的解决方案,但对于大文件却不是。我认为我们必须在这种情况下使用 IBM MQ,它具有更好的性能。但有一件重要的事情:我只在我们的 LAN 中测试了 IBM MQ。我们尝试在 Amazon 上测试 IBM MQ,但尚未成功。