【发布时间】:2014-05-15 19:39:48
【问题描述】:
起初我有一个使用 RabbitMQ 和 Grails 的应用程序。 我定义了听众:
<bean id="rabbitListenerCreateDocument" class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="queues" ref="rabbitQueuePageInstanceCreated" />
<property name="defaultRequeueRejected" value="false"/>
<property name="messageListener" ref="createPageService" />
<property name="errorHandler" ref="errorHandlerService" />
<property name="transactionManager" ref="mongoTransactionManager"/>
<property name="autoStartup" value="true" />
<property name="concurrentConsumers" value="0" />
</bean>
问题是 createPageService 的 onMessage 方法运行次数过多。 我想是因为我收到了这个错误(当我从 spring 开启 onlogs 时):
connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 10
一段时间后,当抛出此异常时,我得到了 spring 不会向 rabbit 发送 ack。 一切都应该看起来不错,但是... 在 onMessage 方法中,我正在 MongoDB 中创建文档——而且我得到了太多的文档——这在我的应用程序中很重要。 我正在使用 Mongo 来存储一些对象,而且我们都知道 MongoDB 不是事务性的。 我认为这种情况是这样的:
- 监听器获取消息
- createPageService 中的 onMessage 方法正在运行
- 在 Mongo 中创建文档的方法
- 消息到达结束的方法
- Spring 想向 rabbit 发送 ACK,但它得到 UnknownChannelException
- TransactionManager 想要回滚但它不能 - MongoDB 上没有事务
- 同样的消息再次出现,现在一切正常(没有异常)
我试图做一些修改来解决这个问题,但它不起作用: 1. 首先,我尝试在 onMessage 方法上添加 Around 方面 - 它不工作......我得到:
Error creating bean with name 'grailsApplicationPostProcessor': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot resolve reference to bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' while setting bean property 'transactionAttributeSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.aop.aspectj.AspectJPointcutAdvisor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut
- 我为 bean 的连接定义了新的事务管理器:createPageService。这也行不通..
有人有办法解决这个问题吗?
【问题讨论】:
-
我发现在 Grails 中使用 spring-integration 来抽象兔子的东西可以简化配置。您可以使用
gateway将消息放在通道上,并使用service-activator处理来自队列的消息。我们正在使用这种方法,实际上根本不需要处理队列或 onMessage。只是一个想法。
标签: spring mongodb grails rabbitmq spring-aop