Detecting graceful restart/stop in child processes

Detecting graceful restart/stop in child processes

am 06.12.2009 18:35:45 von Bill Moseley

--000e0cd147ee7fa4db047a12c67e
Content-Type: text/plain; charset=ISO-8859-1

I'm running mod_perl/2.0.4 with a very large keep-alive set in my
httpd.conf.

Is there a way to detect when a graceful stop or restart has been requested
in the child apache processes?
I tried $SIG{USR1} and $SIG{WINCH} but I'm not seeing them catch the signal.

I'd like to be able to detect when a graceful stop or restart has been
requested so that I can add a Connection: close header to the response.


--
Bill Moseley
moseley@hank.org

--000e0cd147ee7fa4db047a12c67e
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I'm running mod_perl/2.0.4 with a very large keep-alive set in my httpd=
..conf.

Is there a way to detect when a graceful stop or restart has =
been requested in the child apache processes?
I tried $SIG{USR1} and $SI=
G{WINCH} but I'm not seeing them catch the signal.



I'd like to be able to detect when a graceful stop or restart has b=
een requested so that I can add a Connection: close header to the response.=



--
Bill Moseley

<=
br>

--000e0cd147ee7fa4db047a12c67e--

Re: Detecting graceful restart/stop in child processes

am 06.12.2009 18:51:13 von aw

Bill Moseley wrote:
> I'm running mod_perl/2.0.4 with a very large keep-alive set in my
> httpd.conf.
>
> Is there a way to detect when a graceful stop or restart has been requested
> in the child apache processes?
> I tried $SIG{USR1} and $SIG{WINCH} but I'm not seeing them catch the signal.
>
> I'd like to be able to detect when a graceful stop or restart has been
> requested so that I can add a Connection: close header to the response.
>
>
I am not the ultimate authority here, but I think you are going to have
several problems with this idea.
- the first one is that under Windows (where Apache also runs) there are
no such signals.
- the second one is that the signal, if signal there is, is probably
addressed to the main Apache instance, not to the children processes.
I am not sure that the Apache main process then tells the children to
stop via a signal, or via some other mechanism.
- assuming that a child process (or thread) has received (from the main
Apache process) the order to terminate, it will do so after it finishes
the current request, by which time it will be too late to add your header.
But maybe I'm wrong with all of these. Let's wait for a guru here to
comment..

Re: Detecting graceful restart/stop in child processes

am 07.12.2009 05:58:45 von Bill Moseley

--000e0cd1756c1873cf047a1c51bc
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Sun, Dec 6, 2009 at 9:51 AM, Andr=E9 Warnier wrote:

>
> I am not the ultimate authority here, but I think you are going to have
> several problems with this idea.
> - the first one is that under Windows (where Apache also runs) there are =
no
> such signals.
> - the second one is that the signal, if signal there is, is probably
> addressed to the main Apache instance, not to the children processes.
> I am not sure that the Apache main process then tells the children to sto=
p
> via a signal, or via some other mechanism.
> - assuming that a child process (or thread) has received (from the main
> Apache process) the order to terminate, it will do so after it finishes t=
he
> current request, by which time it will be too late to add your header.
> But maybe I'm wrong with all of these. Let's wait for a guru here to
> comment..
>

I'm not concerned with Windows. I think all children in the process group
see the signals -- at least that's what I'm seeing.

Again, I've got keep alives set for a long time. I can start up Apache an=
d
make a request with firefox which establishes a connection with one
process. Repeated request use the same connection (and process) due to the
keep alive. Then I do a graceful stop and just the parent process and that
one child process remain.

Netstat can also show that the connection is persistent to the child
process.

That process stays around serving requests until either the client (firefox=
)
closes the connection or a response sends a Connection: close header to the
client. Then both the parent and child exit. (I send a Connection: close
header when a query parameter is set.)

But, if I set a signal handler (either via $SIG or with a POSIX handler) I
can catch USR1 in the child process on a graceful stop, but it seems just
the act of catching the signal prevents the process from exiting. That is,
the query parameter trick can still trigger closing the connection but the
process does not exit.

So, yes, an IPC and Apache guru would be the next step. ;)



--=20
Bill Moseley
moseley@hank.org

--000e0cd1756c1873cf047a1c51bc
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Sun, Dec 6, 2009 at 9:51 AM, Andr=E9 =
Warnier <aw@ice-sa.co=
m
>
wrote:
r-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-le=
ft: 1ex;">


I am not the ultimate authority here, but I think=
you are going to have several problems with this idea.

- the first one is that under Windows (where Apache also runs) there are no=
such signals.

- the second one is that the signal, if signal there is, is probably addres=
sed to the main Apache instance, not to the children processes.

I am not sure that the Apache main process then tells the children to stop =
via a signal, or via some other mechanism.

- assuming that a child process (or thread) has received (from the main Apa=
che process) the order to terminate, it will do so after it finishes the cu=
rrent request, by which time it will be too late to add your header.



But maybe I'm wrong with all of these. =A0Let's wait for a guru her=
e to comment..

I'm not concerned with Windows.=
=A0 I think all children in the process group see the signals -- at least t=
hat's what I'm seeing.



Again, I've got keep alives set for a long time.   I can start =
up Apache and make a request with firefox which establishes a connection wi=
th one process.=A0 Repeated request use the same connection (and process) d=
ue to the keep alive. Then I do a graceful stop and just the parent process=
and that one child process remain.



Netstat can also show that the connection is persistent to the child pr=
ocess.

That process stays around serving requests until either the c=
lient (firefox) closes the connection or a response sends a Connection: clo=
se header to the client.=A0 Then both the parent and child exit.=A0 (I send=
a Connection: close header when a query parameter is set.)



But, if I set a signal handler (either via $SIG or with a POSIX handler=
) I can catch USR1 in the child process on a graceful stop, but it seems ju=
st the act of catching the signal prevents the process from exiting.=A0 Tha=
t is, the query parameter trick can still trigger closing the connection bu=
t the process does not exit.



So, yes, an IPC and Apache guru would be the next step. ;)

>


--
Bill Moseley
hank.org">moseley@hank.org


--000e0cd1756c1873cf047a1c51bc--

Re: Detecting graceful restart/stop in child processes

am 07.12.2009 10:18:36 von aw

Bill Moseley wrote:
>
> Again, I've got keep alives set for a long time.

Well, isn't that your problem then ?
KeepAlive connections were introduced at a time when establishing and
tearing down TCP connections were relatively expensive things to do.
With modern servers however, this is less important.

By setting KeepAliveTimeOut long, you essentially "block" a child (and
all its resources), doing nothing but waiting for a follow-up request,
for a long time after the last related request from the browser has come
in, for the dubious benefit of avoiding the setup of a new connection.

Re: Detecting graceful restart/stop in child processes

am 07.12.2009 16:01:49 von Bill Moseley

--000e0cd158a8d5185d047a24bd61
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Mon, Dec 7, 2009 at 1:18 AM, Andr=E9 Warnier wrote:

> Bill Moseley wrote:
>
>>
>> Again, I've got keep alives set for a long time.
>>
>
> Well, isn't that your problem then ?
>
KeepAlive connections were introduced at a time when establishing and
> tearing down TCP connections were relatively expensive things to do.
> With modern servers however, this is less important.
>
> By setting KeepAliveTimeOut long, you essentially "block" a child (and al=
l
> its resources), doing nothing but waiting for a follow-up request, for a
> long time after the last related request from the browser has come in, fo=
r
> the dubious benefit of avoiding the setup of a new connection.
>

This is true for my test environment I described, but that was just for
testing and was on purpose.

Under production a load balancer is used between the client and the
Apache/mod_perl servers. It works as a proxy where the connection to the
client is separate from the connection to the pool of backend processes on
each server. The balancer manages this pool of persistent connections read=
y
to handle requests. Clients make separate persistent connections on the
front of the balancer, too. But these are not directly connected to any on=
e
process. Requests come in from the presistent clients and the balancer
finds a free backend process to handle the request. The backend services
the request very quickly and then is available to service other requests
while the client receives its response. The keep-alive timeouts are
different on both sides of the balancer.

If the balancer maintains persistent connections to the back-end processes
then the problem is how to gracefully shut down a server. Just doing a
graceful stop won't work because the connections keeps the process alive.
One way is to pull the server from the balancer pool, wait for existing
requests to finish (only a few seconds) and then stop the server. Problem
there is that it's not always the same people running the web servers and
balancers.

So, it would be more convenient if a graceful restart could be done on just
Apache and that would trigger closing the connections on the next response
freeing up the process to exit. That's the part I'm trying to get working.




--=20
Bill Moseley
moseley@hank.org

--000e0cd158a8d5185d047a24bd61
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Mon, Dec 7, 2009 at 1:18 AM, Andr=E9 =
Warnier <aw@ice-sa.co=
m
>
wrote:
r-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-le=
ft: 1ex;">

Bill Moseley wrote:

204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">


Again, I've got keep alives set for a long time.




Well, isn't that your problem then ?
=3D"gmail_quote" style=3D"border-left: 1px solid rgb(204, 204, 204); margin=
: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
KeepAlive connections were introduced at a time when establishing and teari=
ng down TCP connections were relatively expensive things to do.

With modern servers however, this is less important.



By setting KeepAliveTimeOut long, you essentially "block" a child=
(and all its resources), doing nothing but waiting for a follow-up request=
, for a long time after the last related request from the browser has come =
in, for the dubious benefit of avoiding the setup of a new connection.



This is true for my test environment I described, but=
that was just for testing and was on purpose.

Under production a lo=
ad balancer is used between the client and the Apache/mod_perl servers.=A0 =
It works as a proxy where the connection to the client is separate from the=
connection to the pool of backend processes on each server.=A0 The balance=
r manages this pool of persistent connections ready to handle requests.=A0 =
Clients make separate persistent connections on the front of the balancer, =
too.=A0 But these are not directly connected to any one process.=A0 Request=
s come in from the presistent clients and the balancer finds a free backend=
process to handle the request.=A0 The backend services the request very qu=
ickly and then is available to service other requests while the client rece=
ives its response.=A0 The keep-alive timeouts are different on both sides o=
f the balancer.=A0



If the balancer maintains persistent connections to the back-end proces=
ses then the problem is how to gracefully shut down a server.=A0 Just doing=
a graceful stop won't work because the connections keeps the process a=
live.=A0 One way is to pull the server from the balancer=A0 pool, wait for =
existing requests to finish (only a few seconds) and then stop the server.=
   Problem there is that it's not always the same people running th=
e web servers and balancers.



So, it would be more convenient if a graceful restart could be done on =
just Apache and that would trigger closing the connections on the next resp=
onse freeing up the process to exit.=A0 That's the part I'm trying =
to get working.






--
Bill Moseley
y@hank.org">moseley@hank.org


--000e0cd158a8d5185d047a24bd61--

Re: Detecting graceful restart/stop in child processes

am 11.12.2009 01:41:39 von Bill Moseley

--000e0cd13bae016448047a6931cf
Content-Type: text/plain; charset=ISO-8859-1

On Mon, Dec 7, 2009 at 7:01 AM, Bill Moseley \
>
>
> So, it would be more convenient if a graceful restart could be done on just
> Apache and that would trigger closing the connections on the next response
> freeing up the process to exit. That's the part I'm trying to get working.
>

This was pretty trivial once I remembered a little XS.

One interesting thing I realized (which makes sense if you think about it)
is that MaxRequestsPerChild is not "requests" but connections. IIRC, the
parent has to track the request count and it only knows about connections.
So, with persistent connections you don't really know the number of
requests. And with memory leaks it's probably the requests that I'm
interested in.

I suppose I could count requests in the application process and call
child_terminate. Or use Apache2::SizeLimit as that's really the reason to
limit number of requests.



--
Bill Moseley
moseley@hank.org

--000e0cd13bae016448047a6931cf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Mon, Dec 7, 2009 at 7:01 AM, Bill Mos=
eley <moseley@hank=
..org
>
\
1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex=
;">


So, it would be more convenient if a gr=
aceful restart could be done on just Apache and that would trigger closing =
the connections on the next response freeing up the process to exit.=A0 Tha=
t's the part I'm trying to get working.



This was pretty trivial once I remembered=
a little XS.

One interesting thing I realized (which makes sense if=
you think about it) is that=A0 MaxRequestsPerChild is not "requests&q=
uot; but connections.=A0 IIRC, the parent has to track the request count an=
d it only knows about connections.=A0 So, with persistent connections you d=
on't really know the number of requests.=A0 And with memory leaks it=
9;s probably the requests that I'm interested in.



I suppose I could count requests in the application process and call ch=
ild_terminate.=A0 Or use Apache2::SizeLimit as that's really the reason=
to limit number of requests.

=A0

--

Bill Moseley




--000e0cd13bae016448047a6931cf--