httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Roy T. Fielding" <field...@kiwi.ICS.UCI.EDU>
Subject Re: Apache 1.2b7-dev performance
Date Sun, 09 Feb 1997 04:30:24 GMT
>I'm scrambling to figure out how to free resources as quickly
>as possible on my machines while chasing a pretty nasty swap
>leak. I've yet to be bitten by any problem (that I know of)
>when _not_ running with lingering_close(). Keeping connections
>open unnecessarily seems like it can only add to forking overhead
>for one thing and perhaps swapped out resources. *shrug* (sorry rob)

There is nothing unnecessary about it.  If you don't linger, you won't
know if there is an error or not.  If the client receives the reset before
the server receives the ack for the last response, then the last response
will be SILENTLY TRUNCATED by the client's TCP stack.  There is absolutely
no way for the client to detect this, and as far as the user is concerned
the site is sending garbage.  Likewise, any caching proxy which accesses
your site has an apparently (to the user) random chance of dropping the
last few packets of a valid response.

There are three possible configurations under which Apache remains a
valid HTTP server:

   1) Set the SO_LINGER socket option and just close.  This option
      requires that the server OS supports SO_LINGER with a timeout.

   2) Use the lingering_close routine to simulate SO_LINGER.  This option
      requires that the server OS has a working shutdown(sd,1).

   3) Turn off all keep-alive/persistent connections and prevent the
      server from closing the connection until it has read the current
      request body (if any), but just close after that.

Setting NO_LINGCLOSE without turning off keep-alive will create a server
that appears to send truncated responses over slow connections.  It is
a difficult bug to reproduce, but it has been reported by many users
accessing Apache servers from slow lines in Europe.  Although such a
situation is uncommon in HTTP/1.0 (because it only occurs when sending
POST data to a resource that doesn't read it before closing), it will
be the *normal* case for HTTP/1.1 clients using pipelining.  I already
fixed the problem of not reading POST data in mod_cgi.g, but keepalive
requires some form of lingering close.

It makes far more sense to find out what is wrong with lingering_close.
If it was working properly, it wouldn't be possible to get a performance
improvement from removing lingering_close, aside from the one RTT cost
of keeping the child busy.  We can improve on this by reducing the timeout
on the call to select, and by stopping the read loop when
read_rv != sizeof dummybuf.

(1) and (2) are okay as default configurations. (3) is obviously not okay
for a default, but should be done on any system without a FIN_WAIT_2
timeout.  There are no other working configurations, at least not until
the socket selection algorithm is multithreaded.


View raw message