forgot to include mailing list...
-------- Original Message --------
Subject: Re: http timeout/keep-alive behind balancer
Date: Tue, 26 Jun 2012 09:54:21 +0200
From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
To: Arens, Marc <marc.arens_at_open-xchange.com>
Hi Marc,
thank you for the explanation, think I got it :)
I see 2 options here:
1) Configure different proxies on Apache side, one w/ ProxyTimeout set
to 100s for regular HTTP connections, another w/o ProxyTimeout for
long-polling connections... and depending on URL you can chose proper
proxy (with proper timeout settings) to forward your request. I'm not a
big Apache expert and most probably you considered this option.
2) Send "ping" messages Grizzly -> Apache ->(?) Client.
Grizzly Response object (and OutputStream) is not thread-safe, but if
you synchronize access - it should work. So
Thread #1 Thread #2
| |
begin synchronized(A) begin synchronized(A)
| |
outputStream.write(...) outputStream.write(...)
| |
outputStream.flush() outputStream.flush()
| |
end synchronized(A) end synchronized(A)
should work.
Regarding your question if it's possible to send such a "ping" message
so it will reach Apache, but not a client... Not sure, may be it's
possible to achieve this behavior using some Apache configuration
tricks, otherwise IMO the "ping" message will always reach the client.
Thanks.
WBR,
Alexey.
>> Hi Marc,
>>
>> just couple of question to understand your usecase better...
>>
>> Correct me if I'm wrong, what you're planning to do on Apache side is
>> distinguish clients by request URLs, and depending on them you will
>> apply or not 100s timeout on Apache.
> Not exactly, Apache is just balancing requests to different backends: either by
> load for new requests to establish a new user session or by existing user
> sessions based on the JSessionIds with backendroutes appended: client --> apache
> --> grizzly. The 100s timeout is applied to all connections by apache. If we
> don't receive some data back on a connection from grizzly --> apache within the
> 100s then Apache will simply close the connection to the backend. This is ok for
> most of the clients but not for some that try to open a single connection for
> the user session and try to keep that connection open until new data is pushed
> from grizzly --> apache --> client. The connection may be idle for 30 minutes or
> even an hour before new data is pushed to the client.
>
>> Now (as I understand) the issue you see is that Grizzly also has
>> keep-alive- and request- timeouts, which similarly to Apache closes idle
>> connections. So you'd like to disable these timeouts (for specific
>> clients) on Grizzly side as well.
>>
>> Is that correct?
> That's a part of the solution. It shouldn't be too hard to configure the grizzly
> timeouts to simply be a bit longer than the apache timeouts so grizzly doesn't
> close a connection before apache does. As i already said, the 100s timeout is ok
> for most connections. The real problem is that i have to make an exception for
> those special clients with their long running connections. In Grizzly i want to
> apply the already mentioned keep alive thread only on some connections opened by
> those special clients and send keep alive messages from grizzly --> apache to
> prevent those connections from being closed by apache. Those connections can be
> identified by the url the client requests. This is currently handled by our own
> servlet container/ajp connector (that we want to replace with grizzly/http). In
> the current implementation we can simply block the response outputstream so only
> one keepalive thread can use the outputstream to send some ajp messages from
> backend --> apache and then unblock the response again so possible server push
> messages can be sent again over the just keep-alived (ouch that sounds awful)
> connection.
>
>> On 06/25/2012 03:53 PM, Arens, Marc wrote:
>>> Hello,
>>>
>>> we are currently evaluating Grizzly as servlet container replacement for our
>>> Open-Xchange server. In our usecase-scenario we set up several
>>> Open-Xchange/Grizzly backends behind an Apache balancer and connect those
>>> with
>>> mod_proxy_balancer and mod_proxy_http. The balancer is configured with a
>>> timeout
>>> [1] (Connection timeout in seconds. The number of seconds Apache waits for
>>> data
>>> sent by / to the backend.) of 100 seconds. Request routing is done via
>>> special
>>> JSessionIds with appended backend routes. The communication with some of our
>>> possible clients is realized via server push from servlets, the client opens
>>> a
>>> connection and waits for for the next data to receive from the server. We
>>> have
>>> to be able to keep the connections to those special clients alive for an
>>> undefined time interval while the rest of the clients will be affected by
>>> the
>>> 100s timeout. Those special clients can simply be identified by the request
>>> url.
>>> Now i'm looking for the best way to keep the connection between backend and
>>> balancer alive without rewriting everything to use websockets.
>>>
>>> I thought about writing a filter to watch writes on those connections based
>>> on
>>> request url and implement something like a watcher thread that periodically
>>> checks the last read/write times and sends a keep-alive package to the
>>> balancer
>>> if needed. But i don't know if Grizzly let's me safely access the
>>> response/connection while another thread from the backend might access the
>>> same
>>> response/connection anytime to do another message push. Do you have any
>>> ideas or
>>> pointers for further research? Another question is how to build the package
>>> so
>>> it just keeps the connection between backend and balancer alive and doesn't
>>> even
>>> reach the client?
>>>
>>> [1] http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxytimeout
> Best regards
> --
> Marc Arens
> Backend Development
> Open-Xchange AG
>
> Phone: +49 2761 8385-0, Fax: +49 2761 838530
>
> -------------------------------------------------------------------------------
> Open-Xchange AG, Rollnerstr. 14, 90408 Nürnberg, Amtsgericht Nürnberg HRB 24738
> Vorstand: Rafael Laguna de la Vera, Carsten Dirks, Aufsichtsratsvorsitzender:
> Richard Seibt
>
> European Office: Open-Xchange GmbH, Martinstr. 41, D-57462 Olpe, Germany
> Amtsgericht Siegen, HRB 8718, Geschäftsführer: Frank Hoberg, Martin Kauss
>
> US Office: Open-Xchange, Inc., 303 South Broadway, Tarrytown, New York 10591
> -------------------------------------------------------------------------------