2016-12-15 4 views
1

Wir haben eine Anwendung mit ungefähr 75 partitionierten Schritten, verteilt auf 100 Jobs. Unsere Konfiguration für den Outbound-Gateway ist:JmsOutboundGateway: Manuelles Starten und Stoppen

<int-jms:outbound-gateway 
    id="outbound-gateway_1" 
    auto-startup="true" 
    connection-factory="jmsConnectionFactory" 
    request-channel="jms.requests_1" 
    request-destination="jms.requestsQueue" 
    reply-channel="jms.reply_1" 
    reply-destination="jms.repliesQueue" 
    receive-timeout="${timeout}" 
    correlation-key="JMSCorrelationID" > 
    <int-jms:reply-listener receive-timeout="1000"/> 
</int-jms:outbound-gateway> 

Wenn Autostart = "true" sehen wir den replyListener Thread für jeden Ausgangs-Gateway. Um diesen zusätzlichen Lade- und Ressourcenverbrauch zu entfernen, wechseln wir zu autostart = "false" und fügen einen Schrittlistener für den partitionierten Schritt hinzu, der das Gateway in den beforeStep- und afterStep-Methoden startet und stoppt. Beim Serverstart sind die AntwortListener-Threads nicht wie erwartet vorhanden. Sie erscheinen während der Ausführung des Schritts, werden aber nach dem Aufruf nicht entfernt, um auf dem Outbound-Gateway zu stoppen (auch nach längerem Warten).

Wird zur Bereinigung des replyListener noch etwas benötigt?

+0

Woher wissen Sie, dass diese Threads immer noch da sind? Und welche Version von Spring Integration verwenden Sie? Danke –

Antwort

0

OK, ich verstehe was du meinst. Das sieht aus wie:

while ((active = isActive()) && !isRunning()) { 
    if (interrupted) { 
     throw new IllegalStateException("Thread was interrupted while waiting for " + 
       "a restart of the listener container, but container is still stopped"); 
    } 
    if (!wasWaiting) { 
      decreaseActiveInvokerCount(); 
    } 
    wasWaiting = true; 
    try { 
     lifecycleMonitor.wait(); 
    } 
    catch (InterruptedException ex) { 
     // Re-interrupt current thread, to allow other threads to react. 
     Thread.currentThread().interrupt(); 
     interrupted = true; 
    } 
} 

im DefaultMessageListenerContainer.AsyncMessageListenerInvoker.executeOngoingLoop()

Der Punkt gibt lifecycleMonitor.wait(); ist und achten Sie auf die Nachricht des IllegalStateException.

Nicht sicher, was der Zweck eines solchen Designs ist, aber wir haben keine Wahl, es sei denn, wir leben damit.

Weiterhin basiert die Logik in start() auf dem this.pausedTasks lokalen Cache, der während doInitialize() gefüllt wird, wenn Container !this.running.

Fühlen Sie sich frei, eine JIRA zu erhöhen, wenn Sie denken, dass die Logik irgendwie geändert werden muss.

+0

Alle unsere Partitionen Partition Jobs hören auf die gleiche JMS-Warteschlange und verwenden verschiedene Kanäle. Gibt es eine Möglichkeit, die Outbound-Gateways so zu konfigurieren, dass sie die gleiche replyListener-Instanz verwenden und nur 1 ausgeführt werden müsste (loswerden von Start und Stopp?) –

+0

Überlegen Sie nicht, dass Sie < 'verwenden Ich bin sogar nicht sicher, dass Sie für Ihr dynamisches Beispiel ein statisches "reply-destination" benötigen. Eine "TemporaryQueue" -Lösung sollte ausreichen. –

+0

Verwenden Sie einen externen Task-Executor, der kurzlebige Tasks bevorzugt oder explizit max-messages festlegt -per-task "(mit diesem Executor-Typ auf 10 gesetzt). Wenn max. Nachrichten pro Task> 0 sind, wird der Thread beendet (oder in den Pool zurückgestellt), anstatt auf diesem Monitor zu blockieren. –

Verwandte Themen