开封建设企业网站公司,高质量的网站建设,网站免费源码不用下载,php网站添加验证码每隔一段时间#xff0c;我会遇到一个与ActiveMQ的连接和池相关的有趣问题#xff0c;而今天#xff0c;我想讨论一些并不总是很清楚的问题#xff0c;并且在使用ActiveMQ和Camel JMS时可能会导致您大量饮酒。 并不是说您无论如何都不会在使用ActiveMQ和Camel时大量喝酒……… 每隔一段时间我会遇到一个与ActiveMQ的连接和池相关的有趣问题而今天我想讨论一些并不总是很清楚的问题并且在使用ActiveMQ和Camel JMS时可能会导致您大量饮酒。 并不是说您无论如何都不会在使用ActiveMQ和Camel时大量喝酒……以庆祝使用它们时集成和消息传递变得多么令人愉快。 所以首先。 连接池。 当然您总是听说过要建立连接。 这到底是什么意思为什么要这么做 与创建会话或使用方等其他操作相比打开与ActiveMQ代理的连接是一项相对昂贵的操作。 因此在发送或接收消息并通常与代理进行交互时如果可能的话您希望重用现有的连接。 您不需要做的就是依靠JMS库例如Spring JmsTemplate该库在每次发送或接收消息时都会打开和关闭连接……除非您可以合并/缓存连接。 因此如果我们可以同意池化连接是一个好主意请看一个示例配置 bean idpooledConnectionFactory classorg.apache.activemq.pool.PooledConnectionFactory init-methodstart destroy-methodstopproperty namemaxConnections value10 /property namemaximumActiveSessionPerConnection value10 /property nameconnectionFactory bean classorg.apache.activemq.ActiveMQConnectionFactoryproperty namebrokerURL valuetcp://127.0.0.1:61616 //bean/property/bean 您甚至可能要使用Apache Camel及其出色的camel-jms组件因为否则这样做很愚蠢。 因此也许您想要设置类似于以下内容的JMS配置 bean idjmsConfig classorg.apache.camel.component.jms.JmsConfigurationproperty nameconnectionFactory refpooledConnectionFactory /property nametransacted valuetrue /property nameconcurrentConsumers value15 /property namedeliveryPersistent valuetrue /property namerequestTimeout value10000 /property namecacheLevelName valueCACHE_CONSUMER //bean 此配置基本上对消费者意味着设置15个并发消费者使用事务本地对生产者使用PERSISTENT消息将超时设置为10000以进行请求答复等。 值得注意的是 如果您想更全面地了解jms组件的配置尤其是在缓存使用者事务等方面请参考Torsten关于Camel JMS 的出色的博客 其中包含交易-经验教训 。 也许您还应该花一些时间在他的博客上闲逛因为他也有很多很好的Camel / ActiveMQ东西 到目前为止很棒。 我们有一个包含10个连接的连接池我们希望每个连接10个会话如果需要总共100个会话…以及15个并发使用者。 我们应该能够应付一些沉重的负担对不对 在这里看看这条路线。 这很简单公开了activemq组件它将使用上面的jmsConfig因此有15个并发使用者并仅执行一些日志记录 from(activemq:test.queue).routeId(test.queue.routeId).to(log:org.apache.camel.blog?groupSize100); 尝试运行此程序。 您会发现您的消费者立即被封锁堆栈跟踪将显示出这种美丽 Camel (camel-1) thread #1 - JmsConsumer[test.queue] daemon prio5 tid7f81eb4bc000 nid0x10abbb000 in Object.wait() [10abba000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on 7f40e9070 (a org.apache.commons.pool.impl.GenericKeyedObjectPool$Latch)
at java.lang.Object.wait(Object.java:485)
at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1151)
- locked 7f40e9070 (a org.apache.commons.pool.impl.GenericKeyedObjectPool$Latch)
at org.apache.activemq.pool.ConnectionPool.createSession(ConnectionPool.java:146)
at org.apache.activemq.pool.PooledConnection.createSession(PooledConnection.java:173)
at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:196)
.... 怎么可能呢 我们有连接池...我们将每个连接的会话数设置为每个连接10个那么我们如何阻止创建新会话呢 答案是您正在耗尽会话数就像堆栈跟踪所期望的那样。 但是如何 我需要喝多少才能解决这个问题 好吧现在等等。 喝啤酒听我说。 首先了解一下。 ActiveMQ的池实现使用commons-pool 而maxActiveSessionsPerConnection属性实际上已映射到基础池的maxActive属性。 从文档中这意味着 maxActive controls the maximum number of objects (per key) that can allocated by the pool (checked out to client threads, or idle in the pool) at one time. 这里的键是“键”字面意思是……文档中的“每个键”子句。 因此在ActiveMQ实现中关键是一个对象它表示1是否事务处理模式以及2确认模式是 如此处所示 。 简而言之对于该连接上使用的每个密钥您最终都会获得一个“ maxActive”会话。.因此如果您有使用事务的客户端则不进行任何事务client-ackauto-acktransacted-session dups-okay等等您可以开始看到对于每个排列您最终都将获得“ maxActive”会话。 因此如果将maxActiveSesssionsionsPerConnection设置为10则最终可能会得到10 x 2 x 4 80个会话。 这是藏在你脑海中的东西。 这里的第二个关键是当camel-jms组件设置使用者时它最终会在并发消费者会话指定的所有使用者之间共享一个连接。 这是一个有趣的观点因为camel-jms使用了底层Spring框架的DefaultMessageListenerContainer不幸的是此限制来自该库。 因此如果您有15个并发使用者那么他们将共享一个连接即使是池化……它也会从池中获取一个连接并保持它。 因此如果您有15个使用者每个使用者共享一个连接每个使用者共享一个事务处理模式每个使用者共享一个ack模式那么您最终将尝试为该连接创建15个会话。 最后您得到了上述结果。 因此我避免这些情况的经验法则是 确切了解您的每个生产者和消费者正在做什么他们的TX和ACK模式是什么 需要时请始终调整最大会话参数会话线程太多我不知道..但并发ConsumersConsumers 1的值应至少为ATEST 如果生产者和消费者正在生产/消费相同的目的地则将连接池拆分一个消费者池一个生产者池 邓诺Dunno该信息将非常有价值但我想亲自写下来。 如果其他人觉得它有价值或有疑问请在评论中让我知道。 参考 经验教训ActiveMQApache Camel和我们的JCG合作伙伴 Christian Posta在Christian Posta –软件博客博客上的连接池 。 翻译自: https://www.javacodegeeks.com/2014/03/lessons-learned-activemq-apache-camel-and-connection-pooling.html