tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Konstantin Preißer <kpreis...@apache.org>
Subject RE: Possible IIS SPDY Redirector for Tomcat
Date Sat, 28 Sep 2013 17:40:38 GMT
Hi all,

about a year ago, I wrote about an IIS SPDY/3 Redirector written in C# that could be used
to redirect requests from IIS to Tomcat, Jetty, or other servers with SPDY/3 support; as an
alternative to the ISAPI redirector that uses AJP - see [1]. It uses the new managed module
pipeline that is available since IIS 7.0. However, currently it is simply a request forwarder
that forwards every request over a SPDY. It does not have load-balancing or similar features.

At that time, I could test the redirector with Jetty, but not with Tomcat as it only had support
for SPDY/2. However, I don't know what the current state of the SPDY/3 implementation in Tomcat
is (I saw E-Mails from Costin that he wanted to update Tomcat for SPDY/3, but I don't know
if it is finished). Maybe someone has information about that?

In my initial mail, I wrote about how to test the redirector with Google's web server. That
required an Java NPN tunnel do to this.
However, there is a simpler way to test the Redirector e.g. with IIS 8.0 Express (so you don't
need a Server OS; just a normal client Windows) and Jetty (using a non-SSL SPDY connector).
That way you can test the redirector just like if it would forward the requests to Tomcat.
Below is a guide how to set up IIS 8.0 express and Jetty to test the SPDY redirector.


I think that when comparing an SPDY redirector (C#) to the existing ISAPI redirector (C),
there are advantages and disadvantages:
Pro:
- Because the code is using managed C# instead of native C(++), just like with Java it is
easier to use advanced features like threading etc., and it should be easier to maintain.
E.g. you can program the same way that you would with a Servlet for reading requests and writing
responses. Also e.g. if an error occurs, you will get an exception instead of a crash.
- It is easier to install in IIS: You don't need to add a virtual directory (and don't forget
to set execute permissions for the DLL file etc) - you just add a reference in the web.config
file.
- SPDY should allow for forwarding WebSocket connections (available with IIS 8.0+), which
AJP doesn't. However, I do not yet have looked how to use WebSockets with IIS 8 and over SPDY.
- IIS (7+) seems to enable buffering of response bodies when using the ISAPI redirector. This
means, if you produce 100 MB of data in your servlet, then IIS will cache as much data as
possible before it starts the response. This can be a problem if you need the response to
be immediately started, e.g. for a IP camera which uses MJPEG streaming. It is however possible
to change this behavior in IIS. The SPDY redirector is configured to flush each data packet
so that the response body is sent immediately to the client.
Contra:
- Worse performance than the native ISAPI redirector. I made a test by a Servlet that produces
700 MB of random data, and on a separate machine I used a program to make a HTTP request and
read the data. The average transfer speed was  ~ 98 MByte/s, and the IIS worker process had
around 50% CPU usage, whereas Jetty had only 12 %.


Now, to test the SPDY redirector, you can use IIS 8.0 Express that can be installed on any
current Windows OS like Win8, Win7 and WinVista. Alternatively, if you have Visual Studio
2012 you can also create an empty ASP.Net Web Application and test it with the integrated
IIS 8.0 Express.
The following is an updated guide for how to build the SPDY redirector, install IIS 8.0 Express
and Jetty and configure the IIS web application to use the SPDY redirector on Windows (it
uses Windows 7 64-bit as example).
TOC:
A) Build the SPDY Redirector with MSBuild tool
B) Install IIS 8.0 Express and create a Web Application having the SPDY Redirector
C) Install Jetty 8 and configure it for SPDY/3
D) Test if Jetty and the SPDY redirector is working



A) Build the SPDY Redirector with MSBuild tool

The sources of the SPDY Redirector are available at this SVN repository: https://kinderbasar-luhe.de:8543/svn/PreisserNormaleProjekte/SpdyConnector/

1) Install the .Net Framework 4.5 SDK which is included in the Windows 8 SDK. You can get
it here: http://msdn.microsoft.com/en-us/windows/hardware/hh852363.aspx
When selecting the features to install, the only one you need to select is ".Net Framework
4.5 Software Development Kit". 

2) After checking out the sources, run the MSBuild tool. To do this, open the command prompt
and change to the directory of the checked out sources where the file "SPDY_Redirector.csproj"
is located (SVN location: https://kinderbasar-luhe.de:8543/svn/PreisserNormaleProjekte/SpdyConnector/.Net/SPDY-Redirector/SPDY_Redirector/
).
Then, run MSBuild by typing "%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe". The
result of the build (SpdyRedirector.dll) will be in "bin\Debug" folder.


B) Install IIS 8.0 Express and create a Web Application having the SPDY Redirector

1) Install IIS 8.0 Express. You can get it here: http://www.microsoft.com/en-us/download/details.aspx?id=34679

2) Create a directory for the ASP.Net web application - e.g. "C:\MyIisApp1". Copy SpdyRedirector.dll
to "C:\MyIisApp1\bin\SpdyRedirector.dll", and copy the web.config file located at https://kinderbasar-luhe.de:8543/svn/PreisserNormaleProjekte/SpdyConnector/.Net/web.config
to "C:\MyIisApp1\web.config". This web.config file is an XML file that specifies that the
SPDY Redirector module to be added for this Web Application.
 
3) Run IIS 8.0 Express by calling:

"%ProgramFiles%\IIS Express\iisexpress" /port:8081 /path:"C:\MyIisApp1"

This will bind to localhost:8081. If you open http://localhost:8081/ with a browser, you should
see the following error message:
HTTP 503
The request could not be served because the remote server was not available.

This one is generated from the SPDY Redirector because the SPDY server (Tomcat/Jetty) is not
yet available.


C) Install Jetty 8 and configure it for SPDY/3

1) Download Jetty 8.1.13 from http://eclipse.org/downloads/download.php?file=/jetty/stable-8/dist/jetty-distribution-8.1.13.v20130916.zip&r=1
and extract it. In the following steps, the Jetty directory will be called <jetty>.

2) Download http://repo2.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar
and copy it into <jetty>.

3) Edit <jetty>/etc/jetty-spdy.xml and replace the two existing <Call> elements
by this one:

    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.spdy.http.HTTPSPDYServerConnector">
                <Set name="Port">8444</Set>
                <Set name="defaultAsyncConnectionFactory">
                    <Call name="getAsyncConnectionFactory">
                        <Arg>spdy/3</Arg>
                    </Call>
                </Set>
            </New>
        </Arg>
    </Call> 
	
This will create an non-SSL SPDY/3-Connector at Port 8444.

4) Edit <jetty>/start.ini, and add "spdy" to the OPTIONS list, so that it looks like
this:

OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus,annotations,spdy

5) Start jetty by using the following command, assuming that <jetty> is the current
working directory:

java -Xbootclasspath/p:npn-boot-1.1.6.v20130911.jar -jar start.jar etc/jetty-spdy.xml


D) Test if Jetty and the SPDY redirector is working

1) Open http://localhost:8081/ with your browser. You should now see the "Welcome to Jetty
8" page. To test other  Servlet 3.0 webapps, you can place them in <jetty>/webapps.

2) By default, the SPDY redirector creates a Logfile in C:\SpdyLog\Testlog1.txt. It should
now look like the following:

2013-09-28 16:42:35.580Z: [DEBUG] [IIS Module] Redirecting request: GET http://localhost:8081/
HTTP/1.1
2013-09-28 16:42:35.580Z: [DEBUG] [IIS Module] Creating new HttpSpdyProcessor.
2013-09-28 16:42:35.611Z: [DEBUG] [SpdyConnector] Connecting to 127.0.0.1:8444 ...
2013-09-28 16:42:36.640Z: [DEBUG] [SpdyConnector] S: Stream 1: SYN_STREAM sent (FLAG_FIN:
True; FLAG_UNIDIRECTIONAL: False).
2013-09-28 16:42:36.640Z: [DEBUG] [SpdyConnector] System.Net.Sockets.SocketException (0x80004005):
Es konnte keine Verbindung hergestellt werden, da der Zielcomputer die Verbindung verweigerte
127.0.0.1:8444
   bei System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)
   bei Preisser.Spdy.SpdyRedirector.Connector.SpdyConnector.Start()
2013-09-28 16:42:36.640Z: [DEBUG] [SpdyConnector] TCP Connection aborted.
2013-09-28 16:42:36.640Z: [DEBUG] [SpdyConnector] R: Stream 1: Stream aborted (by remote side).
streamNotCreated: False
2013-09-28 16:42:36.640Z: [DEBUG] [IIS Module] Status Code: 
2013-09-28 16:42:36.640Z: [DEBUG] [IIS Module] Starting the response.
2013-09-28 16:45:53.695Z: [DEBUG] [IIS Module] Redirecting request: GET http://localhost:8081/
HTTP/1.1
2013-09-28 16:45:53.695Z: [DEBUG] [IIS Module] Creating new HttpSpdyProcessor.
2013-09-28 16:45:53.695Z: [DEBUG] [SpdyConnector] Connecting to 127.0.0.1:8444 ...
2013-09-28 16:45:53.695Z: [DEBUG] [SpdyConnector] TCP Connection established.
2013-09-28 16:45:53.711Z: [DEBUG] [SpdyConnector] S: Stream 1: SYN_STREAM sent (FLAG_FIN:
True; FLAG_UNIDIRECTIONAL: False).
2013-09-28 16:45:53.945Z: [DEBUG] [SpdyConnector] R: Stream 1: SYN_REPLY received (FLAG_FIN:
False).
2013-09-28 16:45:53.960Z: [DEBUG] [SpdyConnector] R: Stream 1: Data Frame received (Length:
2239; FLAG_FIN: True).
2013-09-28 16:45:53.976Z: [DEBUG] [IIS Module] Status Code: 200
2013-09-28 16:45:53.976Z: [DEBUG] [IIS Module] Starting the response.
2013-09-28 16:45:53.991Z: [DEBUG] [IIS Module] Redirecting request: GET http://localhost:8081/jetty_banner.gif
HTTP/1.1
2013-09-28 16:45:53.991Z: [DEBUG] [SpdyConnector] S: Stream 3: SYN_STREAM sent (FLAG_FIN:
True; FLAG_UNIDIRECTIONAL: False).
2013-09-28 16:45:53.991Z: [DEBUG] [SpdyConnector] R: Stream 3: SYN_REPLY received (FLAG_FIN:
False).
2013-09-28 16:45:53.991Z: [DEBUG] [SpdyConnector] R: Stream 3: Data Frame received (Length:
65536; FLAG_FIN: False).
2013-09-28 16:45:53.991Z: [DEBUG] [IIS Module] Status Code: 200
2013-09-28 16:45:53.991Z: [DEBUG] [IIS Module] Starting the response.
2013-09-28 16:45:53.991Z: [DEBUG] [SpdyConnector] S: Stream 3: WINDOW_UPDATE sent (Delta:
65536).
2013-09-28 16:45:53.991Z: [DEBUG] [SpdyConnector] R: Stream 3: Data Frame received (Length:
6726; FLAG_FIN: True).
2013-09-28 16:45:54.023Z: [DEBUG] [IIS Module] Redirecting request: GET http://localhost:8081/favicon.ico
HTTP/1.1
2013-09-28 16:45:54.023Z: [DEBUG] [SpdyConnector] S: Stream 5: SYN_STREAM sent (FLAG_FIN:
True; FLAG_UNIDIRECTIONAL: False).
2013-09-28 16:45:54.023Z: [DEBUG] [SpdyConnector] R: Stream 5: SYN_REPLY received (FLAG_FIN:
False).
2013-09-28 16:45:54.038Z: [DEBUG] [SpdyConnector] R: Stream 5: Data Frame received (Length:
1150; FLAG_FIN: True).
2013-09-28 16:45:54.038Z: [DEBUG] [IIS Module] Status Code: 200
2013-09-28 16:45:54.038Z: [DEBUG] [IIS Module] Starting the response.



It would be great to hear some feedback about the IIS SPDY redirector.

Thanks!


Regards,
Konstantin Preißer 



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


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message