I am considering using Java 6's embedded HTTP server for some sort of IPC with a Java daemon. It works pretty well and it's nice that's already bundled with all Java 6 installations. No need of additional libraries.
However, I would like to know if someone has tried this with production environments with heavy load. Does it perform well? Should I be looking for something more robust such as Tomcat or Jetty?
Well, as much as it saddens me to say bad things about Java, I'd really not recommend it for production use, or any kind of heavy use scenario. Even though it works well for small stuff like unit/integration tests, it has big memory issues when it is used intensivelly, especially when you use it for a big number of connections at once. I've had similar issues to the ones described here:
http://neopatel.blogspot.com/2010/05/java-comsunnethttpserverhttpserver.html
And Jetty is not that good for heavy production usage for pretty much the same reason. I'd go with Tomcat if I were you.
As an alternative, I believe you could consider Java Messaging Service as an alternative to Inter Process Communications and just have a JMS server running (like Active MQ)
If you want something that ships with Java have a look at RMI or RMI/IIOP.
Related
One my customers has very strict requirements about how they can deploy a web application. They require it to be deploy-able as WAR within a Java server like Tomcat. Our application however is written in golang and compiles into an executable server.
The only solution I could think off would be to start a long lived golang process in the background which listens on a non-standard port like 8080 and then put some kind of a proxy in java which would transparently proxy all HTTP requests and responses to this process.
How should I go about implementing this ? I'm not at all familiar with Java Servlets and running long running processes like this in the background.
My main concern is if something like this is standard,
would it affect the JVM's memory usage, etc ?
Would the server allow my golang process to allocate the required
amount of memory ?
Would the JVM be able to track it's processor utilization ?
Is there a better way to do this maybe ? Like some kind of inter-process communication mechanism ?
If HTTP is the only API your Go application exposes, then you're only left with the option to just send a HTTP request to Go. Yes you can start the Go executable as a child process from the JVM using a ProcessBuilder. But that's not truly embedding go within your WAR. You can use JNI (Go bindings are called GoJVM) to invoke native routines in Go from Java, but then you have to make a lot of adjustments to your Go code base as well.
What you are looking probably for is indeed a reverse proxy. It's not frequently done in servlets / application servers, because this is usually done in load balancers already. So usually that would be NGINX or httpd with mod_rewrite. For application servers, you can use a proxy servlet.
Examples:
https://github.com/mitre/HTTP-Proxy-Servlet
https://sourceforge.net/projects/j2ep/
The memory footprint is usually not to bad, because you're essentially only connecting the streams. The JVM will be able to track processor and memory utilisation - if implemented properly and the Go executable runs on the same server. Obviously the Java specific statistics don't make much sense anymore, as you're only using your Java server as a pass-through.
Sounds like you will be in trouble though. If my strict requirement was a WAR-archive that can be deployed to an application server, I wouldn't accept another executable added to my stack. Reverse proxied or not.
If they want war, give them war!
Write a thin layer web service that has the executable embedded as a resource that executes it to bring up the go server and accepts web calls and does a pass through to the go service.
Achieves nothing I hear you say? Well, neither does their arbitrary requirement that was probably put in place by someone who's long since left the company, and/or because they lack the confidence/experience/ knowledge to operationally deal with other forms of deployment. There is no particularly good reason to deny your service to be deployed except the work required to establish proper operational procedures (laziness).
Just follow the letter of their rules, not the spirit, and be honest if asked about your implementation. They won't mind.
This may sound like a rant, but IMHO and experience, this kind of approach is reality and the drivers for the requirement are emotionally based, so a somewhat emotional answer is warranted.
I'm carrying out a feasibility study on writing, let's say it's a lightweight run-in-browser MMORPG. (It's not exactly an MMORPG, but would take longer to explain, and the requirements are similar.) I'm trying to figure out the required technology stack.
Client side, it runs in the browser, so the client is Javascript. That was nice and easy :-)
Server side, I'm looking at Java. The common Lamp stack was designed for RESTful applications, as I gather were typical Java web frameworks, and this application is different - it needs a continual stream of data going back and forth between the server and all the clients. I think what I need in this case is Java of the non-framework, full no-holds-barred Java EE variety, someone please correct me if my understanding is incorrect or incomplete? I would need something that is commonly available on reasonably cheap hosting, Java EE fits this description, right?
(Figuring on using MySQL for the database, as this is what's most commonly available. Also I might actually write the code in Scala, being a Java-compatible but supposedly slightly nicer language. I assume neither of these makes any difference?)
Supposing I were writing a website in Lamp, doing at least the initial development on Windows, then I'd install Xamp, which gives you a running copy of the entire server stack right there on your desktop, so you can just alt-tab back and forth between your editor/IDE and browser for testing.
Now my question is: What's the best equivalent setup for Java, for developing something like this on Windows?
Right, in a sense it is. What I think I'm really saying is that almost all discussion of server-side Java seems to talk about JSP, EJB, Glassfish, Google app server etc which are frameworks in the sense that they put restrictions on what your code can do, whereas Java EE puts no such restrictions, you can use as much or as little of the standard library as you want, but it doesn't stop you running arbitrary persistent Java code. Is that correct?
You've thrown out a bunch of terms there:
Glassfish is an application server that implements (all of) Java EE.
JSP is a specification that is part of Java EE, and implemented by application servers such as Glassfish as well as web servers such as Tomcat and (I think) Jetty.
EJB is another specifications that are part of Java EE. It is typically implemented by application servers.
"Google app server" is really "Google Application Engine" (GAE), and is really a platform for implementing web servers in a cloud computing environment. If that's not what you want / need to do, GAE is probably a blind alley for you.
Glassfish, JBoss, Tomcat, Jetty and so on are all platforms that implement some or all of Java EE. None of them stop you implementing arbitrary persistent Java code.
GAE on the other hand does restrict what you can run, because the platform only allows you to run standard Java classes in a whitelist. If your "arbitrary" code depends on other standard Java classes, you are out of luck. (And hence my warning about blind alleys.)
And of course, there are various other Java-based frameworks that are targeted at web development in one form or another. Some are compatible with Java EE servlets and other EE technology, and some have gone off in a different direction.
My recommendation would be to start with something straight forward using plain servlets on a stock platform. Only look at the high performance stuff if and when performance looks like it will be a real concern (not just a "nice to have"). It is better to have a simple and non-scalable prototype, than a high performance solution that you don't have the time and skills to get working. And you can treat the prototype as a learning exercise.
A little hard to tell from the requirements given, but I would look at the following based on your description:
http://www.playframework.org/
http://www.zkoss.org/
http://code.google.com/webtoolkit/
Play Framework is a nice web-centric framework that provides a complete stack (you can code in Java or Scala). ZKoss (ZK) and GWT both provide user interface frameworks. ZK, GWT, and Play all run nicely in Tomcat/MySQL and should work just fine in typical Java/MySQL hosting environment.
... not sure what your definition of 'cheap' is but, that and 'no holds barred Java EE' don't exactly go together. Also, 'frameworks' by themselves don't put restrictions on running any arbitrary java on the server side. When I say 'frameworks' I mean Spring, Struts, etc. Servers will be a little different story. If you need EJBs you'll need Glasfish or JBoss or another EJB compliant container. Hosting with these will be more expensive compared to getting by with Tomcat. IMHO easiest and quickest way to get started is with NetBeans. Comes with Tomcat and / or Glassfish out of the box, all you need is a db.
Is there any real difference to the performance when you use Netty and if you don't use it in an application with tens of thousand of connections?
Not really, a good reason to use Netty is to improve the reliability of the connections and leave you to code what the connection does rather than worry about the details of everything which can go wrong. (Often only comes by finding out the hard way)
Netty may help you scale over 1K connections. However if you don't need so many connections you might find that simple code performs best.
Not really, as Peter noted.
However, I've found that Netty also offers a very nice API for building a server. Although there is a bit of a learning curve to the API, it's well made and creating a new server can be trivial. It's also quite efficient code-wise, so you would have very little code, if you have a simple protocol and implementation.
This is ONLY if you are building a server for something other than HTTP. If you are talking about an HTTP web application, go with the tried an true. Apache for straight HTML pages, Tomcat if you need Servlets.
HTTP web app is not necessarily go to apache httpd and tomcat:
Check this and this to see how superior nginx is compare to apache httpd
Click here to see How Play!framework (based on Netty) outperforms those based on Tomcat/Servlet
Netty is very fast, especially with many connections.
In my experience:
It's more scalable than the standard Java IO. In particular, the old synchronous Java IO packages require you to tie up one thread per connection. This can become problematic with tens of thousands of connections!
It's approximately the same speed as what you would get if you wrote custom networking code using Java NIO, but it's a lot simpler to just use Netty directly rather than go down this route.
Twitter used Netty in its Search System:
Ref: Twitter Search is Now 3x Faster
Actually using Tomcat NIO, you can get up to 16,000 concurrent connections; mind you thats CONCURRENT connections on one machine. This was tested against as a comparison vs Jetty which topped out at 4000 when they kept giving them more and more memory. (http://www.javalobby.org/java/forums/t92965.html)
And using a 'convention over config' framework like Grails with REST functionmality built in (or simple plugins like RestRPC), you can easily build API's, webhooks, etc in seconds.
I also have more control using Spring Security plugin as to who can access what api call via what IP or what role if I want.
Netty has limitations that the plethora of Grails plugins can expand far beyond using Tomcat NIO.
I'll need to develop a Java service that is simple because:
It only communicates via a TCP socket, no HTTP.
It runs on a dedicated server (there are no other services except the basic SSH and such)
Should I make this a standalone service (maybe in something like Java Service Wrapper) or make it run in a container like Tomcat? What are the benefits and detriments of both?
If you aren't working with HTTP, you will have to build your own connectors for Tomcat. When I've written these types of applications, I've just written them as standard Java applications. On Windows machines, I use a service wrapper that allows them to be part of the Windows startup process. On non-windows machines, you just need to add a start up script.
Using a container (regardless which) buys you that all the details about starting, stopping, scaling, logging etc, which you have to do yourself otherwise, and it is always harder than you think (at least when you reach production).
Especially the scalability is something you need to consider already now. Later it will be much harder to change your mind.
So, if somebody already wrote most of what you need, then use that.
Tomcat doesn't sound like a good choice for me in your situation. AFAIK it's primarily made for Servlets and JSPs, and you have neither. You also don't need to deploy multiple applications on your app. server etc. (so no benefit from ".war").
If you need dependency injection, connection pooling, logging, network programming framework etc., there are a lot of good solutions out there and they don't need tomcat.
For example, in my case I went for a standalone app. that used Spring, Hibernate, Netty, Apache Commons DBCP, Log4j etc. These can be easily setup, and this way you have a lot more freedom.
Should you need a HTTP server, maybe embedding Jetty is another option. With this option too, you have more control over the app. and this can potentially simplify your implementation compared to using a tomcat container.
Tomcat doesn't really buy you much if you don't use HTTP.
However, I was forced to move a non-HTTP server to Tomcat for following reasons,
We need some simple web pages to display the status/stats of the server so I need a web server. Java 6 comes with a simple HTTP server but Tomcat is more robust.
Our operation tools are geared to run Tomcat only and standalone app just falls off radar in their monitoring system.
We use DBCP for database pooling and everyone seems more comfortable to use it under Tomcat.
The memory foot-print of Tomcat (a few MBs) is not an issue for us so we haven't seen any performance change since moved to Tomcat.
A container can save you from reinventing the wheel in terms of startup, monitoring, logging, configuration, deployment, etc. Also it makes your service more understandable to non-developers.
I wouldn't necessarily go for tomcat, check out glassfish and germonimo as they are more modular, and you can have just the bits the need, and exclude the http server.
We faced a similar decision a while back, and some parts of the system ended up being jsw based, and the others as .war files. The .war option is simpler (well more standard for sure) to build and configure.
I want to implement a Java HTTP server locally, I mean the server computer would be in my control. I'm expecting not more than 20 clients to send requests to it.
I was wondering how to go about it:
Should I use a J2EE servlet container, like Apache Tomcat?
Could I use J2SE classes and just build it using them?
Are there any existing alternatives?
What does your experience suggest?
There's a simple HTTP server embedded in the Sun 1.6 JRE. It's not JavaEE or servlet-compliant, it's very lightweight, but it might be good enough for your requirements. No need to download any 3rd party stuff if this is all you need.
The javadocs, rather bizarrely, are out on their own, here.
Embed Jetty in your application. Aside from performing quite well, it is delightfully easy to use and configure
You've got many options, not the least of which are Jetty, Grizzly, and TTiny.
I would strongly urge against writing your own web server, unless you've got time to kill and want to spend it writing things that are already available to you for free.
Seriously, reuse an existing solution. Why the hell are you even thinking rolling your own?
Now, 1. I don't understand your question as being about embedding a container. 2. You mentioned long polling several time. So I'd suggest to use GlassFish v3 / Grizzly (because there are many samples, e.g. have a look at the Dead Simple Comet Example on Glassfish v3 / Grizzly).
If you don't want to rely on the way a container implemented Comet support, use atmosphere and any of the container mentioned on the web site:
Atmosphere is a POJO based framework using Inversion of Control (IoC) to bring push/Comet to the masses! Finally a framework which can run on any Java based Web Server, including Google App Engine, Tomcat, Jetty, GlassFish, Weblogic, Grizzly, JBossWeb and JBoss, Resin, etc. without having to wait for Servlet 3.0 Async support or without the needs to learn how Comet support has been differently implemented by all those Containers.
If this is not a concern, just stick with the suggested option (GlassFish v3 / Grizzly).
For a concrete and recent comparison between Comet server implementation, checkout this awesome Comet Maturity comparison grid view (source: Comet Gazing: Maturity). It might help you to make your final choice... or not :)
I guess the biggest question is: why do you want to build this?
If it is for the purpose of personal development, I'd stick to whatever standard libraries come with your JDK and build it on top of that.
If on the other hand you have a particular application that needs a dedicated HTTP server I would try to take one of the open source servlet containers, like Jetty or Tomcat and build on those.
Perhaps look at the list of 26 open source web servers at http://java-source.net/open-source/web-servers.
http://java.sun.com/developer/technicalArticles/Networking/Webserver/WebServercode.html is actual code in a single file implementing a multi threaded webserver. For your requirements, such as they are, this should suffice.
http://java.sun.com/developer/technicalArticles/Networking/Webserver/ is an analysis of the code.
If you will write your own HttpServer you will have to implement all the methods of the HTTP protocol. Tomcat can be easily used locally.
Is it for practice, fun, to implement special requirements or why don't you just embed an existing solution?
Do you really want to build a HTTP server that deals with the protocol directly, or do you just want to write web apps? If all you care about is writing the web apps, then just use Tomcat, or Jetty, or Glassfish, or another server -- it will save you a ton of work.
If you really are interested in writing your own server from scratch, then the best way would be to just use Java SE, and not use any existing server technology.
Ad your 3) option: Try JBoss Netty.
http://fisheye.jboss.org/browse/Netty/trunk/src/main/java/org/jboss/netty/example/http/websocket