On Fri, 9 Apr 2021, 14:29 Mark Thomas, <ma...@apache.org> wrote: > On 09/04/2021 11:53, Peter Chamberlain wrote: > > Hello, > > I've been trying to understand the behaviour of tomcat when handling > > internal redirects. I'm testing using tomcat 9.0.38. I'm testing using > > jdk8 1.8.0_265. My main test cases have been 2 forwards to the same > > servlet, and then a response. Or 2 redirects to the same servlet and > > then a response. > > The forward case looks like a single HTTP request to both Tomcat and the > client. > > The redirect case looks like 3 separate HTTP requests to both Tomcat and > the client. The first two receive a 302 response (no body) and finally a > 200 response with a body. Depending on how the client and Tomcat are > configured these requests may occur on a single network connection (HTTP > keep-alive is enabled) or may require a separate connection for each > request (HTTP keep-alive is disabled). > > Once you get into the situation where the network layer is over-loaded, > behaviour is very much system dependent. It will vary between operating > systems and between major Java versions. > > Note that the OS treats any accept count setting more as a guideline > than a hard rule and may ignore it completely. Under heavy load you also > often see other effects (such as port exhaustion impacting the results). > > If the backlog is considered to be full, any subsequent connection > attempts will will refused immediately. > > Connection timeout is measured from when the server first tries to read > the request. From that point the client has connectionTimeout to send > the first byte. > > NIO uses a Poller/Selector approach whereas NIO2 uses completion > handlers. In many ways there isn't that much difference between them. I > suspect that NIO will perform better on some systems and NIO2 on others. > > When I have looked at this sort of thing in the past, the results have > nearly always been skewed by other factors. Only by significantly > reducing the number of client threads and Tomcat threads (less than 10 > each) was I able to start to see the sort of behaviour expected around > dropped connections, backlog etc and even then it took a fair amount of > analysis to confirm that what I was observing was as expected. > > Mark >
Okay, that's very helpful. I did find it very difficult to get repeatable results, so I suspect other layers are causing the issues I've noticed. So long as I'm not misunderstanding the configuration options, or missing anything that's fine. Thanks alot, Peter > > Servlet as follows: > > > > @WebServlet(loadOnStartup = 1, value = "/") > > public class ConnectorLimitServlet extends HttpServlet { > > > > @Override > > protected void doGet(HttpServletRequest req, HttpServletResponse > > resp) throws IOException, ServletException { > > int number = Integer.parseInt(req.getParameter("number")); > > // Fake some work done at each stage of processing > > try { Thread.sleep(500); } catch (InterruptedException e) {} > > resp.setContentType("text/plain"); > > if (number <= 1) { > > resp.getWriter().write("Finished " + req.getServletPath()); > > return; > > } > > switch (req.getServletPath()) { > > case "/redirect": > > resp.sendRedirect(new URL(req.getScheme() + "://" + > > req.getServerName() + ":" + req.getServerPort() + > > req.getRequestURI() + "?number=" + (number - > 1)).toString()); > > return; > > case "/forward": > > final String forwardAddress = "/forward?number=" + (number - 1); > > > getServletContext().getRequestDispatcher(forwardAddress).forward(req, > > resp); > > } > > } > > } > > > > > > It seems that under high load, 1000 threads in jmeter, Tomcat will > > refuse some of the connections for nio2 connections but not for nio, > > further it seems that these failures happen considerably earlier than > > the configuration page would suggest would be the case. The > > configuration suggests that if acceptCount is high enough for the > > number of connections then they will be queued prior to reaching the > > processing threads, so a small number of processing threads can exist > > with a queue of connection feeding them, it seems like until > > connectionTimeout is reached connections shouldn't be refused, but > > that is not what occurs. In fact acceptCount seems to have very little > > effect. > > In short, my questions are: > > Why is the nio2 connector type worse at this than nio type? > > Why are connections refused before acceptCount is reached, or > > connectionTimeout is reached? > > I'm guessing that each forward or redirect effectively counts as an > > extra connection, as removing the redirects and multipling the number > > of jmeter threads suggests that is the case, am I correct here? > > > > Also, I feel like it would help if there were better documentation > > around the differences between nio2 and nio, as, for example, the > > connector comparison part makes them sound almost the same. > > > > Apologies if this has been covered elsewhere before, I have been > > searching but haven't found anything particularly clear covering this. > > Best regards, Peter > > > > --------------------------------------------------------------------- > > 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