【发布时间】:2020-07-06 05:52:24
【问题描述】:
我们正在从 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 个批次。所以在批次之间重新创建connectionFactory、queue、session。
回复山姆: 当我也像 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,但尚未成功。
【问题讨论】:
-
这是一个非常好的问题,能否请您详细说明您对它进行基准测试的方式(测量什么?测量时间的开始和结束时间?这些平均时间是一条消息还是整个消息?批处理?),以及 IBM MQ 实例位于何处?它在您的本地网络中吗?此外,在您的测试中,您是在发送的每个文件上打开一个连接,还是在同一连接中推送/拉取 300 个文件?抱歉,我要求进行大量改进,但如果您使用这些详细信息更新您的问题,将会很有帮助。
-
感谢 Anton 的回复,我已经更新了回答您问题的请求