ActiveMQ性能优化(中1)(处理规则和优化)

  1. Producer既是消息生产者,作为一个发送消息的客户端它既可以使用同步消息发送模式,也可以使用异步的消息发送模式。另外,消息生产者在ActiveMQ服务节点产生消息堆积的情况下,也不能一味的追求发送效率。还好,这种情况下消息生产者端有完整的保证机制——Slow Producer。另外,JMS提供事务功能,所以生产者是否开启事务发送消息,将会影响消息发送性能;
  2. 在整个消息处理规则中,ActiveMQ服务节点最极端的情况就是产生消息堆积(消息的消费速度持续低于消息生成速度,就会出现消息堆积)。那么ActiveMQ服务节点处理网络IO模型的优化外,最大的优化点就是:如何应对消息堆积。基本原则是:NON_PERSISTENT Message在内存堆积后,转储到Temp Store区域(当然也可以设置为不转储);PERSISTENT Meaage无论怎样都会先使用持久化方案存储到永久存储区域,再视情况决定是否进行发送;在这些区域也产生堆积后,通知消息生产者使用Slow Producer机制;
  3. ActiveMQ服务节点在成功完成PERSISTENT Meaage的持久存储操作后,就会向消息生产者发送一个确认信息,表示该条消息已处理完成。如果ActiveMQ服务节点接受的是NON_PERSISTENT Message,那么生产者默认情况下不会等待服务节点的回执。我们后续会介绍PERSISTENT Meaage的发送也可以设置为不等待回执,这样可以显著提高生产端的消息发送效率;
  4. ActiveMQ服务节点会以一种设置好的策略将消息发送给消费者,这个策略的原则是ActiveMQ服务节点主动推送消息给某一个消费者(不是消费者主动拉取),这样的方式很好便于ActiveMQ服务节点占据整个策略的领导地位。在这个策略中,最重要的属性是prefetchSize:单次获得的消息数量。除此以外,消费者端也是可以调整IO网络模型;
  5. 消费者在获得到消息后,就可以根据这条消息进行业务处理了。最后,消费者需要按照处理结果向ActiveMQ服务节点告知这条(或这些)消息是否处理成功——ACK应答。ActiveMQ中有多种ACK应答方式,它们对性能的影响也不相同。通过这些描述可以看出,消费者的处理性能更能直接影响整个ActiveMQ系统的性能。因为消费者不仅要接受消息、处理消息还要返回消息应答。所以如果您的业务有一定的复杂性,造成每一条消息的处理都会消耗相当的处理时间,那么最直接的性能改善方式就是采用多个消费者节点。
生产者策略 1、生产者策略:Send
消息生产者发送的消息主要分为两种类型:发送PERSISTENT Meaage和发送NON_PERSISTENT Message。
1.1、发送NON_PERSISTENT Message 默认情况下,ActiveMQ服务端认为生产者端发送的是PERSISTENT Message。所以如果要发送NON_PERSISTENT Message,那么生产者端就要明确指定。以下语句明确指定消息发送者将要发送NON_PERSISTENT Message:
...... // 设置发送者发送的是NON_PERSISTENT Message MessageProducer sender = session.createProducer(sendQueue); sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); ......

发送NON_PERSISTENT Message时,消息发送方默认使用异步方式:即是说消息发送后发送方不会等待NON_PERSISTENT Message在服务端的任何回执。那么问题来了:如果这时服务端已经出现了消息堆积,并且堆积程度已经达到“无法再接收新消息”的极限情况了,那么消息发送方如何知晓并采取相应的策略呢?
实际上所谓的异步发送也并非绝对的异步,消息发送者会在发送一定大小的消息后等待服务端进行回执(这个配置只是针对使用异步方式进行发送消息的情况):
...... // 以下语句设置消息发送者在累计发送102400byte大小的消息后(可能是一条消息也可能是多条消息) // 等待服务端进行回执,以便确定之前发送的消息是否被正确处理 // 确定服务器端是否产生了过量的消息堆积,需要减慢消息生产端的生产速度 connectionFactory.setProducerWindowSize(102400); ......

如果您使用的是异步发送方式,那么必须通过这个以上代码指明回执点。例如发送NON_PERSISTENT Message时,这时消息发送者默认使用异步方式。那么如果您想在发送NON_PERSISTENT Message时,每次都等待消息回执,又该如何设置呢?您可以使用connectionFactory提供的“alwaysSyncSend”设置来指定每次都等待服务端的回执:
...... // 设置成:无论怎样每次都等待服务器端的回执 // 但关键是您确定自己的业务需求真的需要这样使用吗? connectionFactory.setAlwaysSyncSend(true); ......

1.2、发送PERSISTENT Message 如果您不特意指定消息的发送类型,那么消息生产者默认发送PERSISTENT Meaage。这样的消息发送到ActiveMQ服务端后将被进行持久化存储(持久化存储方案将在后文进行详细介绍),并且消息发送者默认等待ActiveMQ服务端对这条消息处理情况的回执。
以上这个过程非常耗时,ActiveMQ服务端不但要接受消息,在内存中完成存储,并且按照ActiveMQ服务端设置的持久化存储方案对消息进行存储(主要的处理时间耗费在这里)。为了提高ActiveMQ在接受PERSISTENT Meaage时的性能,ActiveMQ允许开发人员遵从JMS API中的设置方式,为消息发送端在发送PERSISTENT Meaage时提供异步方式:
...... // 使用异步传输 // 上文已经说过,如果发送的是NON_PERSISTENT Message // 那么默认就是异步方式 connectionFactory.setUseAsyncSend(true); ......

一旦您进行了这样的设置,就需要设置回执窗口:
...... // 同样设置消息发送者在累计发送102400byte大小的消息后 // 等待服务端进行回执,以便确定之前发送的消息是否被正确处理 // 确定服务器端是否产生了过量的消息堆积,需要减慢消息生产端的生产速度 connectionFactory.setProducerWindowSize(102400); ......
posted @ 2023-02-09 14:00  疯子110  阅读(260)  评论(0编辑  收藏  举报