ActiveMQ问题分析和解决
- 格式:pdf
- 大小:157.10 KB
- 文档页数:6
ActiveMQ问题分析和解决
1)KahaDb和AMQ Message Store两种持久⽅式如何选择?
官⽅:From 5.3 onwards - we recommend you use KahaDB - which offers improved scalability and recoverability over the AMQ Message Store.
The AMQ Message Store which although faster than KahaDB - does not scales as well as KahaDB and recovery times take longer.
⾮官⽅:kaha⽂件系统实际上上是⼀个⽂件索引系统,有两部分组成,⼀个是数据⽂件系统,由⼀个个独⽴的⽂件组成,缺省⽂件⼤⼩是32M⼤(可配置),另外⼀个是索引⽂件系统,记录消息在数据⽂件中的位置信息以及数据⽂件中的空闲块信息。数据⽂件是存储到硬盘上的,索引⽂件是缓存在内存中的。所以这个存储系统对⼤消息存储有利,象我们的memberId之类的⽂本消息,实际上是浪费,索引⽐消息还⼤,哈。
我⽅分析:
推荐: Amq持久⽅式
理由:虽然官⽅推荐使⽤KahaDB持久⽅式,但其提到的优势:可伸缩性和恢复性较好,对于我们实际的应⽤意义不⼤。从我们⾃⼰的使⽤经验来看,KahaDB持久⽅式,Data⽂件是⼀个⼤⽂件(感觉⽂件过⼤后,造成队列服务瘫死的可能性会增⼤),从官⽹的相关配置(附录1)也找不到哪⾥可以设置数据的⽂件的最⼤Size。)⽽Amq持久⽅式可以设置Data⽂件最⼤Size,这样可以保证即时消息积压很多,Data⽂件也不⾄于过⼤。
2)错误:Channel was inactive for too long
解决⽅法:
在建⽴连接的Uri中加⼊: wireFormat.maxInactivityDuration=0
You can do the following to fix the issues:
1) Append max inactivity duration to your Uri in the format below: wireFormat.maxInactivityDuration=0
2) Use the same Uri at the client side as well as at the server side
Regards,
如果不这样设置,对应的错误会出现:2008-05-07 09:22:56,343 [org.apache.activemq.ActiveMQConnection]-[WARN] Async exception with no exception listener:org.apache.activemq.transport.InactivityIOException: Channel was inactive for too long: localhost/127.0.0.1:61616
org.apache.activemq.transport.InactivityIOException: Channel was inactive for too long: localhost/127.0.0.1:61616
ActiveMQ的tcp url:tcp://localhost:61616后⾯要加⼊?wireFormat.maxInactivityDuration=0 这样的参数,否则当⼀段时间没有消息发送时会抛出 "Channel was inactive for too long"异常
3)错误:Wire format negotiation timeout: peer did not send his wire format.
解决⽅法:1)关闭ActiveMqLog4j
打开:conf/log4j.properties
将:log4j.rootLogger=INFO, console, logfile
修改为:log4j.rootLogger=OFF
2)在建⽴连接的Uri中加⼊: maxInactivityDurationInitalDelay=30000例如北京的测试环境连接Uri:tcp://192.168.199.80:61616?wireFormat.maxInactivityDuration=0&maxInactivityDurationInitalDelay=30000&connection.AsyncSend=true
参考资源:
If you get exception like this,it can mean one of three things:
1. You're connecting to the port not used by ActiveMQ TCP transport
Make sure to check that you're connecting to the appropriate host:port
2. You're using log4j JMS appender and doesn't filter out ActiveMQ log messages
Be sure to read How do I use log4j JMS appender with ActiveMQ and more importantly to never send ActiveMQ log messages to JMSappender
3. Your broker is probably under heavy load (or network connection is unreliable), so connection setup cannot be completed in areasonable time
If you experience sporadic exceptions like this, the best solution is to use failover transport, so that your clients can try connecting again ifthe first attempt fails. If you're getting these kind of exceptions more frequently you can also try extending wire format negotiation period(default 10 sec). You can do that by using wireFormat.maxInactivityDurationInitalDelay property on the connection URL in your client.
For example
tcp://localhost:61616?wireFormat.maxInactivityDurationInitalDelay=30000
will use 30 sec timeout.(貌似有问题)
4)错误:Out of memory
解决⽅法:1) 设置Java最⼤内存限制为合适⼤⼩:
Bin/activemq.bat 中ACTIVEMQ_OPTS=-Xmx512M(默认是512)
2)Activemq.xml配置节:systemUsage/ systemUsage配置⼤⼩合适,并且特别注意:⼤于所有durable desitination设置的memoryUsage之和。
备注:1)尖括号:“>”代表通配符
2)ACTIVEMQ_OPTS的配置〉=memoryUsage中配置〉=所有durable desitination设置之和
3)SystemUsage配置设置了⼀些系统内存和硬盘容量,当系统消耗超过这些容量设置时,amq会“slow down producer”,还是很重要的。
对于MQ的内容实⽤是可管理和可配置的。⾸先需要判断的是MQ的哪部分系统因内存不⾜⽽导致泄漏,是JVM,broker还是消费者、⽣产者? ⼀、内存管理
JVM内存管理:
1. ⽤bin/activemq命令在独⽴JVM中运⾏broker。⽤-Xmx和-Xss命令即可(activemq.bat⽂件中修改ACTIVEMQ_OPTS选项参数即可); 2. 默认情况下,MQ⽤512M的JVM;
broker内存管理:
1. broker使⽤的内存并不是由JVM的内存决定的。虽然受到JVM的限制,但broker确实独⽴管理器内存; 2. systemUsage和destination的内存限制与broker内存息息相关;
3. MQ中内存的关系是:JVM->Broker->broker features;
4. 所有destination的内存总量不能超过broker的总内存;
消费者:
1. 由于消息⼤⼩可以配置,prefetch limit往往是导致内存溢出的主要原因;
2. 减少prefetch limit的⼤⼩,会减少消费者内存中存储的消息数量;
⽣产者:
1. 除⾮消息数量超过了broker资源的限制,否则⽣产者不会导致内存溢出;
2. 当内存溢出后,⽣产者会收到broker的阻塞信息提⽰;
⼆、其他
将消息缓冲之硬盘:
1. 只有当消息在内存中存储时,才允许消息的快速匹配与分发,⽽当消费者很慢或者离开时,内存可能会耗尽;
2. 当destination到达它的内存临界值时,broker会⽤消息游标来缓存⾮持久化的消息到硬盘。
3. 临界值在broker中通过memoryUsage和systemUsage两个属性配置,请参考activemq.xml;
4. 对于缓慢的消费者,当尚未耗尽内存或者转变为⽣产者并发控制模式前,这个特性允许⽣产者继续发送消息到broker;
5. 当有多个destination的时候,默认的内存临界值可能被打破,⽽这种情况将消息缓存到硬盘就显得很有意义;
6. precentUsage配置:使⽤百分⽐来控制内存使⽤情况;
多个线程:
1. 默认情况下,MQ每个destination都对应唯⼀的线程;
2. -Dorg.apache.activema.UseDedicatedTaskRunner=false(activemq.bat⽂件中修改ACTIVEMQ_OPTS选项参数即可),⽤线程池来限制线程的数量,从⽽减少内存消耗; ⼤数据传输:
1. destination policies--maxPageSize:控制进⼊内存中的消息数量;lazyDispatch:增加控制使⽤当前消费者列表的预取值;
2. 使⽤blogMessage或者streamsMessage类型来进⾏⼤量⽂件的传输;
泄漏JMS资源:
1. 当session或者producer或者consumer⼤量存在⽽没有关闭的时候;
2. 使⽤PooledConnectionFactory;