Could you please explain what kind of issues did you find running tomcat/jboss inside containers? We've been running several apps on docker and so far no problem. Thanks a lot in advance.
Essentially, Java is already run like containers, that container being an application server of some sort. Very rarely is Java software really dependent on specific packages being installed or even which operation system aside from a particular Java VM. When you add another container layer you generally are just adding more overhead and further you have issues with correctly setting some tunable parameters like heap sizes vs container memory sizes, etc. It works, it just isn't very ideal.
Thanks for your reply spullara. We might be one of those rare cases where we do need different packages and libraries for each applications. It's the pain that we have to suffer having to maintain several "legacy" apps.
Regarding your view on an app server being a container of some sort, I do agree. We are actually starting to develop apps to be run using embeded app servers (with Spring Boot), as it fits better when running apps using docker.
Tomcat/Jboss are resource hogs and tend to not do well in sandboxed environments as it takes away a lot of the configurability/tuning that they provide/need for scaling. In addition, people tend to deploy multiple applications per application server to keep resources requirements down: containizeration tends not to lend itself to multi-application stategies (in particular resource heavy applications like those that run on the JVM). This is far from something that makes java an impossibility but it changes the techniques enterprises are accustomed to. Technologies like Jetty provide a good solution to the problem, and will probably see wider adoption as containers become more prevalent.
As someone that has deployed multiple production applications in Tomcat and Jetty, I would never choose Jetty again. The concept is good but it has severe quality issues and does not offer the same stability as Tomcat. At one point we had to fork Jetty to fix critical problems, never again.
Interesting point. I've never had an issue with Jetty, though I've never ran it at huge scale before. I've used it for internal business systems which at peak require 1000 req/s which isn't a whole lot. Do you run an wrapped tomcat to create fat jars or Tomcat as a standalone application server?
Thanks a lot for your answer. We create a separate container for each application, as it seemed like the correct approach. In our company we do have several "levels" of library (even jvm) version requirements. Containers have been very helpful to easy the pain that was managing that on the server side.
I've found that building fat JARs with all dependencies bundled solves a lot of the same dependency management issues containers can be used for. And it does it without container overhead.
That's what we do now: fat JARs, including all dependencies and use embedded app server. On top of that, we use docker containers so we can control de JVM version as well. The overhead is not that high and it gives us the benefit of knowing that the same container that the developer/jenkins tested is the one that passed QA and will run in production.
To update on this since I am a Java programmer who is picking up c again after 10 years:
In modern Java world people often maven or another project tool where upgrading a library is as simple as changing the version number in a "pom" file, push and wait for Jenkins to finish build, unit and integration tests.
Not kidding here, this is one of the things I love about Java development.
Just worked on deploying OpenAM on tomcat with Docker. A few things stuck out to validate the "hard to deploy in containers" point:
(1) node.js/Ruby/Python scale with processes, not threads. There's no supervisory/control environment over the processes, just the OS. JVM on the other hand expects to do a lot more process/thread control itself so it's kind of another "layer" between the OS and your code.
(2) Port binding doesn't work the same way, either. Most of our dockerized services have one port/process with simple load balancing built into our "routing fabric", which is something ops controls at my company. My understanding of JVM scaleout is that the servlet container is responsible for multiplexing incoming connections onto free capacity, which isn't how most docker shops work.
(3) I'm not sure what the typical deployment patterns are for servlet containers but they seem more multi-tenant w.r.t # of applications running in them, vs. a typical docker setup where containers are very thin and meant to be run in the dozens or more per-machine.
It's not that the JVM is inherently inferior, more than Docker has grown up around unix/linux ops-minded folks and they're bringing a lot of their assumptions about how software should be deployed and operated (e.g. "things should be scriptable") with them, and that their thinking is dominant among the current container-using crowd.
My understanding of JVM scaleout is that the servlet container is responsible for multiplexing incoming connections onto free capacity, which isn't how most docker shops work.
No, not really, typically you would just run N of your JVM processes with either some sort of load balancer (or your "routing fabric") to balance between them or a discovery mechanism.
I think you might be referring to some sort of big-box "enterprise" servlet container like Websphere or something quite different than Tomcat.