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