You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Максим Гумеров <mg...@gmail.com> on 2018/05/11 17:21:14 UTC

acceptCount with NIO and Tomcat 8

Hi! I am running Tomcat 8 as part of Spring Boot application. As usual,
acceptCount defaults to 100 and maxThreads to 200. According to
https://tomcat.apache.org/tomcat-8.5-doc/config/http.html#NIO_specific_configuration
I am expecting Tomcat to accept 200 "long" requests (each taking say 20
seconds to complete), then accept 100 more connections but not start
reading from them, and then reject any connection requests beyond that.
That's why this is the expected behavior: acceptCount = "The maximum queue
length for incoming connection requests when all possible request
processing threads are in use. Any requests received when the queue is full
will be refused." So, when first 200 requests are all taken by 200
processing threads, next 100 will go to the queue and subsequent will be
ignored. At least that's how it reads to me.

But what I actually see on my Mac is, tomcat successfully accepts a little
short of 1000 such connections (I just didn't try more connections) made
within 5 seconds. It processes no more than 200 requests at a time, but
does not reject connections after 300th one, as one would expect.

What's the explanation for that? Can the quoted documentation be imprecise
or outdated? Or am I missing something in it?

I tried to ask the same question on stackoverflow, to little success:
https://stackoverflow.com/questions/50079513/tomcat-and-acceptcount-not-working

Thanks,
Maksim

Re: acceptCount with NIO and Tomcat 8

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Максим,

On 5/11/18 10:21 PM, Максим Гумеров wrote:
>> 
>> On 11/05/18 18:21, Максим Гумеров wrote:
>>> Hi! I am running Tomcat 8 as part of Spring Boot application.
>>> As usual, acceptCount defaults to 100 and maxThreads to 200.
>>> According to 
>>> https://tomcat.apache.org/tomcat-8.5-doc/config/http.html#NIO_specif
ic_
>>
>>> 
configuration
>>> I am expecting Tomcat to accept 200 "long" requests (each
>>> taking say 20 seconds to complete), then accept 100 more
>>> connections but not start reading from them, and then reject
>>> any connection requests beyond that. That's why this is the
>>> expected behavior: acceptCount = "The maximum
>> queue
>>> length for incoming connection requests when all possible
>>> request processing threads are in use. Any requests received
>>> when the queue is
>> full
>>> will be refused." So, when first 200 requests are all taken by
>>> 200 processing threads, next 100 will go to the queue and
>>> subsequent will be ignored. At least that's how it reads to
>>> me.
>>> 
>>> But what I actually see on my Mac is, tomcat successfully
>>> accepts a
>> little
>>> short of 1000 such connections (I just didn't try more
>>> connections) made within 5 seconds. It processes no more than
>>> 200 requests at a time, but does not reject connections after
>>> 300th one, as one would expect.
>>> 
>>> What's the explanation for that? Can the quoted documentation
>>> be
>> imprecise
>>> or outdated? Or am I missing something in it?
>> 
>> acceptCount for NIO is passed in to
>> ServerSocket.bind(SocketAddress,int) as the 2nd parameter
>> (backlog). The Javadoc for that method says:
>> 
>> <quote> The backlog argument is the requested maximum number of
>> pending connections on the socket. Its exact semantics are
>> implementation specific. In particular, an implementation may
>> impose a maximum length or may choose to ignore the parameter
>> altogether. </quote>
>> 
>> It looks like it is being ignored in your JVM.
>> 
>> Mark
>> 
> 
> Thank you, this looks like one possible explanation. Maybe someone
> else will show me some other.
> 
> But, considering what you say, isn't that a documentation
> deficiency? They shouldn't write "acceptCount is the length of
> connection queue" if it's just a hint. Or, they could just add a
> note that actual queue length may be chosen by implementation
> instead. Also, they shouldn't write " up to the configured maximum
> (the value of the acceptCount attribute)", better formulation is
> "up to connection queue size (based on acceptCount attribute)".
> What's written there now simply contradicts the implementation,
> right?

It looks like the "introduction" section of this page is misleading:
https://tomcat.apache.org/tomcat-8.0-doc/config/http.html#Introduction

It documents the reality for BIO, but not for NIO connectors, which
are *much* more complicated. I think that complexity is not necessary
in the introduction, but it would be good to adjust that language to
be more clear.

How about something like this for that third paragraph:

"
Each type of connector (BIO, NIO, NIO2, and APR) have different
strategies for handling incoming connections, but, in general, Tomcat
will accept concurrent connections until the connector's
`maxConnections` setting has been reached. Any connections received in
addition to that may be queued in the OS's TCP/IP stack, with the
`acceptCount` attribute giving hints to the OS as to the size of that
queue. Any connections received on top of those will receive a
"Connection Refused" response, until earlier connections are processed
to completion and resources are available to accept more connections.

Requests are processed with a thread pool which processes
*connections* in the order in which they are received. Note that
multiple requests can be made through each connection, so *requests*
are not necessary processed in a "fair order". The BIO and APR
connectors cannot be made to be fair, while the NIO and NIO2
connectors can in fact be made to process requests "fairly".
"

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlr67u0ACgkQHPApP6U8
pFgHxhAAsh9Do5rPH7t8Ow3KNIfaZxJIsG5Xz1XXAfQ3Nm5aog31MBmgdjnXeUDV
tZJEi60bHv1jOzSYlGX2JmWPH9dIkfWx1cZn12fML8dpWs6J9v41mGXiPj6+ARYY
aa9UKcZgPWfPZbN5voclwcRTbANy66n6yyfiMrFbFtAJMPWueEemaH83CeaLKc0b
sC4OoLcEBRq352GwwjqzO2C8K0N3sc+J13Yk7MVkRMqBHlTIwnClCm5+k2eRQOZd
M1aNvcLXzIH1QRPK1TjP1VtqpX1V6aM8o2et+pvWc23tFAyR1+/Z1v/VsKDy9BrK
brL4vQo5ahqjASVbdL20qSMNRyzBS1stuisVZ3nYJaMO/2kN6XWhUV/zIk3UCiza
4CVeu6oMhO/pvOqSQaCnfP2YAUrLgTVuyNqjxCgYvlpRQInz9Io5sWgY3b8Lh57Q
u/B9Y3mvv9KwfAKcYw7Gjhjf5g0aFddx5e+DoYZGTOnpdUfwNE8feQIz+cLezAAR
dXvLRJ82I7hBmehdRszuH3fgTr4xDceMxMPTmp2fxd6Hl5A0MPslG5Z7Y7mZemAI
16yTnQ1FIeRIx/SIPDJaor9pBPnRKP21VcdMNMpqOJZXphW5grd1LQh1Clk43Vrs
3kjn8mV6xXWTWSkvwiYOzkvFlCDOw6p4FkFoG+nqKTv0n/Xdyqk=
=pPN5
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: acceptCount with NIO and Tomcat 8

Posted by Максим Гумеров <mg...@gmail.com>.
>
> On 11/05/18 18:21, Максим Гумеров wrote:
> > Hi! I am running Tomcat 8 as part of Spring Boot application. As usual,
> > acceptCount defaults to 100 and maxThreads to 200. According to
> > https://tomcat.apache.org/tomcat-8.5-doc/config/http.html#NIO_specific_
> configuration
> > I am expecting Tomcat to accept 200 "long" requests (each taking say 20
> > seconds to complete), then accept 100 more connections but not start
> > reading from them, and then reject any connection requests beyond that.
> > That's why this is the expected behavior: acceptCount = "The maximum
> queue
> > length for incoming connection requests when all possible request
> > processing threads are in use. Any requests received when the queue is
> full
> > will be refused." So, when first 200 requests are all taken by 200
> > processing threads, next 100 will go to the queue and subsequent will be
> > ignored. At least that's how it reads to me.
> >
> > But what I actually see on my Mac is, tomcat successfully accepts a
> little
> > short of 1000 such connections (I just didn't try more connections) made
> > within 5 seconds. It processes no more than 200 requests at a time, but
> > does not reject connections after 300th one, as one would expect.
> >
> > What's the explanation for that? Can the quoted documentation be
> imprecise
> > or outdated? Or am I missing something in it?
>
> acceptCount for NIO is passed in to ServerSocket.bind(SocketAddress,int)
> as the 2nd parameter (backlog). The Javadoc for that method says:
>
> <quote>
> The backlog argument is the requested maximum number of pending
> connections on the socket. Its exact semantics are implementation
> specific. In particular, an implementation may impose a maximum length
> or may choose to ignore the parameter altogether.
> </quote>
>
> It looks like it is being ignored in your JVM.
>
> Mark
>

Thank you, this looks like one possible explanation.
Maybe someone else will show me some other.

But, considering what you say, isn't that a documentation deficiency? They
shouldn't write "acceptCount is the length of connection queue" if it's
just a hint. Or, they could just add a note that actual queue length may be
chosen by implementation instead. Also, they shouldn't write " up to the
configured maximum (the value of the acceptCount attribute)", better
formulation is "up to connection queue size (based on acceptCount
attribute)". What's written there now simply contradicts the
implementation, right?

Maksim

Re: acceptCount with NIO and Tomcat 8

Posted by Mark Thomas <ma...@apache.org>.
On 11/05/18 18:21, Максим Гумеров wrote:
> Hi! I am running Tomcat 8 as part of Spring Boot application. As usual,
> acceptCount defaults to 100 and maxThreads to 200. According to
> https://tomcat.apache.org/tomcat-8.5-doc/config/http.html#NIO_specific_configuration
> I am expecting Tomcat to accept 200 "long" requests (each taking say 20
> seconds to complete), then accept 100 more connections but not start
> reading from them, and then reject any connection requests beyond that.
> That's why this is the expected behavior: acceptCount = "The maximum queue
> length for incoming connection requests when all possible request
> processing threads are in use. Any requests received when the queue is full
> will be refused." So, when first 200 requests are all taken by 200
> processing threads, next 100 will go to the queue and subsequent will be
> ignored. At least that's how it reads to me.
> 
> But what I actually see on my Mac is, tomcat successfully accepts a little
> short of 1000 such connections (I just didn't try more connections) made
> within 5 seconds. It processes no more than 200 requests at a time, but
> does not reject connections after 300th one, as one would expect.
> 
> What's the explanation for that? Can the quoted documentation be imprecise
> or outdated? Or am I missing something in it?

acceptCount for NIO is passed in to ServerSocket.bind(SocketAddress,int)
as the 2nd parameter (backlog). The Javadoc for that method says:

<quote>
The backlog argument is the requested maximum number of pending
connections on the socket. Its exact semantics are implementation
specific. In particular, an implementation may impose a maximum length
or may choose to ignore the parameter altogether.
</quote>

It looks like it is being ignored in your JVM.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org