Hi Angel and Bilal,

thank you for your replies.


> -----Original Message-----
> From: Angel Java Lopez [mailto:ajlopez2...@gmail.com]
> Sent: Saturday, February 15, 2014 11:59 AM
> To: Tomcat Users List
> Subject: Re: Status of the current IIS ISAPI Redirector for Tomcat
> 
> Very interesting!
> 
> Yes, managed code is the path to follow.
> 
> First idea non-blocking IO (from C# client side): use the new async/await
> for the communication. But force to use the new .NET framework and Visual
> Studio. And await is a wait on the current threads:
> 
> http://msdn.microsoft.com/en-us/library/hh750082.aspx
> 
> Maybe, a "node.js" approach, with a callback:
> 
> http://stackoverflow.com/questions/16894907/creating-asynchronous-
> methods-with-task-factory-and-callback
> and only .NET 4.0:
> http://msdn.microsoft.com/en-us/library/dd537612(v=vs.100).aspx
> 
> I don't still see the value of await: it blocked the current thread. I
> guess it is better to use a callback

A "await" on a Task in C# should internally return the current thread back to a 
threadpool, and use a callback on another thread to continue execution of the 
method when the Task is finished, so that threads are not blocked when waiting 
e.g. for an I/O operation to complete. For a full utilization of asynchronous 
I/O, one would not only have to use async read/write operations when forwarding 
the request to Tomcat, but also async flush the response body at IIS to the 
client (and async read the request body). Although the .Net HttpResponse also 
seem to have BeginFlush() and EndFlush() methods that apply the old-style async 
programming pattern, in the SPDY Redirector (see below) I'm using 
Task.Factory.FromAsync(...) to convert these Begin/End-Methods into one that 
returns a Task, so that it can be integrated into the existing Task-based async 
code.

For async flush and read operations at IIS to work, one will need to create an 
async module (IHttpModule, but use context.AddOnBeginRequestAsync() methods to 
add event handlers) or an async handler (derived from HttpTaskAsyncHandler).

This is the approach that I use on a draft of an SPDY redirector that can 
already be tested with Jetty (but not yet with Tomcat), see [1]. After 
switching from blocking I/O to async methods, the number of threads of the IIS 
apppool (w3wp.exe) was greatly reduced when having a slow output producer 
(servlet) on the Jetty side, and a fast client connecting to IIS (but should 
also work for the more likely scenario: A fast output producer (Jetty) and a 
slow client); as with blocking I/O, the IIS threads would spend most of their 
time with doing nothing, whereas with the async approach, they can do other 
things meanwhile.

This approach suits the idea of a multiplexing SPDY as you can send multiple 
requests on a single SPDY connection, so it doesn't block resources like 
sockets or threads for the duration of an request. With SPDY, it should also be 
possible to forward Websocket connections which is AFAIK not possible with AJP.


> 
> Angel "Java" Lopez
> @ajlopez
> 
> 
> On Fri, Feb 14, 2014 at 9:26 PM, Bilal S <bilal.so...@gmail.com> wrote:
> 
> > Konstantin,

<snip>

> > ==>
> > You raise good points. I have run into similar issues and thus created  my
> > own project outside the Apache foundation three years ago (BonCode). It
> is
> > a C# based AJP connector. It can currently be used with Tomcat, JBOSS,
> > Jetty. From support requests I am surmising that is currently bundled with
> > software from a few manufacturers including: EMC, CSC, Siemens and
> others
> > instead of ISAPI redirector.
> >
> > Thus, I do encourage the update of the current IIS connection mechanism
> to
> > a more up-to-date method. Using a managed code mechanism is the way
> to go
> > in my opinion.
> > In the long run SPDY may also be of interest for the same purpose. The
> more
> > choices the better.
> >
> > The following are differences already in existence with BonCode and in
> > response to your extensive writing, only read on if you are curious::
> > ====>

Thank you for you detailed response, this is very helpful.

<snip>

> > > 6.
> > >
> > > As far as I can see, the ISAPI redirector uses blocking I/O when
> > > forwarding requests to Tomcat.
> > >
> > > This means when a slow client sends a request to IIS which gets
> forwarded
> > > to Tomcat, and Tomcat starts to send the response, in the IIS worker
> > > process at least 1 Thread will be dedicated to this request as long as it
> > > is not finished. This means if 500 slow clients concurrently send
> > requests
> > > to IIS (which get forwarded), IIS has to create 500 threads in the
> > > w3wp.exe. This can be a problem in terms of scalability, if lots of
> > clients
> > > send concurrent requests to your server.
> > >
> > > ==> Not most elegant but BonCode will time out the connection based on
> > IIS
> > AppPool setting and reuse. You can also do a similar thing on the Tomcat
> > side. The nature of AJP does not allow multiplexing a connection, so it
> > needs to be dedicated to a client.
> >
> >
> > > The recently released Servlet 3.1 spec allows to use non-blocking I/O
> > when
> > > reading the request body or writing the response body, so that Tomcat
> > > doesn't have to dedicate a thread for the lifetime of the request, but
> > only
> > > take one from a Therad pool when further data can be sent to (or read
> > from)
> > > the client. IIS however would still need to dedicate a thread for the
> > > request. Another problem is that at least IIS 8 only seems to create
> > > additional threads very slowly (1 Thread per second) when its thread pool
> > > is exhausted, which can happen if a few slow clients concurrently send
> > > requests handled by the ISAPI redirector. So some of the clients would
> > have
> > > to wait very long until a thread is created which can handle their
> > request.
> > >
> >
> > ==> Interesting idea, would need to understand better how this applies to
> > the connector and communication via AJP. Currently BonCode creates and
> > maintains a larger base thread-pool, and times them out slowly so the
> under
> > load behavior is more graceful with less create/destroy overhead.
> >

AFAIK, the behavior of IIS to create additional threads (when the others are 
blocked) very slowly also happens with managed code like an IHttpHandler, but 
only when the handler flushes the output or if output buffering is disabled 
(response.OutputBuffer = false). Otherwise, if IIS is able to buffer the whole 
content to be sent to the client and the handler method returns without doing a 
flush operation, IIS will be able to asynchronously send the buffered content 
to the client.

However, this was based on some observasions; I have not examined in detail how 
IIS handles the output buffer and/or creating additional threads.

The reason for flushing in my case (SPDY redirector) / disable output buffering 
for the ISAPI redirector was, that otherwise IIS might try to buffer the whole 
response - e.g. if the client requests a 1 GB file, IIS would try to buffer 1 
GB before sending it to the client. However, on another try, I found that IIS 
flushed after each buffering some MBs of the response, but I think this then 
happens synchronously on the Stream.Write() methods, so it would also block the 
threads, whereas flushing asynchronously should not block it.

 <snip>

> > > 7.
> > >
> > > The ISAPI redirector handles requests to directories like WEB-INF by
> > > itself (rejecting it with 404, or just disconnecting the client).
> > However,
> > > if it is just forwarding requests, then my point of view would be that it
> > > should not reject requests by itself, but instead let this do Tomcat (or
> > > whatever AJP server is behind), because Tomcat needs to also do this if
> > you
> > > directly connect to it over HTTP.
> > > I can see a reason for rejecting requests to WEB-INF at IIS level if IIS
> > > it is configured to serve static resources directly, and only forward
> > > requests to Tomcat. However, personally I never to this due to the
> > security
> > > implications, and the performance benefit for IIS serving static
> > resources
> > > directly instead of letting Tomcat serve them was rather not noticeable
> > for
> > > me.
> > >
> > > ==> Wouldn't this present an easy exploit path especially if IIS and
> > Tomcat use the same physical path and handlers are misconfigured, e.g.
> when
> > using servlets. I do think the WEB-INF blocking is the safer option.

Yes, if IIS is configured to serve resources from the same physical path as 
Tomcat then a redirector should block such access. In my case, on the websites 
that use the ISAPI redirector, I redirect every request to Tomcat (and IIS uses 
a different physical path than Tomcat).

> > >
> >
> > ==> There is much to be gained by a fresh look at IIS and Tomcat
> > interoperability and adjust it for todays problem set.
> >
> > -Bilal


Thanks!

Regards,
Konstantin Preißer


[1] http://markmail.org/message/ojknieujkcchxqla


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to