On 07/09/17 22:22, Yasser Zamani wrote:
> At first thanks a lot for your reply!
> 
> On 9/7/2017 1:43 PM, Mark Thomas wrote:
>> On 06/09/17 20:59, Yasser Zamani wrote:
>>> Hi there,
>>>
>>> I'm studying Servlet 3's async API using tomcat. I see following strange
>>> behavior from tomcat in a very simple test app!
>>
>> You are also using the BIO connector which, since it is blocking,
>> doesn't offer any benefits when using async. You'd be better off with
>> the NIO connector.
> 
> Yes I know but currently it's not important for me. I am studying 
> Servlet 3's async API and BIO keeps it simpler to study and focus only 
> on it (with NIO I cannot know if something is because of Servlet 3's 
> async API or Tomcat's NIO).
> 
>>
>> You haven't told us which Tomcat version you are using. Since you are
>> using BIO that narrows it down a bit to 7.0.x or 8.0.x but that is still
>> a lot of possibilities.
> 
> It's 7.0.47

You are unlikely to get much interest on this list until you upgrade to
the latest stable 7.0.x (or 8.0.x). So much has changed in the ~4 years
since 7.0.47 that there isn't much value in investigating this. If you
see the same or similar issues with 7.0.81, that would be more interesting.

Mark


> 
>>
>> Neither have you told us what operating system you are using. My
>> experience of JMeter under load, particularly on Windows, is that you
>> see strange behaviour and it can be hard to figure out the interaction
>> of JMeter, the OS network stack and Tomcat.
>>
>> You also haven't told us what hardware this test is running on.
>> Particularly the number of cores available.
>>
> 
> OS Name       Microsoft Windows 8.1 Enterprise
> System Type   x64-based PC
> Processor     Intel(R) Core(TM) i3-4130 CPU @ 3.40GHz, 3400 Mhz, 2 Core(s), 
> 4 Logical Processor(s)
> 
> 
>>> I have following JMeter test plan:
>>> Number of threads (users): 700
>>> Ramp-Up period (in seconds): 23
>>> Loop count: 1
>>>
>>> So JMeter generates 30.43 requests per second and 304.3 requests per 10
>>> seconds. I'm planning to full tomcat's BIO pool and accept buffer :)
>>>
>>> I have an always async test servlet which on destroy, I print tomcat
>>> container max used threads count. It prints 187 for me which is lower
>>> than 200 (tomcat default pool size) so I should not get any "connection
>>> refuse" but I get!
>>
>> There are all sorts of possible reasons for that. I'd suggest scaling
>> down the test. Limit Tomcat to 20 threads. Reduce the load similarly.
>> Increase the sleep time. You want to ensure that the only limit you are
>> hitting is the one you are trying to hit.
>>
> 
> Previously I also tested very low loads but again as you suggested I 
> tested following low load configuration and get even worse results!! 
> Tomcat successfully returns from request below 29th but fails 25 
> requests of 29th to 70th. However this time all fails are "connection 
> refuse" and there are not any "connection reset". Whilst the program 
> output is "Container MAX used threads: 10" !!
> 
> CONFIGURATION #2:
> 
> Server.xml
> <Connector port="7780" protocol="org.apache.coyote.http11.Http11Protocol"
>                 connectionTimeout="120000"
>          maxThreads="20" maxConnections="20" acceptCount="10"
>                 redirectPort="7743" />
> 
> JMeter
> Number of threads (users): 70
> Ramp-Up period (in seconds): 35 (40 requests per 20 seconds)
> Loop count: 1
> 
> My async servlet
> Async Sleep Time: 20 seconds (ensures 40 concurrent requests)
> It's own thread pool size: 41 (lower than 40 so never fulls)
> 
> JMETER RESULT of RESPONSE TIMES #2:
> Max: 38 seconds (lower then tomcat and asyncContext timeout)
> MIN: 20 seconds
> AVG: 18 seconds (because of fails)
> ERR: 36%
> 
> UTPUT:
> 
> Container MAX used threads: 10
> 
> Thanks in advance!
> 
>> Mark
>>
>>
>>> I have simulated a blocking operation by a sleep for 10 seconds. When my
>>> servlet gets a request, it quickly starts an async and add further
>>> processing to my own thread pool (container thread comes back to pool
>>> quickly, right). My own thread pool size is 310 which is greater than
>>> 304.3 (requests in 10 seconds) so never full.
>>>
>>> I've tested several times. Tomcat successfully returns from all requests
>>> below 326th but fails 102 requests from 326th to 700th with "connection
>>> refuse" and afew with "connection reset".
>>>
>>> Why?! My own thread pool does the jobs and Tomcat's pool is free (my
>>> servlet uses 187 threads of tomcat at max).
>>>
>>> Thanks in advance!
>>>
>>> JMETER RESULT of RESPONSE TIMES:
>>> Max: 60 seconds (lower then tomcat and asyncContext timeout)
>>> MIN: 10 seconds
>>> AVG: 37 seconds
>>> ERR: 15%
>>>
>>> CONFIGURATIONS:
>>>
>>> Server.xml
>>> <Connector port="7780" protocol="org.apache.coyote.http11.Http11Protocol"
>>>                 connectionTimeout="120000"
>>>                 redirectPort="7743" />
>>>
>>> Async.java
>>>
>>> package com.sstr.example;
>>>
>>> import javax.servlet.*;
>>> import javax.servlet.annotation.WebInitParam;
>>> import javax.servlet.annotation.WebServlet;
>>> import javax.servlet.http.HttpServlet;
>>> import javax.servlet.http.HttpServletRequest;
>>> import javax.servlet.http.HttpServletResponse;
>>> import java.io.IOException;
>>> import java.util.concurrent.ExecutorService;
>>> import java.util.concurrent.Executors;
>>> import java.util.concurrent.ThreadFactory;
>>>
>>> @WebServlet(
>>>          name = "async",
>>>          value = {"/async"},
>>>          asyncSupported = true,
>>>          initParams = {
>>>                  @WebInitParam(name = "JobPoolSize", value = "310")
>>>          }
>>> )
>>> public class Async extends HttpServlet {
>>>
>>>      public final int REQUEST_TIMEOUT = 120000;
>>>      private ExecutorService exe;
>>>
>>>      @Override
>>>      public void init() throws ServletException {
>>>          int size = Integer.parseInt(getInitParameter("JobPoolSize"));
>>>          exe = Executors.newFixedThreadPool(
>>>                  size,
>>>                  new ThreadFactory() {
>>>                      @Override
>>>                      public Thread newThread(Runnable r) {
>>>                          return new Thread(r, "Async Processor");
>>>                      }
>>>                  }
>>>          );
>>>      }
>>>
>>>      @Override
>>>      protected void doGet(HttpServletRequest req, HttpServletResponse
>>> resp) throws ServletException, IOException {
>>>          final AsyncContext context = req.startAsync();
>>>          context.setTimeout(REQUEST_TIMEOUT);
>>>          exe.execute(new ContextExecution(context,
>>> Thread.currentThread().getName()));
>>>      }
>>>
>>>      @Override
>>>      public void destroy() {
>>>          System.out.println("Container MAX used threads: " + threadCount);
>>>          exe.shutdown();
>>>      }
>>>
>>>      int threadCount = 0;
>>>      class ContextExecution implements Runnable {
>>>
>>>          final AsyncContext context;
>>>          final String containerThreadName;
>>>
>>>          public ContextExecution(AsyncContext context, String
>>> containerThreadName) {
>>>              this.context = context;
>>>              this.containerThreadName = containerThreadName;
>>>          }
>>>
>>>          @Override
>>>          public void run() {
>>>              try {
>>>                  int threadNumber =
>>> Integer.parseInt(containerThreadName.substring(
>>>                          containerThreadName.lastIndexOf('-')+1));
>>>                  if(threadNumber > threadCount) {
>>>                      threadCount = threadNumber;
>>>                  }
>>>
>>>                  // Simulate Time Consuming Task
>>>                  Thread.sleep(10000);
>>>
>>>                  ServletResponse resp = context.getResponse();
>>>                  if (resp != null) {
>>>                      resp.getWriter().write("Ok");
>>>                  }
>>>
>>>                  context.complete();
>>>              } catch (Exception e) {
>>>                  // Handle ?
>>>              }
>>>          }
>>>      }
>>> }
>>>
>>> OUTPUT:
>>>
>>> Container MAX used threads: 187
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
>>> For additional commands, e-mail: users-h...@tomcat.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
>> For additional commands, e-mail: users-h...@tomcat.apache.org
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to