On Thu, Sep 7, 2017 at 3:59 AM, Yasser Zamani <yasser.zam...@live.com>
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!
>
> 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!
>
> 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()));
>      }
>

I'm not 100% sure, but it seems the doGet method code here is not correct.


>
>      @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
>



-- 
Guang <http://javadevnotes.com/java-long-to-string-examples/>

Reply via email to