【问题标题】:Spring Integration HTTP Inbound Gateway Request OverlapSpring集成HTTP入站网关请求重叠
【发布时间】:2016-08-09 15:50:17
【问题描述】:

我的集成应用程序中有一个 HTTP 入站网关,我将在某些保存操作期间调用它。就像这样。如果我有一个产品,我会调用 API 一次,如果我有不止一次,我会调用多次。问题是,对于单次调用,SI 工作得很好。但是对于多个调用,请求和响应会变得一团糟。我认为 Spring Integration Channels 就像 MQ 一样,但事实并非如此?

让我解释一下。假设我有 2 个产品。首先,我为产品 A 调用 SI,然后为 B 调用 SI。A 的响应映射到请求 B!它一直在发生。我不想使用一些肮脏的技巧,例如等待第一个响应来并再次调用。这意味着系统必须等待很长时间。我想我们可以使用任务执行器在 Spring Integration 中做到这一点,但是有了所有基本示例,我找不到合适的示例。所以请帮我找出如何解决这个问题!

我的配置是:

<int:channel id="n2iMotorCNInvokeRequest" />
<int:channel id="n2iMotorCNInvokeResponse" />
<int:channel id="n2iInvoketransformerOut" />
<int:channel id="n2iInvokeobjTransformerOut" />
<int:channel id="n2iInvokegatewayOut" />

<int-http:inbound-gateway id="i2nInvokeFromPOS" 
    supported-methods="GET"
    request-channel="i2nInvokeRequest"
    reply-channel="i2nInvokeResponse"
    path="/postProduct/{Id}"
    mapped-response-headers="Return-Status, Return-Status-Msg, HTTP_RESPONSE_HEADERS"
    reply-timeout="50000">
    <int-http:header name="Id" expression="#pathVariables.Id"/>
</int-http:inbound-gateway>

<int:service-activator id="InvokeActivator"
                input-channel="i2nInvokeRequest"
                output-channel="i2nInvokeResponse"
                ref="apiService"
                method="getProductId"
                requires-reply="true"
                send-timeout="60000"/>

<int:transformer input-channel="i2nInvokeResponse"
        ref="apiTransformer"
        method="retrieveProductJson" 
        output-channel="n2iInvokeRequest"/>

<int-http:outbound-gateway request-channel="n2iInvokeRequest" reply-channel="n2iInvoketransformerOut"
    url="http://10.xx.xx.xx/api/index.php" http-method="POST" 
    expected-response-type="java.lang.String">
</int-http:outbound-gateway>


<int:service-activator 
            input-channel="n2iInvoketransformerOut" 
            output-channel="n2iInvokeobjTransformerOut"
            ref="apiService" 
            method="productResponse"
            requires-reply="true"
            send-timeout="60000"/>

i2nInvokeFromPOS 网关是我们从 Web 应用程序调用的网关,所有产品都将在其中创建。此集成 API 将获取该数据,并将其发布到后端系统,以便它也将更新到其他 POS 位置!

步骤:

  1. 我会将 productId 发送到 i2nInvokeFromPOS。

  2. apiTransformer -> retrieveProductJson() 方法将根据 ID 从数据库中获取产品详细信息

  3. 使用 http:outbound-gateway 将请求 JSON 发送到后端系统

  4. 从后端获取响应并更新数据库中上传的产品状态。发生在 apiService -> productResponse()

收到 A 的响应后,我得到的只是请求 B 的 HTTP 500 错误!但是后端 API 很好。

【问题讨论】:

    标签: java spring spring-mvc spring-integration


    【解决方案1】:

    框架是完全线程安全的 - 如果您看到不同请求/响应之间的串扰,那么框架正在调用的一个(或多个)组件不是线程安全的。

    您不能在字段中保留状态,例如,从服务激活器调用的代码。

    【讨论】:

    • 那么你有什么建议?我不明白你在说什么:“你不能在字段中保持状态,例如,从服务激活器调用的代码。”
    • 每个 HTTP 请求都来自一个单独的线程。您需要通过不在字段中存储数据来使您的对象成为线程安全的,或者如果您想避免线程之间的串扰,则需要进行适当的同步。阅读一本关于线程安全编程的好书。
    • 从前端系统,我通过 ExecutorService 调用这个服务。所以我想它是线程安全的。不,我没有在任何地方存储任何数据。我所做的就是,从 POS 发送 ID -> 从 DB 获取相同的详细信息 -> 将其发送到 BackEnd -> 获取响应 -> 根据收到的响应在 DB 中更新。但在第二个响应到达 SI 之前,它会以 HTTP 500 错误关闭通道。这就是我正在挖掘的内容。
    • 与前端系统无关。你说 A 得到 B 的回应(反之亦然) - 现在你说的是别的东西(500)。打开调试日志并遵循消息流 - 确保将线程添加到日志中,以便关联每个线程的所有消息。
    • 您需要查看服务器端的日志以了解生成 500 的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多