Return-Path: X-Original-To: apmail-camel-dev-archive@www.apache.org Delivered-To: apmail-camel-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 65D86803B for ; Wed, 10 Aug 2011 09:49:45 +0000 (UTC) Received: (qmail 37916 invoked by uid 500); 10 Aug 2011 09:49:45 -0000 Delivered-To: apmail-camel-dev-archive@camel.apache.org Received: (qmail 37222 invoked by uid 500); 10 Aug 2011 09:49:37 -0000 Mailing-List: contact dev-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list dev@camel.apache.org Received: (qmail 37190 invoked by uid 99); 10 Aug 2011 09:49:32 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Aug 2011 09:49:32 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=5.0 tests=FREEMAIL_FROM,NORMAL_HTTP_TO_IP,RCVD_IN_DNSWL_LOW,SPF_PASS,T_TO_NO_BRKTS_FREEMAIL,WEIRD_PORT X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of claus.ibsen@gmail.com designates 209.85.210.43 as permitted sender) Received: from [209.85.210.43] (HELO mail-pz0-f43.google.com) (209.85.210.43) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Aug 2011 09:49:28 +0000 Received: by pzk1 with SMTP id 1so2251623pzk.30 for ; Wed, 10 Aug 2011 02:49:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type:content-transfer-encoding; bh=OA8qXXQ3HPD0Pj/MsFExaKDveQ79Slxw1sXrsYfwomY=; b=OwGyM1xiyDR33xXpoHHjA/VZ7jcbiDSLUQEqOeIQMzRqjWREn9/La3iubpaG2DBRSv tSsULEyAx9LOltc0NQf+qz+2oNr7GYofoAKMpTOy8d+usnNAYRV+jLdZEfeUQ0noEnnp P+o3Ib1TDZMn2Pdr2hsh7q2ESjBLl2FYN1n9o= Received: by 10.142.150.38 with SMTP id x38mr5140212wfd.128.1312969741068; Wed, 10 Aug 2011 02:49:01 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.54.9 with HTTP; Wed, 10 Aug 2011 02:48:41 -0700 (PDT) In-Reply-To: <4E415E6B.2010207@die-schneider.net> References: <4E415E6B.2010207@die-schneider.net> From: Claus Ibsen Date: Wed, 10 Aug 2011 11:48:41 +0200 Message-ID: Subject: Re: [DISCUSS] - JmsConsumer support for asynchronous routing engine - Higher scalability To: dev@camel.apache.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On Tue, Aug 9, 2011 at 6:20 PM, Christian Schneider wrote: > Hi Claus, > > without changing anything in camel wouldn=B4t a simple change in the rout= e > also work? > > from("activemq:queue:inbox?synchronous=3Dtrue") > .threads() > .to("jetty:http://0.0.0.0:9432/myapp") > .to("log:result?groupSize=3D10", "mock:result"); > > So I ask myself if we really need async support in the jms consumer if we > can support the scenario using a well known dsl element. > Using threads is not exactly the same. But its is related. Without threads, you only have the thread of the JMS consumer. And the JMS consumer thread will run at a pace that the system can handle. It will now consume messages from the JMS broker, faster than Camel can handle it. For example if the other pieces in the routes are synchronous, then it will keep being synchronous. Its only because Jetty supports asynchronous, we are able to scale so high using JMS + Jetty. Here is a link with the components that native support async routing engine http://camel.apache.org/asynchronous-routing-engine.html If you use threads DSL, then you introduce a thread pool, with task queue layer. So now you have more active threads in the system. The threads DSL have a task queue, so the JMS consumer would be able to run faster, then Camel can handle it. By this I mean the JMS consumer can consume JMS messages from the JMS broker so fast, and hand over the messages to the threads DSL, and have the message stored in the thread pool task queue. And it can do this faster than the worker threads from the thread pool, so messages will pile up. To remedy this you would have to throttle the JMS consumer, or add more worker threads, if that is possible. Also you have the complexity what to do if the task queue has an upper limit, should you reject the task, wait, discard existing tasks, or steal the consumer thread, and have it execute as it was a worker thread etc. Also the JMS message would be acknowledged and thus consumed from the JMS broker point of view. But they are stored in memory in the threads DSL task queue. So in case of a crash, or a shutdown, you would have to wait for all those tasks to complete. All together you have a more complicated situation. You can of course customize the threads DSL to have a lower task queue. In fact you would be able to have no task queue at all (size of 0) but then you have the overhead of handing over the message from the JMS consumer to a thread from the threads DSL etc. Regardless what the current logic in the JmsConsumer is fully synchronous so even if you use threads, the JmsConsumer would block. So we would have to improve the source code to support this. And in the future, eg possible with Camel 3.0+ we will support asynchronous transactions as well, then this becomes even more interesting. > Christian > > > Am 09.08.2011 14:25, schrieb Claus Ibsen: >> >> Hi >> >> See ticket >> https://issues.apache.org/jira/browse/CAMEL-3632 >> >> Take a look at the following routes >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0from("activemq:queue:inbox?synchronous=3D= true") >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 .to("jetty:http://0.0.0.0:9432/m= yapp") >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 .to("log:result?groupSize=3D10",= "mock:result"); >> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 from("jetty:http://0.0.0.0:9432/myapp") >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 .delay(100) >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 .transform(body().prepend("Bye "= )); >> >> >> Its a fairly simple flow JMS -> =A0JETTY -> =A0MOCK >> >> The JMS consumer will by default be in synchronous mode. Ticket >> CAMEL-3632 is to optimize this by supporting asynchronous routing if >> the JMS consumer is *not* transactional, and *not* sending back a >> reply message. >> >> So the scenarios is for high performance one way messaging. >> >> The 2nd route above simulate a little processing time, which takes 100 >> millis. >> >> If we run a test where we send 1000 messages to the queue. How long >> time would it take to process those messages synchronously? Of course >> roughly 1000 * 0.1 sec =3D 100 sec. On my laptop it takes: >> Took: 1 minute (105393 millis) >> >> Now imagine we set synchronous=3Dfalse on the JMS consumer so it runs >> asynchronously. How fast would it then go? Well lets try >> Took: 10.742 seconds (10742 millis) >> >> That is a lot fast, well of couse its about 10x faster, since the JMS >> consumer is not blocked waiting for the JETTY reply. >> However the messages is now not processed in sequence, that is the cost. >> >> To note in both scenarios this was done with 1 JMS consumer thread. I >> did not enable concurrentConsumers. So with the async routing engine >> we could scale and utilize the CPU resources better. >> >> This seems like a great addition. And if we add this, we should add >> some documentation with the pros/cons for using this. >> >> My question is what would a sensitive default setting be? Should we >> let the JMS consumer be kept as synchronous by default, to keep it >> fully backwards compatible. Then end users must manually set >> synchronous=3Dfalse on the JMS endpoint to enable that. >> >> Any thoughts? >> >> >> >> >> >> >> >> >> > > -- > Christian Schneider > http://www.liquid-reality.de > > Open Source Architect > http://www.talend.com > > --=20 Claus Ibsen ----------------- FuseSource Email: cibsen@fusesource.com Web: http://fusesource.com Twitter: davsclaus, fusenews Blog: http://davsclaus.blogspot.com/ Author of Camel in Action: http://www.manning.com/ibsen/