我希望有人可以帮助我 - 我在基于EJB/JMS的应用程序中使用JBoss 5.1和MQ Series 7.我的应用程序中有几个消息驱动的bean,每个bean都在MQ Series消息队列上进行监听.当在处理消息期间遇到错误时,我需要能够配置"重试延迟",以便mq系列在尝试重新传递消息之前等待一段时间.我已经广泛地梳理了MQ系列文档,并且还没有找到在MQ系列中实现这一目标的方法.我知道JBoss默认的JMS提供程序有办法实现这一点,但我目前仅限于使用MQ Series.由于我无法设置重试延迟 - 当我的消息失败时,我的应用程序会陷入紧急循环,传递消息并不断回滚.任何人都可以帮助我理解MQ系列中是否有一些配置选项允许我在重新发送失败的消息之前等待X毫秒?
对于较大的JMS部署,您对命名约定的最佳实践建议是什么?
目前,我们正在遵循Sun Developer Network Blueprints中的建议.例如:
jms/<resource-name>[Queue|Topic]
Run Code Online (Sandbox Code Playgroud)
随着我们在系统中获得越来越多的队列和主题,我担心扩展它.我特别感兴趣的是听到使用分层命名的经验以及人们如何决定他们的命名约定.
我试图了解我的Java EE应用程序应该放在哪些应用程序逻辑中.我是Java EE的新手,我正在考虑从遗留数据库加载大量非结构化数据,并构建一个干净的对象模型供我的应用程序使用.根据我的调查,我看到Java EE应用程序有两个组件,Enterprise Bean和Web Application组件.我的应用程序的这一部分将负责加载数据,构建对象模型以及根据数据的当前状态通过JMS向感兴趣的各方发送消息.数据将通过与数据库同步以及通过JMS从远程Java应用程序接收的消息进行更新.
EJB是否是这种功能的正确位置?如何开始我的对象模型的初始化(主要方法Java App等价物)?创建定时事件以查看对象模型并通过JMS发送消息的最佳实践是什么?
我已经阅读了很多关于Java EE,Glassfish,EJB的文章......但仍然觉得我没有清楚地了解我应该在哪里编写这个功能.我见过的EJB的任何例子都倾向于围绕来自客户端应用程序的bean的直接方法调用.
目前我觉得Java应用程序可以完成这项工作,但我们正在考虑将来使用RMI和Web客户端.
我是EJB的新手.背景:我有一个使用WebSphere缺省消息传递提供程序的MDB接收具有java.sql.DataSource的MapMessages来做一些工作,使用preparedstatement,jdbc事务等.我在ibm-ejb-bnd.xml中设置了MDB, ejb-jar.xml使用带有激活规范和目标名称的JCA适配器.我在ejb-jar和ibm-ejb-jar-bind中添加了一个java.sql.DataSource.我还在MessageListener中添加了带有@Resource注释的DataSource.
2个场景我无法理解(第一个场景已修复,请参阅更新)......
容器管理的MDB: DataSource驱动程序不兼容XA,因此我在WebSphere中启用了"Last Participant Support".但是,当MDB事务类型设置为Container时,我在提交时收到错误:
[11/28/11 10:56:10:988 MST] 0000002e RegisteredRes E WTRN0063E: An illegal attempt to commit a one phase capable resource with existing two phase capable resources has occurred.
Run Code Online (Sandbox Code Playgroud)
也许这是因为在DataSource提交之后,返回MessageListener,它提交它作为最后一个参与者?我相信WAS 7中的默认消息传递提供程序是XA兼容的,尽管我没有看到任何明确说明的文档.
在第一个错误之后,消息会立即重新运行4次(即使根据WebSphere中的ActivationSpec应该有30秒的延迟).每次抛出相同的错误.根据MessageListener它完成没有错误,所以这个错误是美妙的隐形容器托管事务的一部分.我不认为我需要XA全局事务,因为除了JMS之外只有一个DataSource,我以编程方式处理事务回滚.此外,JMS消息,MDB是异步的,AUTO-ACKNOWLEDGE.收到消息后,可以确认消息.
如果我引入了一个应用程序错误,所以有一个Exception,我立即看到这个错误5次(没有延迟):
[11/28/11 10:16:18:857 MST] 0000002b LocalExceptio E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "onMessage" on bean...
Run Code Online (Sandbox Code Playgroud)
所以我切换到................
Bean托管MDB: 提交正在运行而没有XA错误,只发生一次.但是,错误处理仍然不像我期望或想要的那样!在MessageListener类中,捕获的异常抛出EJB异常,我认为这应该导致MDB具有我想要的行为: 异常的原因对我来说无关紧要,当MDB抛出捕获的异常时,MDB不应该是根据WebSphereActivationSpec中的属性重试? 相反,消息将立即传递给MessageListener 5次,同时抛出与容器管理的MDB相同的错误:"EJB引发了意外(未声明的)异常......"
如果我抛出RuntimeException,则不会发生"未声明(未声明)的消息"消息,但消息仍然会立即重试4次,而不是等待重试延迟.
感谢阅读,非常感谢任何帮助或见解!
更新: 我最终通过将数据源切换到XA兼容来解决XA兼容性问题.在WAS管理控制台中:Resources-> JDBC Providers-> DB2 Universal JDBC Driver Provider->将实现类名更改为:com.ibm.db2.jcc.DB2XADataSource
但是当消息失败时我仍然遇到同样的问题.它会立即重试,而不是根据WAS中的ActivationSpec.
我正在使用JMS API(使用HornetQ),我正在使用spring bean作为消息监听器容器和消息监听器:
<bean id="messageListener" class="core.messaging.handler.MessageListener">
<property name="postCommandService" ref="postCommandService" />
</bean>
<bean id="messageSender"
class="lsn.messaging.sender.MessageSender">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="destination" />
</bean>
<bean id="msgListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer"
p:connectionFactory-ref="connectionFactory"
p:destination-ref="destination"
p:messageListener-ref="messageListener"
p:concurrentConsumers="10"
p:maxConcurrentConsumers="50"
p:receiveTimeout="5000"
p:idleTaskExecutionLimit="10"
p:idleConsumerLimit="5" />
Run Code Online (Sandbox Code Playgroud)
如果我想要我的消息监听器,只消耗特定的消息(具有相同的StringProperty)我该怎么办?我应该在哪里定义选择器?
我有下面的解决方案,但我没有MessageConsumer,所以我不能添加选择器:
String redSelector = "color='red'";
MessageConsumer redConsumer = session.createConsumer(queue, redSelector);
redConsumer.setMessageListener(new SimpleMessageListener("red"));
TextMessage redMessage = session.createTextMessage("Red");
redMessage.setStringProperty("color", "red");
producer.send(redMessage);
Run Code Online (Sandbox Code Playgroud) 我知道Camel的JMS组件,用于接收消息,使用Springs DefaultMessageListenerContainer.它可以配置为使用CLIENT_ACKNOWLEDGE模式来确认消息.我的问题是,什么时候调用message.acknowledge()方法?它是由spring的监听器容器在内部调用的吗?
或者我能以某种方式在遗嘱中承认消息吗?
我想避免因为我的应用程序在处理这些消息期间崩溃并使其成为事务性而导致消息丢失的情况对我来说有点太重了
我在远程glassfish服务器上配置了JMS队列.我正在尝试从本地计算机连接此队列.是否可以直接连接到此服务器,或者我需要通过某个代理/代理连接?它是如何工作的?(我在jms地区很新鲜)非常感谢
我已经安装了Glassfish 4并尝试创建一些JMS资源来跟踪学习JMS的教程,但这是不可能的.在Web界面上,它始终显示文本"java.lang.RuntimeException",并在日志控制台上显示堆栈跟踪.抛出此异常总是我在"JMS目标资源"页面或连接工厂的页面中按下"新建..."链接.这是堆栈跟踪:
[#|2015-11-16T09:15:24.090+0100|INFO|glassfish 4.1|org.glassfish.admingui|_ThreadID=48;_ThreadName=admin-listener(5);_TimeMillis=1447661724090;_LevelValue=800;|
Exception Occurred :null|#]
[#|2015-11-16T09:15:24.097+0100|INFO|glassfish 4.1|org.glassfish.admingui|_ThreadID=48;_ThreadName=admin-listener(5);_TimeMillis=1447661724097;_LevelValue=800;|
Exception Occurred :null|#]
[#|2015-11-16T09:15:24.100+0100|SEVERE|glassfish 4.1|javax.enterprise.resource.webcontainer.jsf.context|_ThreadID=48;_ThreadName=admin-listener(5);_TimeMillis=1447661724100;_LevelValue=1000;|
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException while attempting to process a 'beforeCreate' event for 'event166'.
at com.sun.jsftemplating.layout.descriptors.LayoutElementBase.dispatchHandlers(LayoutElementBase.java:422)
at com.sun.jsftemplating.layout.descriptors.LayoutElementBase.dispatchHandlers(LayoutElementBase.java:394)
at com.sun.jsftemplating.layout.descriptors.LayoutComponent.beforeCreate(LayoutComponent.java:348)
at com.sun.jsftemplating.layout.descriptors.LayoutComponent.getChild(LayoutComponent.java:288)
at com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:556)
at com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:551)
at com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:507)
at com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:507)
at com.sun.jsftemplating.layout.LayoutViewHandler.createView(LayoutViewHandler.java:255)
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:256)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:123)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at com.sun.webui.jsf.util.UploadFilter.doFilter(UploadFilter.java:233)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.doChainInvoke(StandardPipeline.java:678)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
at …Run Code Online (Sandbox Code Playgroud)