-
Notifications
You must be signed in to change notification settings - Fork 41k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add property to configure the queue size for Tomcat #36087
Comments
After some more investigation:
I would have expected that, when setting this to 1, the OS declines new connection requests after 1 request is in the accept queue. This is not the case on MacOS, this parameter doesn't seem to have any effect, as clients still wait in some queue. This queue is not the executor queue of the protocol handler. I'll check again with Linux if this has an effect there. On Linux, it seems to work. At least, netstat reports that the listen queue overflowed (MacOS doesn't do that):
A client still hangs until the client timeout is reached. |
After some discussion and taking a look at Jetty, we decided to add a property which lets users limit the Tomcat queue size. We default that property to the same default Tomcat has (unbounded), because we generally try to stick to the default behavior of each container so that users who are already familiar with Tomcat get a similar experience when using it embedded in Boot. With that property you can configure both Jetty and Tomcat to behave the same way: they print a log when the queue overflows and immediately drop the connection. We should also revisit the descriptions of What I found out so far:
After this issue is resolved: To get the behavior of immediately closing the connection when the queue is full and no request handling threads are available, set the property |
Problems: - When setting an executor, we need to stop the old one - When setting an executor, Tomcat will no longer on shutdown stop it - Q: is there a way to only configure the TaskQueue on the existing handler?
I looked at how this could be implemented and stumbled over some problems. There's no easy way to customize the
You also can't get the I think a better approach would be to ask the Tomcat team if they could provide a configuration parameter |
Problems: - When setting an executor, Tomcat will no longer on shutdown stop it - Q: is there a way to only configure the TaskQueue on the existing handler?
Hey there, Are you still working on this? I'm not quite sure if I've got it right. Are you saying that multiple tasks get piled up in the task queue when making several requests through a single connection? Does that mean the "task queue" holds all these "request tasks"? I mean, n requests put n elements in the queue, it doesn't matter if they are through the same connection....? |
Hey! No, it's involving multiple connections. The load generator closes the connection after some time, and opens a new one. But the closed connection still lingers in the queue until Tomcat wants to work on it, then sees that it's closed, and then removes it from the queue. At least that is what I think, I'm not that familiar with Tomcat internals. |
I have recently conducted a test using HTTP/2 and multiplexing to handle numerous requests within a single connection. I can affirm that this approach allows for the concurrent generation of multiple requests through a single connection, which can potentially lead to the queue expanding well beyond the defined limit set by the "max-connections" parameter. This underscores the importance of also considering a limit on the queue size, often referred to as the "max queue size." |
Problems: - Q: is there a way to only configure the TaskQueue on the existing handler?
Problems: - Q: is there a way to only configure the TaskQueue on the existing handler?
Tomcat already offers
I don't believe this is possible, tomcat create an executor here if none is defined; it uses |
Problems: - When setting an executor, Tomcat will no longer on shutdown stop it - Q: is there a way to only configure the TaskQueue on the existing handler?
Hey @ahmedhus, thanks for working on that! With your changes, I now have something which works. Unfortunately we missed the merge window for Boot 3.2, but I will merge it in 3.3 then. Changes are here: https://github.com/mhalbritter/spring-boot/tree/mh/36087-add-property-to-configure-the-queue-size-for-tomcat |
As of now, the request processing queue size of Tomcat can't be adjusted and defaults to an unbounded queue (this is due to the code in
org.apache.tomcat.util.net.AbstractEndpoint#createExecutor
).There are two properties named
server.tomcat.accept-count
andserver.tomcat.max-connections
but they work on the TCP connection level, and with HTTP/1.1 keep-alive/pipelining and HTTP/2 multiplexing multiple requests onto one connection this doesn't cut it.We added it for Jetty via this PR where it was decided to not do it for Tomcat as we already have
accept-count
andmax-connections
.Right now, out of the box, a Tomcat application which takes 5 second for a response can be easily overwhelmed because the connections pile up in the queue. Even after stopping the load generator, the application takes some time to recover and to clear the queue.
There's a workaround in code:
This limits the queue to 100. When doing it that way, Tomcat closes the socket immediately when the queue is full.
I think we should reconsider adding a
server.tomcat.threads.max-queue-capacity
property. WDYT?The text was updated successfully, but these errors were encountered: