2016-06-16 18 views
2

Ich benutze Apache Camel 2.15 und fand ein interessantes Verhalten. Ich stelle Daten, die über einen REST-API-Aufruf empfangen wurden, in eine Camel-Route, die ein direkter Endpunkt ist. Diese Route verwendet wiederum den geteilten EIP und ruft eine andere Camel-Route auf, die auch ein direkter Endpunkt ist.Camel Split EIP und Verwendung von Threads im Pool scheint nicht über min Threads gehen

Hier ist, was der entsprechende Code Camel wie

from("direct:activationInputChannel").routeId("cbr_activation_route") 
// removed some processes 
.split(simple("${body}")) 
    .parallelProcessing() 
    .to("direct:activationItemEndPoint") 
.end() 
// removed some processes 

und

from("direct:activationItemEndPoint").routeId("cbr_activation_item_route") 
.process(exchange -> this.doSomething(exchange)) 
// removed some processes 

Die Verwendung des direkten Endpunkt sieht die Anrufe führen synchron zu sein und auf dem gleichen Thread ausgeführt werden. Wie erwartet, bewirkt die Verwendung von Split/ParallelProcessing, dass die zweite Route in einem separaten Thread ausgeführt wird. Der Splitter verwendet den Standard-Thread-Pool.

Als ich einige Lasttests gegen die Anwendung mit jMeter durchführte, stellte ich fest, dass die Split-Route zu einem Engpass wurde. Bei einem Lasttest mit 200 Threads beobachtete ich den Tomcat-HTTP-Thread-Pool mit einem currentThreadCount von 200 in jConsole. Ich beobachtete auch die Camel Route cbr_activation_route hatte 200 ExchangesInflight.

enter image description here

Das Problem war die cbr_activation_item_route hatte nur 50 ExchangesInflight. Die Zahl 50 entspricht dem poolSize-Set für den Standardpool. Die maxPoolSize wurde auf 500 gesetzt und die maxQueueSize wurde auf 1000 (Standard) gesetzt.

Die Anzahl der Inflight-Exchanges für diese Route stieg nie über die Mindestpoolgröße. Obwohl viele Anfragen in der Warteschlange standen und Threads verfügbar waren. Als ich die poolSize im Standard-Thread-Pool von Camel auf 200 änderte, verwendete der cbr_activation_item_route den neuen minimalen Wert und hatte 200 ExchangesInflight. Es scheint, dass Camel nicht mehr Threads als das Minimum verwenden würde, auch wenn mehr Threads zur Verfügung standen und sogar unter Last.

Gibt es eine Einstellung oder etwas, das ich vermissen könnte, das dieses Verhalten verursacht? Warum sollte Camel 200 Threads im ersten Testlauf nicht verwenden, wenn das Minimum auf 50 gesetzt wurde?

Danke

+0

Aber dann sagst du: "Als ich die poolSize auf 200 änderte, hatte die cbr_activation_item_route 200 ExchangeSnflight." Es ist nicht klar, was das Problem für mich ist. – javamonkey79

+0

Der erste Test hatte einen Camel-Pool von 50 Minuten und 500 Max-Threads. Wenn Camel 200 aktive Anfragen auf der ersten Route hatte (Inflight Exchange), verwendete der Split nur die min 50. Es scheint, dass es mehr Threads gegriffen haben sollte, da die Leistung nicht großartig war. Ich erhöhte min auf 200 und die Aufteilung war dann in der Lage, 200 Inflationsaustausche zu haben. Bei einem Maximum von 500 hätte ich nicht gedacht, dass ich die Min erhöhen müsste, um Camel dazu zu bringen, mehr Threads zu verwenden. –

+0

klärte dies in der obigen Frage (hoffentlich). –

Antwort

1

Das ist das erwartete Verhalten. Dies hat nichts mit Camel selbst zu tun, sondern mit Javas ThreadPoolExecutor im Allgemeinen.

Wenn Sie die verknüpften Dokumente zu lesen, da heißt es:

Wenn es mehr als corePoolSize sind aber weniger als maximumPoolSize Threads ausgeführt wird, ein neuer Thread wird nur erstellt, wenn die Warteschlange voll ist.

Wenn Sie maxQueueSize-1.000 gesetzt, Sie haben 1050 Anfragen zu erstellen, bevor neue Themen erstellt werden, bis zu 200 Versuchen Kamel erzählt eine SynchronousQueue zu verwenden, wenn Sie Ihre Anforderungen in der Warteschlange werden nicht möchten (nicht empfohlen , MEINER BESCHEIDENEN MEINUNG NACH).

+0

danke. Ich habe den 'ThreadPoolExecutor 'gelesen und ich sehe, dass das jetzt das beabsichtigte Verhalten ist. –

+0

als eine Seite eine Menge unserer niedrigen Leistung - die wir dachten, war in Bezug auf die Split EIP nicht auf weitere Threads zugreifen - war die Standardeinstellung für die HTTP4-Komponente. Es stellt sich heraus, dass die standardmäßige 'connectionsPerRoute' 20 ist und wir einen anderen REST-Dienst von der Split-Route aufrufen. Das Erhöhen dieses Wertes hilft sehr. :) –

3

Stimmen Sie mit Fredericos Antwort über das Verhalten des Thread Pool Executors von Java überein. Es zieht es vor, neue Anforderungen in die Warteschlange einzufügen, anstatt weitere Threads zu erstellen, nachdem 'corePoolSize'-Threads erreicht wurden.

Wenn Ihr TPE nach dem Erreichen von 'corePoolSize' weitere Threads hinzufügen soll, gibt es einen etwas hackigen Weg, da Java die Methode 'offer()' in BlockingQueue aufruft die Anfragen. Wenn die Methode offer() false zurückgibt, erstellt sie einen neuen Thread und ruft den executoredExecutionHandler des Executors auf. Es ist möglich, die Methode offer() zu überschreiben und eine eigene Version des ThreadPool-Executors zu erstellen, die die Anzahl der Threads basierend auf dem Ladevorgang skalieren kann.

fand ich ein Beispiel dafür hier: „Die Anzahl der Inflight Börsen für diese Strecke nie über der min Poolgröße rose“ https://github.com/kimchy/kimchy.github.com/blob/master/_posts/2008-11-23-juc-executorservice-gotcha.textile