Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Spring与RabbitMQ集成_Rabbitmq_Amqp_Spring Integration - Fatal编程技术网

使用Spring与RabbitMQ集成

使用Spring与RabbitMQ集成,rabbitmq,amqp,spring-integration,Rabbitmq,Amqp,Spring Integration,我正在为我们的一个应用程序开发消息传递接口。应用程序是一个服务,它被设计为接受一个“作业”,进行一些处理,并返回结果(实际上是以文件的形式) 其想法是使用RabbitMQ作为消息传递基础设施,使用Spring AMQP处理特定于协议的细节 我不希望我的代码与Spring AMQP紧密耦合,因此我希望使用Spring集成来隐藏消息传递api。所以基本上我想要这个: 发送到RabbitMQ的消息==>Spring AMQP==>Spring集成===>MyService==>一路回复到RabbitM

我正在为我们的一个应用程序开发消息传递接口。应用程序是一个服务,它被设计为接受一个“作业”,进行一些处理,并返回结果(实际上是以文件的形式)

其想法是使用RabbitMQ作为消息传递基础设施,使用Spring AMQP处理特定于协议的细节

我不希望我的代码与Spring AMQP紧密耦合,因此我希望使用Spring集成来隐藏消息传递api。所以基本上我想要这个:

发送到RabbitMQ的消息==>Spring AMQP==>Spring集成===>MyService==>一路回复到RabbitMQ

我正在尝试解决将这些连接在一起所需的XML配置,但我在多个抽象级别和不同术语方面遇到了问题。事实证明,在Spring AMQP/RabbitMQ之上找到一个演示Spring集成的工作示例是非常困难的,尽管我觉得这种设置非常“最佳实践”

1) 所以。。能不能有个聪明的人来看看这个,也许能把我推向正确的方向?我需要什么?我不需要什么?:-)

2) 理想情况下,队列应该是多线程的,这意味着taskExecutor应该将多条消息传递给我的jobService进行并行处理。需要什么配置

 <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:rabbit="http://www.springframework.org/schema/rabbit"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
    xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
    http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
    http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
    ">

    <context:component-scan base-package="com.myprogram.etc" />

    <!-- Messaging infrastructure: RabbitMQ -->

    <bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
        <constructor-arg value="${ei.messaging.amqp.servername}" />
        <property name="username" value="${ei.messaging.amqp.username}" />
        <property name="password" value="${ei.messaging.amqp.password}" />
    </bean>

    <rabbit:connection-factory id="connectionFactory" />

    <rabbit:admin connection-factory="connectionFactory"/>

    <!-- From RabbitMQ -->

    <int-amqp:inbound-gateway request-channel="fromAMQP" reply-channel="toAMQP" queue-names="our-product-name-queue" connection-factory="connectionFactory"/>

    <!-- Spring Integration configuration -->

    <int:channel id="fromAMQP">
        <!-- Is this necessary?? -->
        <int:queue/>
    </int:channel>

    <!-- JobService is a @Service with a @ServiceActivator annotation -->
    <int:service-activator input-channel="fromAMQP" ref="jobService"/>
</beans>

我想我和你一样是spring integration和spring integration amqp的noob,但我确实在一个示例项目的基础上取得了一些成果

对于rabbitmq基础架构,我有以下几点:

<rabbit:connection-factory id="rabbitConnectionFactory"/>

<rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory"/>

<rabbit:admin connection-factory="rabbitConnectionFactory"/>

<!-- some attributes seemed to be ok with queue name, others required id
  -- so I used both with the same value -->
<rabbit:queue id='test.queue' name='test.queue'/>

<rabbit:direct-exchange name:"my.exchange">
    <rabbit:bindings>
        <rabbit:binding queue="test.queue" key="test.binding"/>
    </rabbit:bindings>
</rabbit:direct-exchange>
<!-- This is just an interface definition, no implementation required
  -- spring will generate an implementation which puts a message on the channel -->
<int:gateway id="backgroundService", 
         service-interface="com.company.BackgroundService"
             default-request-channel="toRabbit"

<int:channel id:"toRabbit"/>

<!-- used amqpTemplate to send messages on toRabbit channel to rabbitmq -->
<int-amqp:outbound-channel-adapter channel:"toRabbit" 
                               amqp-template="amqpTemplate" 
                   exchange-name="my.exchange" 
                   routing-key="test.binding"/>
<int:service-activator input-channel="fromRabbit" 
                       ref="testService" 
                       method="serviceMethod"/>


// from rabbitmq to local channel
<int-amqp:inbound-channel-adapter channel="fromRabbit" 
                                  queue-names="test.queue" 
                                  connection-factory="rabbitConnectionFactory"/>

<int:channel id="fromRabbit"/>
如果不希望使用Springbean中配置的默认通道,可以通过注释在每个方法上指定一个通道

连接到service activator的服务如下所示:

package com.company

import org.springframework.integration.annotation.Gateway

public interface BackgroundService {

    //@Gateway(requestChannel="someOtherMessageChannel")
    public String sayHello(String toWho)

}
package com.company;

class TestService {

    public void serviceMethod(String param) {
    log.info("serviceMethod received: " + param");
    //return "hello, " + param;
    }
}
当我在本地连接所有内容而不涉及rabbitmq时,调用者正确地接收到了返回值。当我转到rabbitmq通道时,当返回值后引发异常时,我得到了前面提到的无限循环。这当然是可能的,否则在不修改代码的情况下连接不同的通道是不可能的,但我还不确定这个技巧是什么。如果你明白了,请给出解决方案。显然,您可以根据需要在端点之间放置您喜欢的任何路由、转换和过滤


如果我上面的XML摘录中有打字错误,请不要感到惊讶。我必须从groovy DSL转换回xml,所以我可能会犯错误。但是意图应该足够清楚。

我注意到cafe示例也有一个启用amqp的配置,并由此计算出双向(返回值)通信。配置int amqp:入站网关和int amqp:出站网关,而不是配置入站通道适配器和出站通道适配器。您只需更改标记名,并保留上面示例中的所有属性(但将“通道”重命名为“请求通道”)。显然,你可以指定一个特定的回复频道,而不是使用默认频道,但我在尝试时出错了。嗨,你能让它工作吗?我也有类似的问题