You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Andrew Skiba <sk...@gmail.com> on 2008/01/10 09:47:44 UTC

backlog measurement

Hello,

I want to contribute a custom SocketFactory allowing to analyze the
utilization of acceptConnection attribute of a Connector. In a properly
configured production system, there should be rare situations where
connections wait for a worker thread to be handled. Our client complained on
high latency of web requests, but the measurement on servlet did not show
high latency. So we wanted to know the number of connections which wait in
socket backlog and were not accepted yet.

I solved this problem by writing a custom SocketFactory, which accepts
connections immediately and puts it in my queue until a call to accept()
will take them. So the number of waiting connections can be monitored via
JMX.

To activate this factory, the declaration of the corresponding Connector in
server.xml should be changed like in the following example.

 <Connector port="8080" maxHttpHeaderSize="8192"
               maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
               enableLookups="false" redirectPort="8443" acceptCount="10"
               connectionTimeout="2000" disableUploadTimeout="true"

               socketFactory="
org.apache.tomcat.util.net.BacklogMeasuringServerSocketFactory"/>


No changes in existing classes are required.

Please review the code in the attachment.


Andrew Skiba.

Re: backlog measurement

Posted by srinivasch <sr...@gmail.com>.
Hi Adrew/Filip,

       I guess I am in similar situation as Andrew, I am trying to monitor
my application through nagios and I was about to start writing a plugin to
monitor AJP Queue size. I thought I could use andrews solution, but I am
still unsure of the state of the patch he contributed and whether I can use
that patch and customize and create a plugin for the same.

Appreciate your responses.

Thanks
Sri



Andrew Skiba-2 wrote:
> 
> Hello,
> 
> I want to contribute a custom SocketFactory allowing to analyze the
> utilization of acceptConnection attribute of a Connector. In a properly
> configured production system, there should be rare situations where
> connections wait for a worker thread to be handled. Our client complained
> on
> high latency of web requests, but the measurement on servlet did not show
> high latency. So we wanted to know the number of connections which wait in
> socket backlog and were not accepted yet.
> 
> I solved this problem by writing a custom SocketFactory, which accepts
> connections immediately and puts it in my queue until a call to accept()
> will take them. So the number of waiting connections can be monitored via
> JMX.
> 
> To activate this factory, the declaration of the corresponding Connector
> in
> server.xml should be changed like in the following example.
> 
>  <Connector port="8080" maxHttpHeaderSize="8192"
>                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
>                enableLookups="false" redirectPort="8443" acceptCount="10"
>                connectionTimeout="2000" disableUploadTimeout="true"
> 
>                socketFactory="
> org.apache.tomcat.util.net.BacklogMeasuringServerSocketFactory"/>
> 
> 
> No changes in existing classes are required.
> 
> Please review the code in the attachment.
> 
> 
> Andrew Skiba.
> 
> 
> package org.apache.tomcat.util.net;
> 
> import java.io.*;
> import java.net.*;
> import java.util.concurrent.BlockingQueue;
> import java.util.concurrent.LinkedBlockingQueue;
> import java.util.concurrent.atomic.AtomicLong;
> import javax.management.MBeanRegistration;
> import javax.management.MBeanServer;
> import javax.management.ObjectName;
> import org.apache.commons.modeler.Registry;
> 
> /**
>  * Default server socket factory. Doesn't do much except give us
>  * plain ol' server sockets.
>  *
>  * @author db@eng.sun.com
>  * @author Harish Prabandham
>  */
> 
> // Default implementation of server sockets.
> 
> //
> // WARNING: Some of the APIs in this class are used by J2EE. 
> // Please talk to harishp@eng.sun.com before making any changes.
> //
> public class BacklogMeasuringServerSocketFactory extends
> ServerSocketFactory
>     implements MBeanRegistration
> {
>     private static org.apache.commons.logging.Log logger =
>        
> org.apache.commons.logging.LogFactory.getLog(BacklogMeasuringServerSocketFactory.class);
>     private static AtomicLong queuesCommonSize = new AtomicLong(0);
> 
>     static class ServerSocketProxy extends ServerSocket {
>         public static final int DEFAULT_QUEUE_SIZE = 50;
> 
>         BlockingQueue<Socket> acceptQueue;
>         Thread acceptThread;
> 
>         class AcceptRunnable implements Runnable {
>             public void run() {
>                 try {
>                     while (!isClosed()) {
>                         acceptQueue.put(superAccept());
>                         queuesCommonSize.incrementAndGet();
>                     }
>                 } catch (InterruptedException ex) {
>                     logger.warn("unexpected exception", ex);
>                 } catch (IOException ex) {
>                     logger.info("stopping accepting connections", ex);
>                 }
>             }
>         }
> 
>         private Socket superAccept () throws IOException {
>             return super.accept();
>         }
>         void init (int queueSize) {
>             acceptQueue = new LinkedBlockingQueue (queueSize);
>             acceptThread = new Thread(new AcceptRunnable(),
> "Accept-"+toString());
>             acceptThread.start();                    
>         }
>         
>         public ServerSocketProxy(int port) throws IOException {
>             super(port);
>             init(DEFAULT_QUEUE_SIZE);
>         }
>         
>         public ServerSocketProxy(int port, int backlog) throws IOException
> {
>             super(port, backlog);
>             init(backlog);
>         }
>         
>         public ServerSocketProxy(int port, int backlog, InetAddress
> bindAddr) throws IOException {
>             super(port, backlog, bindAddr);
>             init(backlog);
>         }
> 
>         @Override
>         public Socket accept() throws IOException {
>             try {
>                 Socket res = acceptQueue.take();
>                 queuesCommonSize.decrementAndGet();
>                 return res;
>             } catch (InterruptedException ex) {
>                 throw new SocketException ("unexpected
> InterruptedException");
>             }
>         }
>     }
>     
>     public BacklogMeasuringServerSocketFactory () {
>         try {
>             Registry.getRegistry(null, null).registerComponent(this,
>                     new
> ObjectName("measure:type=Backlog,obj="+hashCode()), null);
>         } catch (Exception ex) {
>             logger.error("MBean was not registered", ex);
>         }
>     }
> 
>     public ServerSocket createSocket (int port)
>     throws IOException {
>         return new ServerSocketProxy(port);
>     }
> 
>     public ServerSocket createSocket (int port, int backlog)
>     throws IOException {
>         return new ServerSocketProxy (port, backlog);
>     }
> 
>     public ServerSocket createSocket (int port, int backlog,
>         InetAddress ifAddress)
>     throws IOException {
>         return new ServerSocketProxy (port, backlog, ifAddress);
>     }
>  
>     public Socket acceptSocket(ServerSocket socket)
>  	throws IOException {
>         return socket.accept();
>     }
>  
>     public void handshake(Socket sock)
>  	throws IOException {
>  	// NOOP
>     }
>     
>     public long size () {
>         return queuesCommonSize.longValue();
>     }
> 
>     
>     protected String domain;
>     protected ObjectName oname;
>     protected MBeanServer mserver;
> 
>     public ObjectName getObjectName() {
>         return oname;
>     }
> 
>     public String getDomain() {
>         return domain;
>     }
> 
> 
>     public ObjectName preRegister(MBeanServer server, ObjectName name)
> throws Exception {
>         this.oname = name;
>         this.mserver = server;
>         domain = name.getDomain();
>         return name;
>     }
> 
>     public void postRegister(Boolean registrationDone) {
>     }
> 
>     public void preDeregister() throws Exception {
>     }
> 
>     public void postDeregister() {
>     }    
>  }
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
> 

-- 
View this message in context: http://www.nabble.com/backlog-measurement-tp14729968p16447208.html
Sent from the Tomcat - Dev mailing list archive at Nabble.com.


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


Re: backlog measurement

Posted by Andrew Skiba <sk...@gmail.com>.
Hello Filip,

Thank you again for your reply and for the links.

I think that makes sense.

Yes, I will end up with unmeasurable backlog after acceptQueue is full. But
when the queue is empty, which is the normal operating mode, the backlog
will be filled only for few milliseconds of context switch. AcceptRunnable
is only accepting sockets and putting them into the queue, so it's hard for
kernel backlog not to be empty.

Anyway, the purpose of this patch is not to measure backlog size per se, but
to identify a server incapable to handle its load for long periods of time -
tens of minutes, or hours.

You are right, different OSes have tools to monitor this, but it's always
good to have a pure java solution at hand.

In underloaded server this patch will add an overhead of 1 thread per port,
and rarely few extra I/O buffers for short periods of higher load. I
suppose, GC will take care of that, when the load is low again.

If the server is slashdotted, you will know this sooner or later. The worst
situation is when the load is just slightly above the possible to handle. If
I have 10 worker threads and 20 simultaneously stressing clients, the
response time is double of what can be measured on servlets. This patch
allows to figure that out at price of 1 additional thread and 10 extra I/O
buffers. Probably there will be people who are willing to pay this price, so
they will use this connection factory.

Regards,

Andrew.

On 1/10/08, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
>
>
>
> hi Andrew, the solution is a bit overkill and you may be
> misunderstanding the backlog concept.
>
> the concept behind the backlog, is when the app is too busy accepting
> connection, the kernel and its TCP stack will handle it for you.
> and by doing this, you can balance the pressure of new connections at
> the kernel level.
>
> for example, if all threads are busy in java handling requests, the
> kernel will handle SYN and TCP handshakes until its backlog is full.
> when the backlog is full, it will simply drop future SYN requests. it
> will not send a RST, ie causing "Connection refused" on the client,
> instead the client will assume the package was lost and retransmit the
> SYN. hopefully, the backlog queue will have cleared up by then.
>
> doing this in java, and by accepting connections by the process running,
> you're doing redundant work, hence it would be overkill.
>
> in terms of backlog reporting, which is the idea behind this, one would
> have to look at the specific OS, and see what it has to offer for that
> kind of info.
>
> a great read to understand the backlog functionality, since its so
> loosely defined is
>
> http://www.amazon.com/Unix-Network-Programming-Addison-Wesley-Professional/dp/0131411551/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1199991167&sr=8-1
>
> it explains it fairly well.
>
> in your example, maxThreads=10 acceptCount=30, with your
> implementations, your not measuring the actual backlog, you're only
> measuring the number of actually accepted connections, you still end up
> with unmeasurable backlog. what you instead end up with is 15 extra
> connections, and the TX/RX buffers and the java objects associated with
> it.
>
> does that make sense?
>
> Filip
>
> Andrew Skiba wrote:
> > Hello Filip, thanks for your reply.
> >
> > You are absolutely right.
> >
> > I did this trick when I understood that it's not trivial to measure
> backlog
> > in Java. I called it backlog because a normal system would have backlog
> of
> > this size in the same conditions. For example, for maxThreads=10 and
> > acceptCount=30 and 25 client threads the backlog size will be 15,
> although
> > we cannot measure it.
> >
> > If you use by socket factory in the same conditions, it will report
> > "backlog" size=15. Although now these 15 sockets are in totally
> different
> > state, from logical point of view, my blackbox behaves the same and now
> is
> > able to report this number.
> >
> > About memory consumptions. In normally functioning system I expect
> threads
> > to be blocked on accept() 99% of the time. Backlog is a spare for short
> term
> > spikes. So my implementation will accept a socket and this socket will
> be
> > used by an other thread very soon. Also it's possible to configure a
> half of
> > a usual acceptCount because I create an additional buffer of this size.
> >
> > I intend to use this socket factory to monitor and store the "backlog"
> size
> > once in a few minutes for all my servers. If I see that in last 3 hours
> this
> > size is always above zero, I know there is a problem. Or if users
> complain
> > that between 17:00  and 17:30 my application responded slower than
> usual, I
> > can check what were backlog readings at that time. Currently I can check
> > only timestamps when requests were processed, but requests could be
> delayed
> > in the backlog and I have no way to know.
> >
> > If my solution is an overkill for this problem, can you please advice me
> a
> > more appropriate way.
> >
> > Thank you
> >
> > Andrew.
> >
> > On 1/10/08, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
> >
> >> I'm a bit confused on how you can measure backlog in Java. Backlog is a
>
> >> TCP stack implementation setting.
> >> Also, between TCP implementations, there is no firm definition of what
> >> backlog actually means. does it mean SYN_RCVD or ESTABLISHED but not
> yet
> >> accepted?
> >>
> >> If I read the implementation correct, this has nothing to do with
> >> backlog, since you are accepting the connections into the process, ie,
> >> the handshake is done, and the accept call has returned. this
> connection
> >> is no longer subject to the TCP backlog (IIRC).
> >>
> >> This implementation, would prematurely accept connections, causing the
> >> system to take up memory for send and receive buffers for the Java
> >> process.
> >> Filip
> >>
> >> Andrew Skiba wrote:
> >>
> >>> Hello,
> >>>
> >>> I want to contribute a custom SocketFactory allowing to analyze the
> >>> utilization of acceptConnection attribute of a Connector. In a
> >>> properly configured production system, there should be rare situations
> >>> where connections wait for a worker thread to be handled. Our client
> >>> complained on high latency of web requests, but the measurement on
> >>> servlet did not show high latency. So we wanted to know the number of
> >>> connections which wait in socket backlog and were not accepted yet.
> >>>
> >>> I solved this problem by writing a custom SocketFactory, which accepts
> >>> connections immediately and puts it in my queue until a call to
> >>> accept() will take them. So the number of waiting connections can be
> >>> monitored via JMX.
> >>>
> >>> To activate this factory, the declaration of the corresponding
> >>> Connector in server.xml should be changed like in the following
> example.
> >>>
> >>>  <Connector port="8080" maxHttpHeaderSize="8192"
> >>>                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
> >>>                enableLookups="false" redirectPort="8443"
> >>>
> >> acceptCount="10"
> >>
> >>>                connectionTimeout="2000" disableUploadTimeout="true"
> >>>
> >>>
> >>> socketFactory="
> >>>
> >> org.apache.tomcat.util.net.BacklogMeasuringServerSocketFactory"/>
> >>
> >>> No changes in existing classes are required.
> >>>
> >>> Please review the code in the attachment.
> >>>
> >>>
> >>> Andrew Skiba.
> >>>
> ------------------------------------------------------------------------
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> >>> For additional commands, e-mail: dev-help@tomcat.apache.org
> >>>
> ------------------------------------------------------------------------
> >>>
> >>> No virus found in this incoming message.
> >>> Checked by AVG Free Edition.
> >>> Version: 7.5.516 / Virus Database: 269.19.0/1216 - Release Date:
> >>>
> >> 1/9/2008 10:16 AM
> >>
> >>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> >> For additional commands, e-mail: dev-help@tomcat.apache.org
> >>
> >>
> >>
> >
> >
> > ------------------------------------------------------------------------
>
> >
> > No virus found in this incoming message.
> > Checked by AVG Free Edition.
> > Version: 7.5.516 / Virus Database: 269.19.0/1216 - Release Date:
> 1/9/2008 10:16 AM
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>

Re: backlog measurement

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.

hi Andrew, the solution is a bit overkill and you may be 
misunderstanding the backlog concept.

the concept behind the backlog, is when the app is too busy accepting 
connection, the kernel and its TCP stack will handle it for you.
and by doing this, you can balance the pressure of new connections at 
the kernel level.

for example, if all threads are busy in java handling requests, the 
kernel will handle SYN and TCP handshakes until its backlog is full. 
when the backlog is full, it will simply drop future SYN requests. it 
will not send a RST, ie causing "Connection refused" on the client, 
instead the client will assume the package was lost and retransmit the 
SYN. hopefully, the backlog queue will have cleared up by then.

doing this in java, and by accepting connections by the process running, 
you're doing redundant work, hence it would be overkill.

in terms of backlog reporting, which is the idea behind this, one would 
have to look at the specific OS, and see what it has to offer for that 
kind of info.

a great read to understand the backlog functionality, since its so 
loosely defined is
http://www.amazon.com/Unix-Network-Programming-Addison-Wesley-Professional/dp/0131411551/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1199991167&sr=8-1

it explains it fairly well.

in your example, maxThreads=10 acceptCount=30, with your 
implementations, your not measuring the actual backlog, you're only 
measuring the number of actually accepted connections, you still end up 
with unmeasurable backlog. what you instead end up with is 15 extra 
connections, and the TX/RX buffers and the java objects associated with it.

does that make sense?

Filip

Andrew Skiba wrote:
> Hello Filip, thanks for your reply.
>
> You are absolutely right.
>
> I did this trick when I understood that it's not trivial to measure backlog
> in Java. I called it backlog because a normal system would have backlog of
> this size in the same conditions. For example, for maxThreads=10 and
> acceptCount=30 and 25 client threads the backlog size will be 15, although
> we cannot measure it.
>
> If you use by socket factory in the same conditions, it will report
> "backlog" size=15. Although now these 15 sockets are in totally different
> state, from logical point of view, my blackbox behaves the same and now is
> able to report this number.
>
> About memory consumptions. In normally functioning system I expect threads
> to be blocked on accept() 99% of the time. Backlog is a spare for short term
> spikes. So my implementation will accept a socket and this socket will be
> used by an other thread very soon. Also it's possible to configure a half of
> a usual acceptCount because I create an additional buffer of this size.
>
> I intend to use this socket factory to monitor and store the "backlog" size
> once in a few minutes for all my servers. If I see that in last 3 hours this
> size is always above zero, I know there is a problem. Or if users complain
> that between 17:00  and 17:30 my application responded slower than usual, I
> can check what were backlog readings at that time. Currently I can check
> only timestamps when requests were processed, but requests could be delayed
> in the backlog and I have no way to know.
>
> If my solution is an overkill for this problem, can you please advice me a
> more appropriate way.
>
> Thank you
>
> Andrew.
>
> On 1/10/08, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
>   
>> I'm a bit confused on how you can measure backlog in Java. Backlog is a
>> TCP stack implementation setting.
>> Also, between TCP implementations, there is no firm definition of what
>> backlog actually means. does it mean SYN_RCVD or ESTABLISHED but not yet
>> accepted?
>>
>> If I read the implementation correct, this has nothing to do with
>> backlog, since you are accepting the connections into the process, ie,
>> the handshake is done, and the accept call has returned. this connection
>> is no longer subject to the TCP backlog (IIRC).
>>
>> This implementation, would prematurely accept connections, causing the
>> system to take up memory for send and receive buffers for the Java
>> process.
>> Filip
>>
>> Andrew Skiba wrote:
>>     
>>> Hello,
>>>
>>> I want to contribute a custom SocketFactory allowing to analyze the
>>> utilization of acceptConnection attribute of a Connector. In a
>>> properly configured production system, there should be rare situations
>>> where connections wait for a worker thread to be handled. Our client
>>> complained on high latency of web requests, but the measurement on
>>> servlet did not show high latency. So we wanted to know the number of
>>> connections which wait in socket backlog and were not accepted yet.
>>>
>>> I solved this problem by writing a custom SocketFactory, which accepts
>>> connections immediately and puts it in my queue until a call to
>>> accept() will take them. So the number of waiting connections can be
>>> monitored via JMX.
>>>
>>> To activate this factory, the declaration of the corresponding
>>> Connector in server.xml should be changed like in the following example.
>>>
>>>  <Connector port="8080" maxHttpHeaderSize="8192"
>>>                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
>>>                enableLookups="false" redirectPort="8443"
>>>       
>> acceptCount="10"
>>     
>>>                connectionTimeout="2000" disableUploadTimeout="true"
>>>
>>>
>>> socketFactory="
>>>       
>> org.apache.tomcat.util.net.BacklogMeasuringServerSocketFactory"/>
>>     
>>> No changes in existing classes are required.
>>>
>>> Please review the code in the attachment.
>>>
>>>
>>> Andrew Skiba.
>>> ------------------------------------------------------------------------
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
>>> For additional commands, e-mail: dev-help@tomcat.apache.org
>>> ------------------------------------------------------------------------
>>>
>>> No virus found in this incoming message.
>>> Checked by AVG Free Edition.
>>> Version: 7.5.516 / Virus Database: 269.19.0/1216 - Release Date:
>>>       
>> 1/9/2008 10:16 AM
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: dev-help@tomcat.apache.org
>>
>>
>>     
>
>   
> ------------------------------------------------------------------------
>
> No virus found in this incoming message.
> Checked by AVG Free Edition. 
> Version: 7.5.516 / Virus Database: 269.19.0/1216 - Release Date: 1/9/2008 10:16 AM
>   


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


Re: backlog measurement

Posted by Andrew Skiba <sk...@gmail.com>.
Hello Filip, thanks for your reply.

You are absolutely right.

I did this trick when I understood that it's not trivial to measure backlog
in Java. I called it backlog because a normal system would have backlog of
this size in the same conditions. For example, for maxThreads=10 and
acceptCount=30 and 25 client threads the backlog size will be 15, although
we cannot measure it.

If you use by socket factory in the same conditions, it will report
"backlog" size=15. Although now these 15 sockets are in totally different
state, from logical point of view, my blackbox behaves the same and now is
able to report this number.

About memory consumptions. In normally functioning system I expect threads
to be blocked on accept() 99% of the time. Backlog is a spare for short term
spikes. So my implementation will accept a socket and this socket will be
used by an other thread very soon. Also it's possible to configure a half of
a usual acceptCount because I create an additional buffer of this size.

I intend to use this socket factory to monitor and store the "backlog" size
once in a few minutes for all my servers. If I see that in last 3 hours this
size is always above zero, I know there is a problem. Or if users complain
that between 17:00  and 17:30 my application responded slower than usual, I
can check what were backlog readings at that time. Currently I can check
only timestamps when requests were processed, but requests could be delayed
in the backlog and I have no way to know.

If my solution is an overkill for this problem, can you please advice me a
more appropriate way.

Thank you

Andrew.

On 1/10/08, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
>
> I'm a bit confused on how you can measure backlog in Java. Backlog is a
> TCP stack implementation setting.
> Also, between TCP implementations, there is no firm definition of what
> backlog actually means. does it mean SYN_RCVD or ESTABLISHED but not yet
> accepted?
>
> If I read the implementation correct, this has nothing to do with
> backlog, since you are accepting the connections into the process, ie,
> the handshake is done, and the accept call has returned. this connection
> is no longer subject to the TCP backlog (IIRC).
>
> This implementation, would prematurely accept connections, causing the
> system to take up memory for send and receive buffers for the Java
> process.
> Filip
>
> Andrew Skiba wrote:
> > Hello,
> >
> > I want to contribute a custom SocketFactory allowing to analyze the
> > utilization of acceptConnection attribute of a Connector. In a
> > properly configured production system, there should be rare situations
> > where connections wait for a worker thread to be handled. Our client
> > complained on high latency of web requests, but the measurement on
> > servlet did not show high latency. So we wanted to know the number of
> > connections which wait in socket backlog and were not accepted yet.
> >
> > I solved this problem by writing a custom SocketFactory, which accepts
> > connections immediately and puts it in my queue until a call to
> > accept() will take them. So the number of waiting connections can be
> > monitored via JMX.
> >
> > To activate this factory, the declaration of the corresponding
> > Connector in server.xml should be changed like in the following example.
> >
> >  <Connector port="8080" maxHttpHeaderSize="8192"
> >                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
> >                enableLookups="false" redirectPort="8443"
> acceptCount="10"
> >                connectionTimeout="2000" disableUploadTimeout="true"
> >
> >
> > socketFactory="
> org.apache.tomcat.util.net.BacklogMeasuringServerSocketFactory"/>
> >
> >
> > No changes in existing classes are required.
> >
> > Please review the code in the attachment.
> >
> >
> > Andrew Skiba.
> > ------------------------------------------------------------------------
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: dev-help@tomcat.apache.org
> > ------------------------------------------------------------------------
> >
> > No virus found in this incoming message.
> > Checked by AVG Free Edition.
> > Version: 7.5.516 / Virus Database: 269.19.0/1216 - Release Date:
> 1/9/2008 10:16 AM
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>

Re: backlog measurement

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
I'm a bit confused on how you can measure backlog in Java. Backlog is a 
TCP stack implementation setting.
Also, between TCP implementations, there is no firm definition of what 
backlog actually means. does it mean SYN_RCVD or ESTABLISHED but not yet 
accepted?

If I read the implementation correct, this has nothing to do with 
backlog, since you are accepting the connections into the process, ie, 
the handshake is done, and the accept call has returned. this connection 
is no longer subject to the TCP backlog (IIRC).

This implementation, would prematurely accept connections, causing the 
system to take up memory for send and receive buffers for the Java process.
Filip

Andrew Skiba wrote:
> Hello,
>
> I want to contribute a custom SocketFactory allowing to analyze the 
> utilization of acceptConnection attribute of a Connector. In a 
> properly configured production system, there should be rare situations 
> where connections wait for a worker thread to be handled. Our client 
> complained on high latency of web requests, but the measurement on 
> servlet did not show high latency. So we wanted to know the number of 
> connections which wait in socket backlog and were not accepted yet.
>
> I solved this problem by writing a custom SocketFactory, which accepts 
> connections immediately and puts it in my queue until a call to 
> accept() will take them. So the number of waiting connections can be 
> monitored via JMX.
>
> To activate this factory, the declaration of the corresponding 
> Connector in server.xml should be changed like in the following example.
>
>  <Connector port="8080" maxHttpHeaderSize="8192"
>                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
>                enableLookups="false" redirectPort="8443" acceptCount="10"
>                connectionTimeout="2000" disableUploadTimeout="true"
>
>                
> socketFactory="org.apache.tomcat.util.net.BacklogMeasuringServerSocketFactory"/>
>
>
> No changes in existing classes are required.
>
> Please review the code in the attachment.
>
>
> Andrew Skiba.
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
> ------------------------------------------------------------------------
>
> No virus found in this incoming message.
> Checked by AVG Free Edition. 
> Version: 7.5.516 / Virus Database: 269.19.0/1216 - Release Date: 1/9/2008 10:16 AM




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


Re: backlog measurement

Posted by Andrew Skiba <sk...@gmail.com>.
It works with tomcat from trunk now. I opened a bug and attached a patch for
the new code. License and author specified as you said. Please review.

http://issues.apache.org/bugzilla/show_bug.cgi?id=44199

On Jan 10, 2008 11:47 AM, Andrew Skiba <sk...@gmail.com> wrote:

> Hi Peter, thanks for your reply,
>
> The name of Harish appears in the code by mistake. I started from
> DefaultSocketFactory written by Harish, but nothing remained from the
> original. So I am the author and I will include Apache license in the code.
>
> You are correct, it works only with java 5, and I checked it only with
> tomcat 5.5. I will check it with tomcat 6 as well.
>
> I will open a bug and attach the fixed code.
>
> Andrew.
>
>
> On Jan 10, 2008 11:30 AM, Peter Rossbach <pr...@objektpark.de> wrote:
>
> > HI Andrew,
> >
> > good idea, but why you can contribute a code from  Harish Prabandham
> > (db@eng.sun.com).
> > We can only accept contributions from orignal author and with Apache
> > 2 license included!
> >
> > I seems that this only work with java 5 and the code is designed for
> > JIO HTTP tomcat 5.5.
> >
> > Open a bug report, then we can discuss your contribution.
> >
> > Regards,
> > Peter
> >
> >
> > Am 10.01.2008 um 09:47 schrieb Andrew Skiba:
> >
> > > Hello,
> > >
> > > I want to contribute a custom SocketFactory allowing to analyze the
> > > utilization of acceptConnection attribute of a Connector. In a
> > > properly configured production system, there should be rare
> > > situations where connections wait for a worker thread to be
> > > handled. Our client complained on high latency of web requests, but
> > > the measurement on servlet did not show high latency. So we wanted
> > > to know the number of connections which wait in socket backlog and
> > > were not accepted yet.
> > >
> > > I solved this problem by writing a custom SocketFactory, which
> > > accepts connections immediately and puts it in my queue until a
> > > call to accept() will take them. So the number of waiting
> > > connections can be monitored via JMX.
> > >
> > > To activate this factory, the declaration of the corresponding
> > > Connector in server.xml should be changed like in the following
> > > example.
> > >
> > >  <Connector port="8080" maxHttpHeaderSize="8192"
> > >                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
> >
> > >                enableLookups="false" redirectPort="8443"
> > > acceptCount="10"
> > >                connectionTimeout="2000" disableUploadTimeout="true"
> > >
> > >
> > > socketFactory="org.apache.tomcat.util.net.BacklogMeasuringServerSocket
> > > Factory"/>
> > >
> > >
> > > No changes in existing classes are required.
> > >
> > > Please review the code in the attachment.
> > >
> > >
> > > Andrew Skiba.
> > > <BacklogMeasuringServerSocketFactory.java>
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> > > For additional commands, e-mail: dev-help@tomcat.apache.org
> >
> >
>

Re: backlog measurement

Posted by Andrew Skiba <sk...@gmail.com>.
Hi Peter, thanks for your reply,

The name of Harish appears in the code by mistake. I started from
DefaultSocketFactory written by Harish, but nothing remained from the
original. So I am the author and I will include Apache license in the code.

You are correct, it works only with java 5, and I checked it only with
tomcat 5.5. I will check it with tomcat 6 as well.

I will open a bug and attach the fixed code.

Andrew.

On Jan 10, 2008 11:30 AM, Peter Rossbach <pr...@objektpark.de> wrote:

> HI Andrew,
>
> good idea, but why you can contribute a code from  Harish Prabandham
> (db@eng.sun.com).
> We can only accept contributions from orignal author and with Apache
> 2 license included!
>
> I seems that this only work with java 5 and the code is designed for
> JIO HTTP tomcat 5.5.
>
> Open a bug report, then we can discuss your contribution.
>
> Regards,
> Peter
>
>
> Am 10.01.2008 um 09:47 schrieb Andrew Skiba:
>
> > Hello,
> >
> > I want to contribute a custom SocketFactory allowing to analyze the
> > utilization of acceptConnection attribute of a Connector. In a
> > properly configured production system, there should be rare
> > situations where connections wait for a worker thread to be
> > handled. Our client complained on high latency of web requests, but
> > the measurement on servlet did not show high latency. So we wanted
> > to know the number of connections which wait in socket backlog and
> > were not accepted yet.
> >
> > I solved this problem by writing a custom SocketFactory, which
> > accepts connections immediately and puts it in my queue until a
> > call to accept() will take them. So the number of waiting
> > connections can be monitored via JMX.
> >
> > To activate this factory, the declaration of the corresponding
> > Connector in server.xml should be changed like in the following
> > example.
> >
> >  <Connector port="8080" maxHttpHeaderSize="8192"
> >                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
> >                enableLookups="false" redirectPort="8443"
> > acceptCount="10"
> >                connectionTimeout="2000" disableUploadTimeout="true"
> >
> >
> > socketFactory="org.apache.tomcat.util.net.BacklogMeasuringServerSocket
> > Factory"/>
> >
> >
> > No changes in existing classes are required.
> >
> > Please review the code in the attachment.
> >
> >
> > Andrew Skiba.
> > <BacklogMeasuringServerSocketFactory.java>
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: dev-help@tomcat.apache.org
>
>

Re: backlog measurement

Posted by Peter Rossbach <pr...@objektpark.de>.
HI Andrew,

good idea, but why you can contribute a code from  Harish Prabandham  
(db@eng.sun.com).
We can only accept contributions from orignal author and with Apache  
2 license included!

I seems that this only work with java 5 and the code is designed for  
JIO HTTP tomcat 5.5.

Open a bug report, then we can discuss your contribution.

Regards,
Peter


Am 10.01.2008 um 09:47 schrieb Andrew Skiba:

> Hello,
>
> I want to contribute a custom SocketFactory allowing to analyze the  
> utilization of acceptConnection attribute of a Connector. In a  
> properly configured production system, there should be rare  
> situations where connections wait for a worker thread to be  
> handled. Our client complained on high latency of web requests, but  
> the measurement on servlet did not show high latency. So we wanted  
> to know the number of connections which wait in socket backlog and  
> were not accepted yet.
>
> I solved this problem by writing a custom SocketFactory, which  
> accepts connections immediately and puts it in my queue until a  
> call to accept() will take them. So the number of waiting  
> connections can be monitored via JMX.
>
> To activate this factory, the declaration of the corresponding  
> Connector in server.xml should be changed like in the following  
> example.
>
>  <Connector port="8080" maxHttpHeaderSize="8192"
>                maxThreads="10" minSpareThreads="5" maxSpareThreads="7"
>                enableLookups="false" redirectPort="8443"  
> acceptCount="10"
>                connectionTimeout="2000" disableUploadTimeout="true"
>
>                 
> socketFactory="org.apache.tomcat.util.net.BacklogMeasuringServerSocket 
> Factory"/>
>
>
> No changes in existing classes are required.
>
> Please review the code in the attachment.
>
>
> Andrew Skiba.
> <BacklogMeasuringServerSocketFactory.java>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org