2016-08-09 234 views
0

Ich habe ein HTTP Inbound Gateway in meiner Integration Application, die ich während einer Speicheroperation aufrufen werde. Es ist so. Wenn ich ein Produkt habe, rufe ich die API einmal an, und wenn ich mehr als einmal habe, rufe ich mehrmals an. Das Problem besteht darin, dass SI einfach funktionieren kann. Aber für mehrere Anrufe werden Anfrage und Antwort durcheinander gebracht. Ich dachte, dass Spring Integration Channels genau wie MQs sind, aber das ist es nicht?Spring Integration HTTP Eingehende Gateway Request Overlap

Lassen Sie mich das erklären. Sagen wir, ich habe 2 Produkte. Zuerst rufe ich SI für Produkt A und dann für B auf. Antwort von A wurde auf Anforderung B abgebildet! Es passiert ständig. Ich möchte keine dreckigen Hacks verwenden, wie zum Beispiel darauf, dass die erste Antwort kommt und wieder aufruft. Dies bedeutet, dass das System lange warten muss. Ich schätze, wir können es in der Spring Integration mit dem Task Executor machen, aber mit all den grundlegenden Samples kann ich nicht den richtigen finden. Also bitte hilf mir herauszufinden, wie ich dieses Problem beheben kann!

Meine Konfiguration ist:

<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"/> 

Das i2nInvokeFromPOS Gateway ist das, was wir von Web Application aufrufen, die ist, wo alle Produkte erstellt werden. Diese Integrations-API ruft diese Daten ab und speichert sie im Backend-System, damit sie auch an den anderen POS-Standorten aktualisiert werden.

Schritte:

  1. Ich werde die productId zu i2nInvokeFromPOS senden.

  2. apiTransformer -> retrieveProductJson() -Methode wird die Produktdetails von DB holen basierend auf der ID

  3. senden und die JSON Anfrage an Backend-System http: Outbound-Gateway

  4. Erhalten Sie die Antwort Backend und aktualisieren Sie den Produktstatus, wie in DB hochgeladen. Geschieht in apiService -> productResponse()

Sobald die Antwort für A empfangen wird, alles, was ich bin immer für die Anforderung B HTTP 500 Error! Aber die Backend-API ist in Ordnung.

Antwort

0

Das Framework ist vollständig Thread-sicher - wenn Sie ein Nebeneinandertreffen zwischen verschiedenen Anforderungen/Antworten sehen, dann ist eine (oder mehrere) Ihrer Komponenten, die das Framework aufruft, nicht Thread-sicher.

Sie können den Status in Feldern nicht beibehalten, z. B. in Code, der von einem Dienstaktivator aufgerufen wird.

+0

Was würden Sie vorschlagen? Ich verstehe nicht, was Sie damit sagen: "Sie können den Status in Feldern nicht halten, beispielsweise in Code, der von einem Dienstaktivator aufgerufen wird." – Rajkumar

+1

Jede HTTP-Anfrage kommt in einem separaten Thread. Sie müssen Ihre Objekte threadsicher machen, indem Sie keine Daten in Feldern speichern, oder mit einer geeigneten Synchronisation, wenn Sie das Übersprechen zwischen Threads vermeiden möchten. Lesen Sie ein gutes Buch zur Thread-sicheren Programmierung. –

+0

Vom Frontend-System aus rufe ich diesen Dienst über ExecutorService auf. Also ich denke es ist threadsicher. Und nein, ich speichere keine Daten irgendwo. Alles, was ich tue, ist, senden ID aus POS -> Details aus der DB abrufen -> senden Sie es an BackEnd -> Antwort erhalten -> in DB basierend auf der Antwort erhalten. Bevor jedoch die zweite Antwort SI erreicht, schließt sie den Kanal mit einem HTTP 500-Fehler. Darüber habe ich geforscht. – Rajkumar