标签: jms

Terracotta是否使JMS成为不需要的层?

我们目前正在编写一个IT已经为其购买硬件的应用程序.他们的方法是购买我们将部署的大型硬件.为了增加更多处理,他们计划添加具有相同软件的其他服务器.为了适应这种设计,我们使用Terracotta来提供运行多个JVM的能力,就像它是一个大型JVM一样.无论这是否是一种明智的方式(我仍然不相信),这就是我正在处理的情况.

无论如何,我们有一部分应用程序使用标准的生产者/消费者类型队列.使用Terracotta,我们可以创建一个可与多个JVM一起使用的单个队列.这很漂亮,效果很好.

但现在,我们正在寻找额外的机会来运行异步流程.为了使我们的所有排队逻辑更加一致,我们正在考虑使用JMS来抽象出通用逻辑.由于我们不打算将JMS用作远程队列(至少在可预见的未来),我想知道JMS是否只是增加了不必要的复杂性.

有什么建议或想法?我们应该继续将队列构建为并发结构,还是将它们视为单独的可能远程对象?

java concurrency terracotta jms

8
推荐指数
1
解决办法
940
查看次数

我为什么要使用JMS而不是RMI + Queue?

目前我正在使用RMI或粗体库在我的服务器和客户端之间进行通信(通过LinkedBlockingQueue).现在我读到了可以在这个领域使用的JMS.它是否正确?如果是的话,你介意给我一个简单的优缺点列表,因为它似乎是一个非常复杂和"全面 - 企业"的领域.

有什么好处?与RMI + Queue相比,性能如何呢?JMS能否击败RMI +队列?

PS:我知道有类似的问题,但我希望将JMS与RMI + Queue进行比较.

java queue jms rmi

8
推荐指数
2
解决办法
5968
查看次数

当消费者关闭时,javax.jms.MessageConsumer会挂起

根据javadoc,如果我在javax.jms.MessageConsumer上调用receive(),它将无限期地阻塞,直到产生消息或消息使用者关闭为止.

我有一个调用receive()的线程.作为线程关闭的一部分,我调用close(),但是消费者仍然在receive()中阻塞,因此线程不会关闭.我的代码的要点是:

public String receiveMessage() {
...
...
   System.out.println("About to receive")
   TextMessage message = (TextMessage) consumer.receive();
   System.out.println("No longer receiving")
...
...
}

public void stop() {
    try {
        if (consumer != null) {
            consumer.close();
        }
    } catch (JMSException ex) {
        throw new IllegalStateException(ex);
    }
}
Run Code Online (Sandbox Code Playgroud)

在调试器中,我可以看到正在调用close(),但接收仍然阻塞.如果我使用带有超时的receive()方法,它将一直阻塞,直到超时到期.

一切看起来都对我来说,希望有人可以告诉我我做错了什么.

java jms ibm-mq

8
推荐指数
2
解决办法
2万
查看次数

WebSphere 7中的消息驱动Bean(EJB3),XA事务,错误处理

我是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.

java websphere ejb jms message-driven-bean

8
推荐指数
1
解决办法
5657
查看次数

KahaDB和LevelDB - 真正的区别是什么?

我正试图ActiveMQ 5.8.0在我的项目中使用.有两种不同的存储配置,KahaDBLevelDB.根据问题,Kaha可以比Level更快或Level可以比Kaha更快.

它们之间真正的区别是什么?

activemq-classic jms leveldb difference

8
推荐指数
2
解决办法
4401
查看次数

ActiveMQ不从队列中取消消息

我最近将服务器从ActiveMQ从5.8升级到最新(5.11.1).从那以后,我偶尔会注意到消息会在特定队列中累积而不会被取消.

我们的架构有一个生产者,一个消费者.我可以看到消费者仍然是连接的,但消息正在从生产者堆积起来.我的解决方案是通过Web控制台删除队列.之后,我立即看到消费者重新连接并再次开始处理消息.

如果它是相关的,在这种情况下,生产者在.NET上运行NMS,而消费者在Java 1.7上运行JMS.

java activemq-classic jms nms

8
推荐指数
1
解决办法
2507
查看次数

wildfly10中JMS队列的JNDI名称格式

嗨我从JBoss_6.1.0_final迁移到wildfly 10.

在JBoss for Queue名称中,格式如下

<queue name="TEST_QUEUE">
  <entry name="/queue/TEST_QUEUE"/>
</queue>
Run Code Online (Sandbox Code Playgroud)

并在MDB注释中

@ActivationConfigProperty(propertyName = "destination",
                propertyValue = "queue/TEST_QUEUE")
Run Code Online (Sandbox Code Playgroud)

现在在野生蝇类如下.参考链接

<jms-queue name="TEST_QUEUE" entries="jms/queue/TEST_QUEUE java:jboss/exported/jms/queue/TEST_QUEUE"/>
Run Code Online (Sandbox Code Playgroud)

with activationproperty

@ActivationConfigProperty(propertyName = "destination",
                        propertyValue = "jms/queue/TEST_QUEUE")
Run Code Online (Sandbox Code Playgroud)

在wildfly中,我尝试通过删除jms/from队列名称和注释,它在具有相同队列名称的wildfly中正常工作,如

<jms-queue name="TEST_QUEUE" entries="queue/TEST_QUEUE java:jboss/exported/queue/TEST_QUEUE"/>
Run Code Online (Sandbox Code Playgroud)

现在我的问题是,是否JMS/有目的地添加了队列名称.

编写没有前缀的队列名称是一种好习惯 jms/

jms wildfly wildfly-10 jms-queue

8
推荐指数
1
解决办法
455
查看次数

为什么我的QuendConnectionFactory的JNDI查找返回null?

我试图寻找一个QueueConnectionFactoryQueue通过Geronimo的JNDI.在Queue获取返回正常,但QueueConnectionFactory查找始终返回null.它不会抛出一个NamingException,如果JNDI名称不正确,这就是我所期望的.

谁能看到我做错了什么?下面的测试代码输出:

true
false

import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JndiTest
{
    private final static String QUEUE_NAME = "jca:/org.apache.geronimo.configs/activemq-ra/JCAAdminObject/SendReceiveQueue";
    private final static String FACTORY_NAME = "jca:/org.apache.geronimo.configs/activemq-ra/JCAManagedConnectionFactory/DefaultActiveMQConnectionFactory";

    public static void main(String[] args) throws NamingException
    {
        InitialContext ctx = new InitialContext();
        QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup(FACTORY_NAME);
        Queue queue = (Queue)ctx.lookup(QUEUE_NAME);
        System.out.println(factory == null);
        System.out.println(queue == null);      
    }

}
Run Code Online (Sandbox Code Playgroud)

如果它有所不同:我已将openejb-client-3.0.1.jar,geronimo-ejb_3.0_spec-1.0.1.jar和activemq-core-4.1.2-G20090207.jar添加到我的类路径中,并且我的jndi.properties文件具有以下属性:

java.naming.factory.initial = org.apache.openejb.client.RemoteInitialContextFactory
java.naming.provider.url = ejbd://127.0.0.1:4201

java jndi jms geronimo java-ee

7
推荐指数
1
解决办法
3万
查看次数

如何在Apache Camel中检测损坏/恢复的JMS连接?

我们正在使用Apache Camel(Camel 2.10.3,基于Java DSL)构建集成项目.

我们有一个从数据库中提取数据的路径(让我们称之为IN_DB),做一些逻辑并每天插入另一个数据库(OUT_DB),另一个订阅XML数据的JMS主题的路径,做一些逻辑和插入它整天都在同一个数据库(OUT_DB)中.

要求是当JMS主题连接因任何原因而失效时,我们会不断尝试重新连接,一旦重新连接成功,我们需要返回数据库(IN_DB)并进行另一次加载以填补主题的空白失意了.

我的问题是我们怎么能在Camel中做这个逻辑('我已经连接然后我断开连接,现在又连接了')?当主题发生故障时,以主题消费者开头的路线会发生什么,路线会停止吗?或者它会向某个错误队列发出错误消息?我是否必须编写自己的处理程序来监视主题连接,或者当主题重新启动并设置一些消息头时Camel会自动重新连接,或者设置一些上下文变量以指示'我已连接然后我断开了连接现在我再次联系'情景已经发生了?我很高兴围绕调用数据库负载构建路由逻辑我无法找出在Camel中"检测"这种情况发生的最佳方法.

任何建议非常感谢.

java jms apache-camel

7
推荐指数
1
解决办法
3517
查看次数

JMSMessageID应该在发布和订阅之间进行更改吗?

JMS 2.0规范说

所述JMSMessageID报头字段包含唯一标识由提供商发送的每个消息的值.

...和...

唯一性的确切范围是提供者定义的.它应该至少涵盖特定安装提供程序的所有消息,其中安装是一组连接的消息路由器.

规范没有明确声明JMSMessageID从发布API调用返回的内容必须与消息中消息中存在的内容匹配.关于在回复请求时移动JMSMessageID到规范的规范中的讨论JMSCorrelationID意味着两者将是相同的.如果在发布和使用之间更改了消息ID,则此样式的请求/回复将失败.

当然,在JMS 1.1和现在2.0的统一域模型中,JMSMessageID根据目标是队列还是主题,改变行为是没有意义的.在统一的模式下,人们会期望所有目的地在这方面都采取相同的行动.

此外,如果第一段中使用的"提供者"指的是发送消息的内容,那么散布到具有相同JMSMessageID值的10条相同消息的发布将符合规范,因为在发送方测量唯一性.

不幸的是,规范在使用术语"提供者"来描述发送消息的事物与使用它来描述JMS传输的供应商之间切换.这在上面两个引用的段落中很明显.这种模棱两可并不重要.

至少有一个实现(IBM的MQ)采用的方法是,一个发布到10条消息的发布已经创建了10条唯一的新消息,因此每个消息都具有唯一JMSMessageID值.这可以说与第二个引用的段落一致,该段落需要作用于提供者的唯一性,其中"提供者"似乎是指供应商实现而不是发送消息的事物.

我相信,当发布的消息向多个订阅者扇出时,正确的行为将是JMSMessageID在消息的每个实例中保留,以便可以按预期关联回复.换句话说,我认为IBM的实施是不合规的.由于规范在这个问题上是模棱两可的,我正在寻找一个权威的来源,要么直接或强烈地暗示规范所预期的行为,不管是哪种方式.根据响应,我要么退出,要么将IBM的问题作为合规性缺陷提出.

jms ibm-mq

7
推荐指数
1
解决办法
1123
查看次数