Spring JMS

This page last changed on 2010-06-03 by   calvin.

1.Overview

  • ActiveMQ
  • <ActiveMQ in action>
  • <Java Message Service 2nd>, 有中文版。

2.选型

  ActiveMQ5.X暂时还是开源中的最佳选择,JBoss的HornetQ是另一个很有意思的项目,但还需要发展.

3.in SpringSide3

3.1 概述

  在showcase示例中在修改用户时将发送消息,由消息处理者异步执行较为耗时的通知邮件发送。

  1. 开发/演示时使用嵌入式的activemq broker。
  2. 实际生产环境中JMS Server应该独立启动,不受应用的影响。activemq的参数配置在activemq.xml中,在常见的tcp://61616端口侦听请求。

3.2 基本使用

  在appicationContext-simple.xml中的基本定义:

  1. 定义了普通的activemq的connectionFactory
  2. 定义了Spring的共享一个Connection, 缓存Session,Producer的CachingConnectionFactory, 默认仅Cache一个Session.
  3. 定义了只有一个消费者的notifyQueue 与 订阅-发布模式有多个消费者的notifyTopic.

  消息发送者

  1. 定义了Spring的JMSTemplate,默认为PERSISTENT,优先级为4,无过期时间
  2. 综合考虑性能与扩展性,一般都是使用MapMessage,使用JMSTemplate的convertAndSend()简单发送。

  消息消费者

  1. 消息消费者,一般使用Spring的MDP(Message Driven POJO)异步接收的模式,而不使用JMSTemplate主动同步接收。
  2. 在xml中定义MessageContainer与MessageListener接受者。
  3. Topic单线程的接收
  4. Queue则可以定义并发接收,默认为非Durable接收者。
  5. 确认模式默认为AUTO,即在onMessage()之前返回Ack,onMessage()中发生任何意外都不会触发Broker的重发.

3.3  高级使用

  在applicationContext-advanced.xml中的基本定义:

  1. 定义activemq的connetctionFactory,可定义对PERSISTENT的消息进行异步发送(PERSISTENT消息默认同步发送,而NON_PERSISTENT消息默认异步发送),可定义ClientID(Durable订阅者的必须设置)。
  2. 定义Spring的CachingConnectionFactory,定义Cache 10个Session.

   消息发送者

  1. 定义JMSTemplate,定义NON_PERSISTENT,优先级为9.
  2. 发送者实现MessageCreator类,在发送MapMessage同时设置了一个便于接收者用Selector过滤的Property.

   消息消费者

  1. Queue的Listener定义了concurrentConsumers与maxConcurrentConsumers,初始化5个,可动态扩展到10个用户。
  2. Topic的Listener定义了自己为持久化用户。定义了一个消息过滤条件(只接收Property中type为user的消息。
  3. 确认模式改为Client模式,如果出现异常或应用被异常关闭,在Connection关闭后,Broker将会把消息转发给另一个消费者。(如果另一个消费者也不能消费,则在此消费者关闭后继续发给下一个消费者,永远循环下去。
    而如果设置为transacted=true模式,ActiveMQ会把消息重发6次给同一个消费者--在RedeliverPolicy中设置,如果此消费者已完蛋,则发送给其他消费者。超过6次后,把消息放入Dead Letter Queue。
    感觉使用Client模式较为简单。

4.服务器配置

4.1 极限性能配置

      参看activemq-throughput.xml:

  • Broker没有JMX, 没有advisory信息
  • kahaDB配置成Batch模式

      但以上两点的可管理性与安全度不高,非极限情况慎用。

4.2 关于Message Flow Control的配置

  • VMCursor:Dispatch Queue满了之后,待发的信息放在Store还是内存中,一般持久化订阅的Topic肯定是放Store, 而非持久化订阅的Topic肯定是放内存. 对于Queue,默认是放Store, 如果你相信Queue Consumer不会同时死光,可以放内存以加快性能。
  • Message Flow Control:为免把AMQ撑爆,而且大量消息未被消费本来就是异常,AMQ提供控制生产者速度的方法。
    对于同步生产者,可以针对某个Session进行控制(通过ACK信号), 异步的生产者,除非你设置windowPrefetchSize,否则就会对整个连接进行Block,容易产生锁。
    整个控制感觉和持久化/非持久化消息 * Queue&持久化订阅Topic/ Topic * Cursor * 目的地级别的是否MessageFlowCtrol * 目的地级别的Memory Limit * 系统级别的容量限制结合起来,让人看得无比头痛。建议在测试中配合JMX提供的消息自己实验一下,暂时没有什么建议。

4.3 SpringSide3中的配置

    在server/activemq下,有单机与动态Network Broker两种配置,注意目录下的ReadMe文件。

4.3.1 打开JMX, 提升内存 

  在启动命令改了两个地方,一个是打开了JMX的开关,一个是将内存从512M提高到2G

4.3.2 Message Flow Control 参数   

  在activemq-*.xml 中修改两个配置:

  • 每个目的地的内存限制从1M加到10M
  • 系统总容量限制,内存从默认的64M加到128M,而磁盘和临时磁盘则降低了10倍,分别是10G和1G

4.3.3 预定义Queue与Topic的名称

    虽说可以动态定义,但觉得预建立了更好更安全。

4.3.4 Networks of Brokers

  与Master/Slave相比,NOB是一种相对简单廉价的HA与Load Balance兼顾的方案。

  配置了multicast时的组名,未免与同一机房的其他机器冲突,从默认的multicast://default ==  multicast://239.255.2.3:6155?group=default 改换组名变成了multicast://239.255.2.3:6155?group=springside

  如果要loadBalance,networkConnectors中的conduitSubscriptions要设为false,decreaseNetworkConsumerPriority=false,这样分配到remote broker的流量就按remote broker的实际消费者而不是固定按1来计算,优先级也不会预先减5.

4.3.5 FailOver的URL Broker

     下面的URL是一个典型的连接两个远程的Networks of Brokers式部署的方式。

     默认情况下,failOver会有一条线程在无限重连,发送的线程则无限重发数据,除非你配置了timeout 或 MaxAttemps参数。重试间隔从10ms开始,每次增长一倍直到30s。

     按实际需要,可改为从100ms开始重试,5秒超时。并设置randomize随机选择一个broker。

 failover://(tcp://remote1:61616,tcp://remote2:61616)?randomize=true&initialReconnectDelay=100
&timeout=5000
出自:http://www.darkmi.com/man/SpringSide3/JMS.html

你可能感兴趣的:(spring,jms)