刚刚开始JMS ActiveMQ Acknowledgements着手在Spring工作.到目前为止,我有一个完美的消费者工作,除了当我不确认消息时,它仍然从队列中取出(我希望它留在那里或以死信队列结束).
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">
<!-- A JMS connection factory for ActiveMQ -->
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
p:brokerURL="failover://(tcp://jms1:61616,tcp://jms2:61616)?randomize=false&jms.redeliveryPolicy.maximumRedeliveries=5" />
<!-- A POJO that implements the JMS message listener -->
<bean id="simpleMessageListener" class="com.company.ConsumerClass" />
<!-- A JMS namespace aware Spring configuration for the message listener container -->
<jms:listener-container
container-type="default"
connection-factory="connectionFactory"
acknowledge="client"
concurrency="10-50"
cache="consumer">
<jms:listener destination="someQueue" ref="simpleMessageListener" method="onMessage" />
</jms:listener-container>
</beans>
Run Code Online (Sandbox Code Playgroud)
在ConsumerClass中,我的简单消费者看起来像这样:
@Override public final void onMessage(Message message) {
Object postedMessage = null; …Run Code Online (Sandbox Code Playgroud) 以下是1.5.2演示问题的简单弹簧启动项目(版本):
https://github.com/lanwen/camel-jms-activemq-test
它有Apache Camel版本2.18.3
在分支上master一切正常,因为activemq-camel=5.14.4和camel-jms=2.16.3(从它传递)
Spring启动应用程序正常启动日志:
2017-04-22 00:53:19.647 INFO 97217 --- [ main] o.a.camel.spring.SpringCamelContext : Apache Camel 2.18.3 (CamelContext: camel-1) is starting
2017-04-22 00:53:19.662 INFO 97173 --- [ main] o.apache.activemq.broker.BrokerService : Apache ActiveMQ 5.14.4 (localhost, ID:lanwen-osx3.local-62145-1492811599544-0:1) is starting
2017-04-22 00:53:19.665 INFO 97173 --- [ main] o.apache.activemq.broker.BrokerService : Apache ActiveMQ 5.14.4 (localhost, ID:lanwen-osx3.local-62145-1492811599544-0:1) started
2017-04-22 00:53:19.665 INFO 97173 --- [ main] o.apache.activemq.broker.BrokerService : For help or more information please see: …Run Code Online (Sandbox Code Playgroud) 我被要求设计并实施一个系统,用于从大量设备接收大量自动传感器数据.此数据将定期生成,并作为xml在http帖子中发送到服务器.如果设备未从服务器收到特定确认,则设备将继续重新发送相同的数据.在通过事务将数据插入主数据库中的多个表之前,需要对该数据进行一些潜在的重载处理,并且还需要将一些数据点入队以重定向到其他外部URL.
我打算使用Java应用程序服务器(倾向于GlassFish)和servlet来接收传入的数据.我想实现某种排队机制来暂时存储数据,以便返回传感器的响应不依赖于所有中间处理.单独的独立队列也是数据重定向部分的要求.经过一些研究后,两个主要选择似乎是:
1)在应用服务器上安装数据库,并使用表用于各种队列.队列将由Java应用程序处理,可以在应用程序服务器中运行,也可以作为自己的服务独立运行.
2)使用数据库支持的JMS解决方案来实现排队.
我对JMS并不熟悉,但从我看过的内容来看,似乎是这种情况下更好的解决方案.主要要求是在处理之前没有传感器数据丢失或从队列中丢弃,并且它或多或少地按顺序处理.我们还希望在某些时候可以轻松停止某些队列的处理,但仍然会让它们累积数据,并且这些消息永远不会自动过期.
使用策略1,我很明显如何满足这些要求,但它可能不那么健壮和可扩展,并且比策略2更复杂,因为我需要编写自己的多线程代码来处理各种独立队列.我想知道在为此目的使用JMS队列时可能存在的潜在缺陷是什么,因为我之前从未使用过它们.
数据完整性是一个大问题,所以我需要确保JMS能够保证在服务器重启,停电或者由于某种原因队列变得非常大的情况下不会丢失数据.例如,在一段时间内完成到主数据库的事务可能会导致JVM耗尽内存,崩溃并丢失所有累积的数据?(这将是噩梦般的场景).
此外,我想知道是否有任何方法可以通过应用服务器管理工具暂停JMS队列处理或轻松查看队列中的内容(我会将一个对象列入消息xml加上一些其他数据,包括收到的时间戳,等等.我在这里阅读了一些处理相关问题的帖子,但希望得到一些直接反馈.基本上我想知道JMS不是一个合适的排队解决方案的实例(如果有的话),如果这是其中一个案例.任何意见是极大的赞赏.
我希望我的所有应用程序日志都集中在一起(理想情况下是近乎实时的).我们将使用Log4 Appender.我应该使用哪一个:
你在用哪一个?
从Session的javadoc中可以看出:
Session对象是用于生成和使用消息的单线程上下文.
所以,我明白,你不应该使用一个会话对象,从两个不同的线程在同一时间.我不清楚的是,你是否可以从与其创建的不同的线程中使用Session对象(或者像Queue这样的子代).
在我正在研究的情况下,我正在考虑将我的Session对象放入一个可用会话池中,任何线程都可以借用,使用,并在完成后返回池中.
这是犹太人吗?
(使用ActiveMQ BTW,如果这会影响答案.)
我一直在使用JMS和ActiveMQ.一切都在创造奇迹.我不是用春天,也不是我.
界面javax.jms.MessageListener只有一种方法onMessage.在实现中,有可能抛出异常.如果事实上抛出异常,那么我说消息没有正确处理,需要重新尝试.所以,我需要ActiveMQ等待一段时间,然后重试.即我需要抛出异常来回滚JMS事务.
我怎样才能完成这样的行为?
也许ActiveMQ中有一些我无法找到的配置.
或者......也许可以取消MessageListener向消费者注册并自己消费消息,如下所示:
while (true) {
// ... some administrative stuff like ...
session = connection.createSesstion(true, SESSION_TRANSACTED)
try {
Message m = receiver.receive(queue, 1000L);
theMessageListener.onMessage(m);
session.commit();
} catch (Exception e) {
session.rollback();
Thread.sleep(someTimeDefinedSomewhereElse);
}
// ... some more administrative stuff
}
Run Code Online (Sandbox Code Playgroud)
在几个线程中,而不是注册监听器.
或者......我可以以某种方式装饰/ AOP /字节操纵MessageListeners来自己做.
你会采取什么途径?为什么?
注意:我没有完全控制MessageListeners代码.
编辑 概念证明的测试:
@Test
@Ignore("Interactive test, just a proof of concept")
public void transaccionConListener() throws Exception {
final AtomicInteger atomicInteger = …Run Code Online (Sandbox Code Playgroud) 如何使用Java获取ActiveMQ中的队列长度(发送到队列的未消耗消息的数量)?
我尝试使用eclipse实现JMS.但是当我试图保存代码时,它显示了它javax.jms.* cannot be resolved并且它也有no suggestions推荐.
我如何包含它并使用它?当我用Google搜索时,我发现javax.jms.*不是java API的一部分,那么如何在eclipse中使用它并让我的程序成功运行?
我想implement JMS with the help of activemq,我需要下载什么以及包含在代码中?
我是这个JMS的新手,请建议一些可以使用activemq实现JMS的参考或示例代码.
我阅读了今年UberConf的幻灯片,其中一位发言人提出Spring JMS为您的消息队列系统增加了性能开销的论点,但我没有看到任何证据支持幻灯片.发言者还说明点对点比传统的"发布 - 订阅"方法更快,因为每个消息只发送一次而不是广播给每个消费者.
我想知道是否有经验丰富的Java消息传递专家可以在这里权衡并澄清一些技术细节:
背景: 我有一个相对较旧的应用程序,它使用Websphere MQ进行消息传递.它在WAS(Websphere Application Server)上运行并使用MDB(消息驱动Bean).我成功地使用Spring Integration - JMS替换了所有MDB .我的下一步是尝试查看是否可以将其移出WAS,以便它可以在任何其他具有非IBM JRE的servlet容器上运行(我正在尝试:apache tomcat).请注意,使用SSL保护通道是必需的.我更喜欢使用JNDI.
最终目标: 将我的应用程序与应用程序服务器(WAS)和其他基础结构(如消息传递(MQ))分离.但是将这个从WAS中取出来到tomcat是第一步.接下来是使用更具可伸缩性的东西更新我的消息传递基础结构 这使我能够更新我的应用所依赖的基础架构的各个组件,一次一件事(应用服务器,消息传递层,数据存储),而不会过多地中断我的应用程序.
问: 现在,我的挑战是在tomcat上定义可以访问Websphere MQ的JNDI资源.我使用我在context.xml文件中定义的非SSL通道在这方面取得了一些进展,如下所示:
<Resource
name="jms/qcf_sandbox"
auth="Container"
type="com.ibm.mq.jms.MQQueueConnectionFactory"
factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
description="JMS Queue Connection Factory for sending messages"
HOST="localhost"
PORT="1414"
CHAN="CHANNEL_SANDBOX"
TRAN="1"
QMGR="QM_SANDBOX"/>
<Resource
name="jms/SandboxQ"
auth="Container"
type="com.ibm.mq.jms.MQQueue"
factory="com.ibm.mq.jms.MQQueueFactory"
description="JMS Queue"
QU="SANDBOX_Q"/>
Run Code Online (Sandbox Code Playgroud)
我的下一步是使用SSL通道.我理解涉及设置密钥库(kdb文件和证书生成和交换),在QM等上配置SSL通道的部分.我已经完成了所有工作.如何让tomcat使用我的密钥库,密码套件等?指针或工作示例会很棒!
注意:我目前正在使用Spring Integration 4.2,Websphere MQ v8,Tomcat v9.
我必须补充一点,我确实在没有JNDI的情况下尝试了一切.所以这里是没有JNDI的我的spring jms non-ssl配置,它的工作原理如下:
<bean id="mq-jms-cf-sandbox"
class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory">
<ref bean="mqQueueConnectionFactory" />
</property>
</bean>
<bean id="mqQueueConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName" value="localhost" />
<property name="port" value="1414" />
<property name="queueManager" value="QM_SANDBOX" />
<property …Run Code Online (Sandbox Code Playgroud)