Bug 50603 - Bug in how Apache is counting KeepAliveTimeOut
Summary: Bug in how Apache is counting KeepAliveTimeOut
Status: RESOLVED WONTFIX
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: Core (show other bugs)
Version: 2.2.17
Hardware: All Linux
: P2 normal with 1 vote (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-17 09:43 UTC by Peter
Modified: 2011-08-01 15:04 UTC (History)
0 users



Attachments
trace of the problem (16.39 KB, text/plain)
2011-01-17 09:43 UTC, Peter
Details
trace2 of the problem (14.56 KB, text/plain)
2011-02-08 04:46 UTC, Peter
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Peter 2011-01-17 09:43:36 UTC
Created attachment 26498 [details]
trace of the problem

Hi,

In my belief their is a bug in the way Apache is counting the KeepAliveTimeout. 

The problems is that Apache starts to count the KeepAliveTimeout when it starts to send data (package 28) instead of when the transfer is finished. In this case the session is taken down in package 53. Please see the attachement.

This causes unnecessary retransmitts and establishing of new sessions if you are not aware about this.

And yes, this behaviour is in apache 2.2.17.

Best regards,

Peter
Comment 1 Peter 2011-02-08 04:46:01 UTC
Created attachment 26621 [details]
trace2 of the problem

Adding another example of the same behaviour.

Apache starts to count at package 8 and ends the sessions at package 56.

/Peter
Comment 2 Stefan Fritsch 2011-07-17 14:19:29 UTC
httpd will start counting the keepalive timeout once it has delivered all data to the OS. If you have a slow connection, it is possible that the delivery of the data to the client will take some time. There is nothing to be fixed in httpd.

You should either increase the keepalive timeout or tune the socket buffer size (SendBufferSize in httpd, or /proc/sys/net/* under Linux).
Comment 3 Peter 2011-08-01 07:45:06 UTC
It sounds a little strange that Apache starts to count when it has delivered the data to the OS. Is this an RFC compliant behaviour? In my world it would be more reasonable if it starts to count when the data really has been transfered by the NIC. Counting as soon as the data is delivered to the OS makes the value of KeepAliveTimeout to vary a lot from request to request for the end user. 

/Peter
Comment 4 Eric Covener 2011-08-01 11:45:42 UTC
As Stefan described, You'll have to accommodate for your slow/high latency clients by using a larger KeepAliveTimeout or try to get httpd to block instead of queuing up much data by tuning the TCP stack.  In both cases, it looks like buffering cost you close to half of your low KeepAliveTimeout.
Comment 5 Peter 2011-08-01 12:02:40 UTC
Yes, the KeepAliveTimeout is maybe a little to low and we are planning to change that to 15, but it wont fix the problem entirely since apache starts to count before the transfer is finished! It doesn't matter if it is a high or low speed connection, if you download a file large enough the KeepAliveTimeout will expire. You don't want to set a unnessasary high KeepAliveTimeout since that will require a higher MaxClient value with will take additional resourses from the system.

Regarding buffering I have hard to see how I can tune the already tuned IP-stack further.

/Peter
Comment 6 Eric Covener 2011-08-01 12:14:01 UTC
I think you're confusing when Apache begins counting -- it's when the last buffer has been queued up the OS, not the first. Your responses have been small, so this has not been apparent.

Also, a large response would likely begin to block on the way, so my belief is that your loss of a 2-3 seconds out of 5 would not really get much worse in a practical way.
Comment 7 Peter 2011-08-01 12:55:39 UTC
I'm not confused when apache is starting to count.

I looked up the RFC for HTTP 1.1 and found the following:
http://tools.ietf.org/html/rfc2616#section-8.1

8.1.4 Practical Considerations

 Servers SHOULD NOT close a connection in the
   middle of transmitting a response, unless a network or client failure
   is suspected.

8.2.1 Persistent Connections and Flow Control

   HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's
   flow control mechanisms to resolve temporary overloads, rather than
   terminating connections with the expectation that clients will retry.
   The latter technique can exacerbate network congestion.

As I read the text apache is not following the RFC and closes the connection in the middle of a transmition of a response.

/Peter
Comment 8 Eric Covener 2011-08-01 13:10:19 UTC
The server is not closing the connection in the middle of a response.  Emphasis on "middle" and  "response".
Comment 9 Peter 2011-08-01 13:37:09 UTC
If you take a look at the first trace of this error I have attached to this bug report you see that a transfer starts at package 28 and the servers is closing the connection at package 53, in the "middle" of a transfer.
Comment 10 Eric Covener 2011-08-01 13:53:06 UTC
(In reply to comment #9)
> If you take a look at the first trace of this error I have attached to this bug
> report you see that a transfer starts at package 28 and the servers is closing
> the connection at package 53, in the "middle" of a transfer.

I disagree.

I interpret the trace as showing a response that begins in #28 and is fully transmitted and acknowledged by packet #45.  Packet #46 is a new request that hasn't been ackowledged at all by the server at the time the FIN arrives at the system running the trace [presumably the client].

This is not in the middle of a response.
Comment 11 Peter 2011-08-01 14:11:25 UTC
Ok, I see your point regarding the trace.

But with this implementation of the Keep-Alive in apache in mind is their not a potential risk/problem to close a connection in the middle of transmitting a response?
Comment 12 Eric Covener 2011-08-01 15:04:13 UTC
(In reply to comment #11)
> Ok, I see your point regarding the trace.
> 
> But with this implementation of the Keep-Alive in apache in mind is their not a
> potential risk/problem to close a connection in the middle of transmitting a
> response?

Even with latency, delay between requests, and a small KeepAliveTimeout the closure is queued up behind the response, so I don't think there is a concern there.