You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by apatel <ap...@asg.bellsouth.net> on 2013/07/17 19:21:09 UTC

Groovy script synchronized issue with 2.10.x and 2.11.x prevents camel groovy script for High Concurrenc

In below code why method is synchronized? This prevents camel groovy script
for High Concurrency.


protected synchronized Object evaluateScript(Exchange exchange) {
        try {
            getScriptContext();
            populateBindings(getEngine(), exchange);
            addScriptEngineArguments(getEngine(), exchange);
            Object result = runScript(exchange);
            LOG.debug("The script evaluation result is: {}", result);
            return result;
        } catch (ScriptException e) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Script evaluation failed: " + e.getMessage(), e);
            }
            throw createScriptEvaluationException(e.getCause());
        } catch (IOException e) {
            throw createScriptEvaluationException(e);
        }
    }




I've below two routes. When i tested this route with 1 tps it returns
responses in avg 1005 ms but when i tested same route with 5tps it returns
responses in avg 8005 ms. My goal is tuning this routes for High
Concurrency.

<route xmlns="http://camel.apache.org/schema/spring" trace="true">
  <from uri="restlet:/test/v1.0/testGroovyWait"/>
    <to uri="direct:test.directGroovyWait.v1.0"/>
</route>

<route xmlns="http://camel.apache.org/schema/spring" 
errorHandlerRef="noErrorHandler">
 
  <from uri="direct:test.directGroovyWait.v1.0"/>
    <setHeader headerName="foo">
        <groovy> 
             Thread.sleep(1000) 
             return "OK"
        </groovy>
    </setHeader>
        
     <setBody>
        <header>foo</header>
    </setBody>

</route>


I think we've found the root cause of our groovy performance problem. I did
a little testing this morning and found that a single thread test with the
route that waits 1 second had an average response time of about 1005
milliseconds. When I took this to 5 threads the average response time went
up to 4389. When I went to 10 threads the average went to 9169. This is all
without any pauses in the script so each thread is hitting the server as
soon as the result returns.

Here's the pattern of response times at the beginning of the 10 thread test:

1004, 1101, 2201, 3303, 4403, 5504, 6605, 7705, 8806, 9908, 2000, 4001,
6001, 8002, 10003, 12003, 14005, 16005, 18006

Interestingly the 3rd thread took 2.2 seconds, the 4th thread took 3.3
seconds, the 5th thread 5.5 seconds and so on. This clearly pointed to some
sort of semaphore or single resource that each thread was waiting for in
turn.

I took a look at the active threads using console. Here's where most of the
worker threads (http-bio-8080-exec-<n>) were waiting:

Name: http-bio-8080-exec-3
State: BLOCKED on org.apache.camel.builder.script.ScriptBuilder@12349d8
owned by: http-bio-8080-exec-6
Total blocked: 99  Total waited: 271

Stack trace: 
org.apache.camel.builder.script.ScriptBuilder.evaluateScript(ScriptBuilder.java:338)
org.apache.camel.builder.script.ScriptBuilder.evaluate(ScriptBuilder.java:92)
org.apache.camel.builder.script.ScriptBuilder.evaluate(ScriptBuilder.java:96)
org.apache.camel.builder.ProcessorBuilder$4.process(ProcessorBuilder.java:103)
org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) 

from 
 --Doug 










--
View this message in context: http://camel.465427.n5.nabble.com/Groovy-script-synchronized-issue-with-2-10-x-and-2-11-x-prevents-camel-groovy-script-for-High-Concurc-tp5735815.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Groovy script synchronized issue with 2.10.x and 2.11.x prevents camel groovy script for High Concurrenc

Posted by Willem jiang <wi...@gmail.com>.
I think we can cache the ScriptEngine as a thread local variable, and we need to find a way to clean up these variables when the camel route is shutdown.
So I just fill a JIRA[1] for it.

[1] https://issues.apache.org/jira/browse/CAMEL-6559  

--  
Willem Jiang

Red Hat, Inc.
FuseSource is now part of Red Hat
Web: http://www.fusesource.com | http://www.redhat.com
Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/) (English)
          http://jnn.iteye.com (http://jnn.javaeye.com/) (Chinese)
Twitter: willemjiang  
Weibo: 姜宁willem





On Thursday, July 18, 2013 at 3:01 PM, Willem jiang wrote:

> The ScriptEngine evaluate method is not thread safe, I think you can use seda component to cache the request in the queue, then using one consumer to processing the groovy script.
>  
>  
> --  
> Willem Jiang
>  
> Red Hat, Inc.
> FuseSource is now part of Red Hat
> Web: http://www.fusesource.com | http://www.redhat.com
> Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/) (English)
> http://jnn.iteye.com (http://jnn.javaeye.com/) (Chinese)
> Twitter: willemjiang  
> Weibo: 姜宁willem
>  
>  
>  
>  
>  
> On Thursday, July 18, 2013 at 1:21 AM, apatel wrote:
>  
> > In below code why method is synchronized? This prevents camel groovy script
> > for High Concurrency.
> >  
> >  
> > protected synchronized Object evaluateScript(Exchange exchange) {
> > try {
> > getScriptContext();
> > populateBindings(getEngine(), exchange);
> > addScriptEngineArguments(getEngine(), exchange);
> > Object result = runScript(exchange);
> > LOG.debug("The script evaluation result is: {}", result);
> > return result;
> > } catch (ScriptException e) {
> > if (LOG.isDebugEnabled()) {
> > LOG.debug("Script evaluation failed: " + e.getMessage(), e);
> > }
> > throw createScriptEvaluationException(e.getCause());
> > } catch (IOException e) {
> > throw createScriptEvaluationException(e);
> > }
> > }
> >  
> >  
> >  
> >  
> > I've below two routes. When i tested this route with 1 tps it returns
> > responses in avg 1005 ms but when i tested same route with 5tps it returns
> > responses in avg 8005 ms. My goal is tuning this routes for High
> > Concurrency.
> >  
> > <route xmlns="http://camel.apache.org/schema/spring" trace="true">
> > <from uri="restlet:/test/v1.0/testGroovyWait"/>
> > <to uri="direct:test.directGroovyWait.v1.0"/>
> > </route>
> >  
> > <route xmlns="http://camel.apache.org/schema/spring"  
> > errorHandlerRef="noErrorHandler">
> >  
> > <from uri="direct:test.directGroovyWait.v1.0"/>
> > <setHeader headerName="foo">
> > <groovy>  
> > Thread.sleep(1000)  
> > return "OK"
> > </groovy>
> > </setHeader>
> >  
> > <setBody>
> > <header>foo</header>
> > </setBody>
> >  
> > </route>
> >  
> >  
> > I think we've found the root cause of our groovy performance problem. I did
> > a little testing this morning and found that a single thread test with the
> > route that waits 1 second had an average response time of about 1005
> > milliseconds. When I took this to 5 threads the average response time went
> > up to 4389. When I went to 10 threads the average went to 9169. This is all
> > without any pauses in the script so each thread is hitting the server as
> > soon as the result returns.
> >  
> > Here's the pattern of response times at the beginning of the 10 thread test:
> >  
> > 1004, 1101, 2201, 3303, 4403, 5504, 6605, 7705, 8806, 9908, 2000, 4001,
> > 6001, 8002, 10003, 12003, 14005, 16005, 18006
> >  
> > Interestingly the 3rd thread took 2.2 seconds, the 4th thread took 3.3
> > seconds, the 5th thread 5.5 seconds and so on. This clearly pointed to some
> > sort of semaphore or single resource that each thread was waiting for in
> > turn.
> >  
> > I took a look at the active threads using console. Here's where most of the
> > worker threads (http-bio-8080-exec-<n>) were waiting:
> >  
> > Name: http-bio-8080-exec-3
> > State: BLOCKED on org.apache.camel.builder.script.ScriptBuilder@12349d8
> > owned by: http-bio-8080-exec-6
> > Total blocked: 99 Total waited: 271
> >  
> > Stack trace:  
> > org.apache.camel.builder.script.ScriptBuilder.evaluateScript(ScriptBuilder.java:338)
> > org.apache.camel.builder.script.ScriptBuilder.evaluate(ScriptBuilder.java:92)
> > org.apache.camel.builder.script.ScriptBuilder.evaluate(ScriptBuilder.java:96)
> > org.apache.camel.builder.ProcessorBuilder$4.process(ProcessorBuilder.java:103)
> > org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
> > org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)  
> >  
> > from  
> > --Doug  
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> > --
> > View this message in context: http://camel.465427.n5.nabble.com/Groovy-script-synchronized-issue-with-2-10-x-and-2-11-x-prevents-camel-groovy-script-for-High-Concurc-tp5735815.html
> > Sent from the Camel - Users mailing list archive at Nabble.com (http://Nabble.com).
>  




Re: Groovy script synchronized issue with 2.10.x and 2.11.x prevents camel groovy script for High Concurrenc

Posted by Willem jiang <wi...@gmail.com>.
The ScriptEngine evaluate method is not thread safe, I think you can use seda component to cache the request in the queue, then using one consumer to processing the groovy script.


--  
Willem Jiang

Red Hat, Inc.
FuseSource is now part of Red Hat
Web: http://www.fusesource.com | http://www.redhat.com
Blog: http://willemjiang.blogspot.com (http://willemjiang.blogspot.com/) (English)
          http://jnn.iteye.com (http://jnn.javaeye.com/) (Chinese)
Twitter: willemjiang  
Weibo: 姜宁willem





On Thursday, July 18, 2013 at 1:21 AM, apatel wrote:

> In below code why method is synchronized? This prevents camel groovy script
> for High Concurrency.
>  
>  
> protected synchronized Object evaluateScript(Exchange exchange) {
> try {
> getScriptContext();
> populateBindings(getEngine(), exchange);
> addScriptEngineArguments(getEngine(), exchange);
> Object result = runScript(exchange);
> LOG.debug("The script evaluation result is: {}", result);
> return result;
> } catch (ScriptException e) {
> if (LOG.isDebugEnabled()) {
> LOG.debug("Script evaluation failed: " + e.getMessage(), e);
> }
> throw createScriptEvaluationException(e.getCause());
> } catch (IOException e) {
> throw createScriptEvaluationException(e);
> }
> }
>  
>  
>  
>  
> I've below two routes. When i tested this route with 1 tps it returns
> responses in avg 1005 ms but when i tested same route with 5tps it returns
> responses in avg 8005 ms. My goal is tuning this routes for High
> Concurrency.
>  
> <route xmlns="http://camel.apache.org/schema/spring" trace="true">
> <from uri="restlet:/test/v1.0/testGroovyWait"/>
> <to uri="direct:test.directGroovyWait.v1.0"/>
> </route>
>  
> <route xmlns="http://camel.apache.org/schema/spring"  
> errorHandlerRef="noErrorHandler">
>  
> <from uri="direct:test.directGroovyWait.v1.0"/>
> <setHeader headerName="foo">
> <groovy>  
> Thread.sleep(1000)  
> return "OK"
> </groovy>
> </setHeader>
>  
> <setBody>
> <header>foo</header>
> </setBody>
>  
> </route>
>  
>  
> I think we've found the root cause of our groovy performance problem. I did
> a little testing this morning and found that a single thread test with the
> route that waits 1 second had an average response time of about 1005
> milliseconds. When I took this to 5 threads the average response time went
> up to 4389. When I went to 10 threads the average went to 9169. This is all
> without any pauses in the script so each thread is hitting the server as
> soon as the result returns.
>  
> Here's the pattern of response times at the beginning of the 10 thread test:
>  
> 1004, 1101, 2201, 3303, 4403, 5504, 6605, 7705, 8806, 9908, 2000, 4001,
> 6001, 8002, 10003, 12003, 14005, 16005, 18006
>  
> Interestingly the 3rd thread took 2.2 seconds, the 4th thread took 3.3
> seconds, the 5th thread 5.5 seconds and so on. This clearly pointed to some
> sort of semaphore or single resource that each thread was waiting for in
> turn.
>  
> I took a look at the active threads using console. Here's where most of the
> worker threads (http-bio-8080-exec-<n>) were waiting:
>  
> Name: http-bio-8080-exec-3
> State: BLOCKED on org.apache.camel.builder.script.ScriptBuilder@12349d8
> owned by: http-bio-8080-exec-6
> Total blocked: 99 Total waited: 271
>  
> Stack trace:  
> org.apache.camel.builder.script.ScriptBuilder.evaluateScript(ScriptBuilder.java:338)
> org.apache.camel.builder.script.ScriptBuilder.evaluate(ScriptBuilder.java:92)
> org.apache.camel.builder.script.ScriptBuilder.evaluate(ScriptBuilder.java:96)
> org.apache.camel.builder.ProcessorBuilder$4.process(ProcessorBuilder.java:103)
> org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
> org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)  
>  
> from  
> --Doug  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
> --
> View this message in context: http://camel.465427.n5.nabble.com/Groovy-script-synchronized-issue-with-2-10-x-and-2-11-x-prevents-camel-groovy-script-for-High-Concurc-tp5735815.html
> Sent from the Camel - Users mailing list archive at Nabble.com (http://Nabble.com).