I just noticed the XML I gave was for a dev version. Here is another semi-production one I found lying around, which I used when testing against already balanced production servers, which shows some more magick you can do with Tomcat, mostly related to custom valves, custom config and custom HttpResponse/Request objects, and a very basic clustering I had between 2 balancers that configured a floating IP in case the "other" went down. You can really do alot (though with the config I cheated by loading the LoadBalancer tag data into my own XML processor).
<Service name="NineLives" className="mypackage.tomcat.NLService"> <Executor name="ninelivesThreadPool" namePrefix="ninelives-exec-" maxThreads="225" minSpareThreads="15"/> <Connector executor="ninelivesThreadPool" port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="15000" /> <Engine name="NineLives" defaultHost="balancer.status" className="mypackage.tomcat.NLEngine"> <LoadBalancer protocol="HTTP/1.1" className="mypackage.lb.requesttyperobin.Manager"> <BackendNode commonName="dynamic1noauth" hostname="10.85.0.101" port="10080" alive="true"> <Not><Authenticated/></Not> <Or> <Match>\.php(\?.*)?$</Match> <Match>.*/cgi-bin/.*</Match> </Or> </BackendNode> <BackendNode commonName="dynamic2noauth" hostname="10.85.0.102" port="10080" alive="true"> <Not><Authenticated/></Not> <Or> <Match>\.php(\?.*)?$</Match> <Match>.*/cgi-bin/.*</Match> </Or> </BackendNode> <BackendNode commonName="dynamic3auth" hostname="10.85.0.103" port="10080" alive="true"> <Authenticated/> <Or> <Match>\.php(\?.*)?$</Match> <Match>.*/cgi-bin/.*</Match> </Or> </BackendNode> <BackendNode commonName="static1" hostname="10.85.0.104" port="10080" alive="true"> <Not> <Or> <Match>\.php(\?.*)?$</Match> <Match>.*/cgi-bin/.*</Match> </Or> </Not> </BackendNode> <BackendNode commonName="backup1" hostname="10.85.0.105" port="10080" alive="false"> <Match>.*</Match> </BackendNode> </LoadBalancer> <Host name="balancer.status" appBase="webapps" unpackWARs="false" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> </Host> <Valve className="mypackage.filters.content.GoogleAnalyticsHtmlAppender" gaID="[google-analytics-id]"/> <NineLivesCluster probePort="10050" partner="10.80.0.2" probeTime="1000" maxFail="10"/> <!--<NineLivesCluster probePort="10050" partner="10.80.0.1" probeTime="1000" maxFail="10"/>--> </Engine> </Service> Q On Mon, Sep 7, 2009 at 9:21 PM, Quintin Beukes <quin...@skywalk.co.za> wrote: > Well, it is quite tricky doing custom protocols. Though I had a vague > plan on implementing SMTP using the same Connector framework. > > The problem with the connector framework is that it revolves around > something like an "Adapter" which works only with stream based > protocols following the "request/response" pattern. > > So, if your protocol follows this pattern, then you can use it. Beyond > this the Request/Response classes are pretty generic. They don't yet > have HTTP design in them. For that you have the > HttpRequest/HttpResponse classes. > > So what you want to do is completely possible, and proven by the AJP > protocol handler, which is widely used by people wanting to link > tomcat and Apache HTTPD. Though AJP is very "HTTP like", it's not > HTTP. It's a non-text protocol, and only shares similarities with http > because it's meant to be an HTTP reverse proxy protocol, so it > supports the concepts of headers/bodies, and follows the > request/response pattern. > > Further. The protocol implementations in Tomcat have what is called > "endpoints", which is the other party in the request IIRC. And with > this class you can do you communication. The protocol handler is very > generic, in having only lifecycle callbacks, and in these you would do > you communicate and construct Request/Response objects, and pass it up > the stack to the engine/service implementations. > > So to handle a completely custom protocol in Tomcat you would have to > make your own Connector, with your own extensions of Request/Response, > and then have your Engine/Service implementations that understand > these types. You can even add your own XML tags, very easily. For this > i had to modify the tomcat base, as they have no way to "extend" on > the config file. I did however put the minimal code in the tomcat > base, which accepted an interface and did callbacks to my library for > the XML parsing. I for instance had the following <Service> tag (just > to give an idea about the Engine/Service implementation and the custom > XML: > > <Service name="NineLives" className="mypackage.tomcat.NLService"> > <Executor name="ninelivesThreadPool" namePrefix="ninelives-exec-" > maxThreads="150" minSpareThreads="4"/> > > <Connector executor="ninelivesThreadPool" > port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" > connectionTimeout="20000" /> > > <Engine name="NineLives" defaultHost="ninelives.status" > className="mypackage.tomcat.NLEngine"> > <LoadBalancer protocol="HTTP/1.1" > className="mypackage.lb.roundrobin.Manager"> > <BackendNode commonName="backend1" hostname="127.0.0.1" > port="8580" alive="true"/> > <BackendNode commonName="backend2" hostname="127.0.0.1" > port="8580" alive="true"/> > </LoadBalancer> > > <Host name="ninelives.status" appBase="webapps" > unpackWARs="false" autoDeploy="true" > xmlValidation="false" xmlNamespaceAware="false"> > </Host> > </Engine> > </Service> > > As you can see I used HTTP, and thus didn't have my own protocol > handler. But the <LoadBalancer> does have a protocol specification, > which I would change to SMTP at a later time when linking my own > connector. IIRC correctly the protocol option could be used to link > back to a Connector so each load balancer would only handle requests > from the appropriate connectors. > > I know this has nothing to do with Geronimo, or with your application. > I just figured giving you some information on what I did might help > clear up how you would do these things in Tomcat. > > After having written this I built up tremendous respect for Tomcat. If > you have a look at the request stack, you would notice Tomcat has > minimal overhead. It does very little in between receiving the request > and handing it to the servlet. And it's extensible design allows you > to completely customize next to anything in it's behaviour, while > still having the benefit of it's thread pools and optimized > request/response handling. I would definitely recommend using it. It's > not easy to write your own protocol handlers. There is too many things > to do if you want something that works well under all kinds of > situations, esp. the "high load" situation, where Tomcat keeps up > quite well. > > When I was researching the design of my load balanced, I did some > benchmarks between some OSS Java proxies/servlet/HTTP > containers/implementations. Of these, Tomcat was able to keep it's > request times quite stable under high loads, where jetty started to > have a very hard time keeping up. So it just shows that if you had to > build on top of a Tomcat, not only do you benefit from a lot of > existing features with years of maturity, but also from a high > performance design, able to take the punch. It's actually these > benchmarks that inspired the name for my application, ie. NineLives. > The word "cat" in Tomcat, together with it's "survival" ability, and > the "nine lives of a cat", I though of NineLives. > > So in my very critical/harsh research, I have to admit I started with > a little bit of a negative attitude towards Tomcat, hoping Jetty would > win. In the end Tomcat really made an impression on me. > > So all in all. What you would do should be possible, depending on the > nature of the protocol you wish to implement. And if it's possible, > you should seriously consider Tomcat over Jetty or your complete own > development. > > Q > > On Mon, Sep 7, 2009 at 2:16 PM, sim085 <sim...@hotmail.com> wrote: >> >> >> >> Quintin Beukes-2 wrote: >>> >>> Are you referring to the connector framework of Tomcat? Frankly I >>> don't see how you can't do what you want with Geronimo+Tomcat. >>> >> >> Hi Quintin, >> >> That is what I tried to do a few months ago. What I tried to do is build my >> own custom protocol handler within Tomcat itself. However the problem I >> faced here was that the CoyoteAdapter class provided by tomcat handled all >> request objects as HttpRequests. I had started a thread about this on the >> Tomcat Nabble Forum here: >> http://www.nabble.com/Tomcat-Custom-Connector-tc17620116.html (the last >> entry). On that thread no one answered if I could create my own adapter and >> if I could configure Tomcat to use this adapter together with the >> CoyoteAdapter it already has. >> >> Unfortunately that has been some time ago and what was clear back then is a >> little bit foggy now. However I am more then happy to check the code again >> and try to understand it should it be necessary. >> >> -- >> View this message in context: >> http://www.nabble.com/Can-I-make-Geronimo-work-with-my-own-implementation-of-web-server--tp25320346s134p25329613.html >> Sent from the Apache Geronimo - Users mailing list archive at Nabble.com. >> >> > > > > -- > Quintin Beukes > -- Quintin Beukes