Thanks for your attention. Now I downloaded a fresh apache-tomcat-7.0.81-windows-x64 and chenged it's connector in same way (BIO,20,20,10). I get same result, fortunately :)
OUTPUT: Using CATALINA_BASE: "C:\Users\user\.IntelliJIdea2016.3\system\tomcat\Unnamed_Async-Servlet-Example_2" Using CATALINA_HOME: "C:\Users\user\Downloads\apache-tomcat-7.0.81-windows-x64-IJ\apache-tomcat-7.0.81" Using CATALINA_TMPDIR: "C:\Users\user\Downloads\apache-tomcat-7.0.81-windows-x64-IJ\apache-tomcat-7.0.81\temp" Using JRE_HOME: "E:\jdk1.7.0_79" INFO: Server version: Apache Tomcat/7.0.81 INFO: Server built: Aug 11 2017 10:21:27 UTC INFO: Server number: 7.0.81.0 INFO: OS Name: Windows 8.1 INFO: OS Version: 6.3 INFO: Architecture: amd64 INFO: Java Home: E:\jdk1.7.0_79\jre INFO: JVM Version: 1.7.0_79-b15 INFO: JVM Vendor: Oracle Corporation INFO: CATALINA_BASE: C:\Users\user\.IntelliJIdea2016.3\system\tomcat\Unnamed_Async-Servlet-Example_2 Container MAX used threads: 10 Sincerely Yours, Yasser. On 9/8/2017 2:30 AM, Mark Thomas wrote: > 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 > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org