第十二章 ActiveMQ性能调优

           第十二章 ActiveMQ性能调优

章节导读

 

  •  学习调优技术
  •    如何优化生产者和消费者
  •    一个优化的实例

      ActiveMQ的性能高度依赖于许多不同的因素,包括代理网络的拓扑结构,传输连接器,网络的速度和服务质量,硬件,操作系统以及Java虚拟机.

     但是不管在什么应用环境下,你都可以使用一些性能调优技术以改善ActiveMQ性能.也许你的程序不需要确保消息能够准确投送,这时使用可靠的,非持久化消息会有更好的性能.对于减少消息在传输路劲中的序列化次数来说,使用嵌入式代理是很合理的.另外,可以使用大量的调优参数,它们有各自的优点和使用注意事项.

 

 12.1 ActiveMQ通用调优技术

      

         有两种简单方式可以提升JMS消息性能:使用非持久化消息,或者在需要确保消息发送成功时使用事务来将消息分批组合.通常不考虑使用非持久化消息分发除非你不在乎消息可能会丢失(比如,一个实时的数据源,因为状态数据在很短的时间内会重复发送),并且使用事务将消息分批也不总是可行的.但是ActiveMQ为非持久化的消息分发采用了失效安全策略,因此只有灾难性的失败才会导致消息丢失.本节中我们将解释为什么非持久化消息和消息分批会更快,以及为什么在不需要绝对保证消息不会丢失的情况下,可以将它们可应用在你的程序中.

 

       12.1.1 持久化消息 VS 非持久化消息

       JMS规范允许两种消息分发模式:持久化分发和非持久化分发.默认的分发模式是持久化分发.当消息生产者发送具有持久化标识的消息到代理时,消息代理将持久化消息到消息存储中然后在发送消息给消费者.这样是为了应对在灾难性失败或者在稍后时间再发送消息给目前尚未激活的消息消费者.

         如果你正在使用非持久化消息分发,则JMS允许消息服务提供者使用最大的效率发送消息给当前活动的消息消费者.ActiveMQ对于非持久化消息分发还提供了额外的可靠性保证,本节稍后就此展开介绍.非持久化消息明显比持久化消息快,主要因为下面两点:
(1) 消息生产者通过异步方式发送消息,所以生产者无需等待代理的回执.如图所示.

(2) 持久化消息保存到消息存储(通常需要写磁盘数据)比在网络中传输消息要慢.

     


 
 

         使用持久化消息的一个主要理由是在系统崩溃时防止消息丢失.但是正如11章中所述,可以配置ActiveMQ代理的失效转移协议来缓存异步消息,并且在传输连接器失效时重新发送消息(使用失效转移协议的trackMessages属性).同样,ActiveMQ还可以通过客户端或代理端的消息审计以防止消息重复发送.因此,对于各种仅需保证可靠性的应用场景(相对于确保消息能成功送达的场景)来说使用非持久化消息分发模式即可满足你的需求.

        因为默认情况下消息分发模式是持久化的,你需要在MessageProducer中明确制定以非持久化方式发送消息,如下代码所示:

       MessageProducer producer = session.createProducer(topic);

producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

我们已经看到为何使用用持久化消息分发和非持久化消息分发会有那么大的性能差异,并且了解了ActiveMQ为改善非持久化消息分发的可靠性而采取的措施.保证消息分发可靠性的好处是允许非持久化消息不仅可用于典型的JMS提供者,而且可以用于更多其他场景中.

 

12.1.2 事务

 当发送消息使用了事务时,只有在事务的边界处(即,Session.commit()方法)会导致与消息代理的同步通信.因此,可以通过批量化的消息生产和消息消费来改善发送持久化消息的性能.下面是相关的代码示例:

 

public void sendTransacted() throws JMSException {
		ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory();
		Connection connection = cf.createConnection();
		connection.start();
		Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
		Topic topic = session.createTopic("Test.Transactions");
		MessageProducer producer = session.createProducer(topic);
		int count = 0;
		for (int i = 0; i < 1000; i++) {
			Message message = session.createTextMessage("message " + i);
			producer.send(message);
			if (i != 0 && i % 10 == 0) {
				session.commit();
			}
		}

	}

	public void sendNonTransacted() throws JMSException {
		ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory();
		Connection connection = cf.createConnection();
		connection.start();
		// create a default session (no transactions)
		Session session = connection.createSession(false, Session.AUTO_ACKNOWELDGE);
		Topic topic = session.createTopic("Test.Transactions");
		MessageProducer producer = session.createProducer(topic);
		int count = 0;
		for (int i = 0; i < 1000; i++) {
			Message message = session.createTextMessage("message " + i);
			producer.send(message);
		}

	}
 

 

至此我们已经了解了性能调优的几个简单方式:如果可行的化使用非持久化消息,以及上面介绍的,在合适的情况下,在应用程序中使用事务边界发送持久化消息.

 

12.1.3 嵌入式代理

 

通常有的需求要求应用程序和代理在同一位置(译注:虚拟机)部署,因此所有依赖消息代理的服务只有在消息代理可用的时候才可用,如图所示.创建一个嵌入式代理相当容易,并且使用虚拟机传输连接器的一个优势是通过嵌入式代理分发的消息不会因网络传输要求的序列化而产生性能损耗,这就使得嵌入式代理成为那些要求能对大量服务做出快速响应的程序的理想选择.

 



 
 

 你可以使用一个监听TCP连接的传输连接器来创建一个嵌入式代理,并且依然可以使用VM传输连

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值