Which application container is better for Docker container? - docker

Our future architecture is to move towards docker /micro services. Currently we are using JBoss EAP 6.4 (with potential to upgrade to EAP 7) and Tomcat.
According to me JEE container is too heavy (slow, more memory, higher maintenance etc) for microservices environment. However, I was told that EAP 7 is quite fast and light weight and can be used for developing microservices. What is your input in deciding EAP 7 vs Tomcat 8 for docker/microservices? Cost and speed would be consideration.

EAP7 vs Tomcat 8 is an age old question answered multiple times here, here and here.
Tomcat is only a web container where as EAP7 is an application server that provides all Java EE 7 features such as persistence, messaging, web services, security, management, etc. EAP7 comes in two profiles - Web Profile and Full Profile. The Web Profile is much trimmer version and includes only the relevant implementations typically required for building a web application. The Full Profile is, as you'd expect, contains full glory of the platform. So using EAP 7 Web Profile will help you cut down the bloat quite a bit.
With Tomcat, you'll have to use something like Spring to bring the equivalent functionality and package all the relevant JARs with your application.
These discussions are typically helpful when you are starting a brand new project and have both Java EE or Spring resources at hand. Here are the reasons you may consider using EAP7:
You are already using EAP 6.4. Migrating to EAP 7 would be seamless. Using Docker would be just a different style of packaging your applications. All your existing monitoring, clustering, logging would continue to work. If you were to go with Tomcat, then you'll have to learn the Spring way of doing things. If you have time and resources and willing to experiment, you can go that route too. But think about what do you want to gain out of it?
EAP 7 is optimized for container and cloud deployments. Particularly, it is available as a service with OpenShift and so you know it works OOTB.
EAP 7 will give a decent performance boost in terms of latency and throughput over EAP 6.4. Read https://access.redhat.com/articles/2607521 for more details.
You may also consider TomEE. They provide Java EE stack integrated with Tomcat.
Another option, as #Federico recommended, consider using WildFly Swarm. Then you can really start customizing on what parts of the Java EE platform do you want. And your deployment model is using a JAR file.
As for packaging using Docker, they all provide a base image and you need to bundle your application in it. Here are a couple of important considerations for using a Docker image for microservices:
Size of the Docker image: A container may die unexpectedly or orchestration framework may decide to reschedule it on a different host. A bigger image size will take that much more longer to download. This means your perceived startup time of the service would be more for a bigger image. This also means dynamic scaling of the app would take longer to be effective.
Bootup time of the image: After the image is downloaded, the container may startup quickly but how long does it take for the application to be "ready"?
As a personal note, I'm much more familiar with Java EE stack than Tomcat/Spring, and WildFly continues to be favorite application server.

Besides using traditional Application servers, which are not really that heavy, you can taste different flavor of Java EE, called microcontainers.
Java EE is just a set of standards. Standard results in an API specification and everyone is then free to implement the specification. An Application Server (AS) is mainly a fine-tuned collection of this functionality. Those APIs were not brought to life for no reason. These represent functionality commonly used in projects. Application server can be viewed as a "curated set" of those functionalities. This approach has many advantages - AS has many users, therefore it is well tested over time. Wiring the functionality on your own may result in bugs.
Anyhow, a new age has come, where with Docker, the application carries its dependencies with it. The need for a full-blown application server with all the functionality ready to be served to applications is no longer required in many cases. In times past, the application server did not exactly know which services the applications deployed will need. Therefore, everything was bundled in. Some of more innovative AS like WildFly instantiated only the services required. Also, there are Java EE profiles which eased the monolith Application Server a little bit.
Right now, we usually ship the application together with it's dependencies (JDK, libraries, AS) inside a Docker - or we're heading there. Therefore, an effort to bundle exactly the right amount of is a logical choice. But, and it is a "big but", the need for the functionality of the AS is still relevant. It is still good idea to develop common functionality based on standards and common effort. It only no longer seems to be an option to distribute it as one big package, potentially leaving most of the APIs inactive. This effort has many names, be it microcontainers, uberjar creators ...
WildFly Swarm
Payara Micro
Spring Boot*
There are Java EE server so light it is doubtful to use anything else.
* Spring Boot is not based on Java EE and in default configuration present in the Getting Started guide, Tomcat is used internally.
WebSphere Liberty
Apache TomEE
The key point is, your Java EE application should be developed as an independent Java EE application. Wrapping it with "just enough" functionality is delegated onto these micro solutions. This is, at least in my humble opinion, the right way to go. This way, you will retain compatibility with both full-blown AS and micro-solutions. The uber-jar, containing all the dependencies, can be created during or after the build process.
WildFly Swarm or Payara Micro are able to "scan" the application, running only the services required. For a real-world application, the memory footprint in production can be as low as 100 MB - for a real-world application. This is probably what you want. Spring Boot can do similar things, if you require Spring. However, from my experience, Spring Boot is much more heavyweight and memory hungry than modern Java EE, because it obviously has Spring inside, so if you are seeking lightweigtness in terms of memory consumption, try Java EE, especially WildFly Swarm (or pure WildFly) and Payara Micro. Those are my favorite AS and they can be really, really small. I would say WildFly Swarm is much easier to start with, Payara micro requires more reading, but offers interesting functionality. Both can work as a wrapper - you can just wrap your current project with them after the build phase, no need to change anything.
Payara Micro even provides Docker images ready to use ! As you can see, Java EE is mature and ready to enter Docker lands :)
One of the very good and reliable resources is Adam Bien, for example in his Java EE micro/nanoservices video. Have a look.

Related

Neo4j rest server v/s embedded

In which mode neo4j database should be used embedded or rest server?
My main concerns are :
Performance
Horizontal scaling (HA,Clustering) - essential as application is very big.
Transactional support(in frameworks like SDN,Grails Plugin,structr etc.)
Deployment server support like amazon,GrapheneDB etc.
Easiness of switching from one to another
Scaling(size of database)
Disclaimer: I'm one of the founders of GrapheneDB.
I'm not an expert in embedded mode so my answer might be biased but I will try my best:
Embedded is more performant at this time than server
Clustering is supported in embedded as well as in server
Transactional support is available in both modes AFAIK. Spring Data, however has currently bad performance over Rest/server.
From my POV embedded has the disadvantage of being coupled to your app/server deployment.
There is one more option which you haven't brought up, which is using unmanaged server extensions.
Using extensions you can get the best of both modes:
You write your code on top of the Java API and it's executed locally, so you get extremely good performance.
You can run the server in server mode, making operations easier and also enabling you to host on a separate remote host, on any cloud environment.
GrapheneDB supports unmanaged extensions and it's the option we currently recommend for scenarios where extra performance is needed.

Calling a windows .exe (compiler) from Rails app on Heroku

I would like to know if this is even feasible. And if so, what a possible approach would be.
I am thinking that the .exe would have to be made available through a web service running on a windows stack (asp.net or php) and that a direct heroku solution would not be the way to go.
If you do it as a externally, yes. The main trick there would be making the service on the windows box and making sure your service was secure. If you're going for cloud stuff, your best bet is probably to set your service up on a windows server on EC2 or Rackspace or [insert cloud provider here]. They're not as cheap as linux boxes because of the license cost, but shouldn't be too difficult to manage.
Unless Heroku has changed a lot from the last time I looked at it, the underlying OS was linux of some variety, so it's really unlikely that you could get an windows binary to run internally without bundling wine into your application (probably not worth trying to figure out).

What it the real benefit from Erlang's fault tolerance for a web project?

Let's assume we have a web project in which we want to have ~10000 web clients connected to the server simultaneously. Let's also assume that one client session lasts about 25 minutes.
If we compare LAMP stack or any other popular web stack/framework (Ruby on Rails with Apache on Linux, etc.) to a web project built in Erlang/OTP - what does Erlang/OTP have in terms of fault tolerance that other frameworks don't?
What event can happen to a client that will cause the whole LAMP stack crash, while Erlang/OTP will stand its ground?
Note that a typical LAMP-stack does employ some fault tolerance. In particular, if a request in the LAMP stack fail, only that request will, while the rest of the code will run on. This kind of protection allows you to have faults in a single request without that hurting other requests.
Erlang provides this idea of "able to cope with smaller unforseen errors" at a much finer grained scale. You may have other subsystems in an application, and the same kind of tolerance to errors can be extended to those. You won't get it "for free", but the tooling is there to build a system which is robust. Imagine a client error in the LAMP stack. This will often lead to a disconnect of that client. It may not be so in Erlang and the client can keep on running.
For a system of 10000 clients, Erlang provides the advantage that you can have a process per client. Or perhaps 10 processes per client. That is much harder to pull of in many languages since a process/thread is rather heavy and expensive. Note that interprocess communication between the clients are easy, also if some clients are on another machine (imagine extending to a distributed cluster some day).
If you write your code in a certain way, you can make sure that if a client crashes, for one reason or the other, then its state is properly cleaned up by other processes. That can avoid lots and lots of small nasty leaks in state as well.
what does Erlang/OTP have in terms of fault tolerance that other frameworks don't?
Now, Erlang/OTP has very minimal if not, Zero side effects. Because of its concurrency, a web server like yaws literally spawns a small web server for every connection. If one user is affected by a given web service fault in your application, all other users will never notice and the only that users process may exit.
With OTP, you can build applications with a number of supervisors, such that if a server goes down, its restarted and many other functions and options you may need.
Erlang's distribution allows us to write distributed applications. I have personally used yaws web server in building a web application.
My experience is that which ever web server you may pick, say Mochiweb, a tutorial found here: http://alexmarandon.com/articles/mochiweb_tutorial/, is quite impressive in performance. Infact, a few years back, the oldest version of yaws web Server was bench marked with the (then) newest version of Apache, and the results of the bench mark are very awakening. When i went through a million user comet application with Mochiweb, which has Part 2 and Part 3, i was impressed. These are some of the few examples of powerful web frameworks built for the web.
And by the way, have you heard of these new NO SQL Databases with REST (HTTP) interface developed in Erlang/OTP e.g. Membase Server [home page here: http://www.couchbase.com/products-and-services/membase-server], Couch DB, and Riak, their performance is very impressive, meaning that their web/REST interface is very stable and due to their impressive , documented write through put, they have proved that their underlying Technology (Erlang/OTP), was built not only for high availability and fault-tolerant systems only, but for the web too! Just read through this document: http://blog.couchbase.com/why-membase-uses-erlang
Many more web frameworks built in erlang and are very impressive can be found listed on the wiki page here: http://en.wikipedia.org/wiki/Erlang_(programming_language). A probably better summary of its features that make it powerful on the web can be found in here: http://cs.nyu.edu/~lerner/spring10/projects/Erlang.pdf

Should separate Erlang applications share the same VM on the same machine?

I have a CouchDB instance running on one machine, and thus with its own Erlang VM process. If I have another separate Erlang application running on that machine too, is it be better to share the same VM between CouchDB and my application, or is it recommended to start a new Erlang node?
While many would recommend decoupling these subsystems I would take the opposite approach. Erlang has a built in strategy to run many applications on the same release. If your applications talk to each other directly it might make sense for you to bundle them together into a release. This will make calls between the applications faster. Some will argue that all you applications now share the same fate should you need to take the system down for an upgrade that only one of the applications needs. This is a moot point with Erlang where you are distributing your applications across many nodes. Also most upgrades can be done with hot code loading.
There is no problem with running several VMs on the same machnie (at least recent OTP releases), however it is quite handy if you have all your applications on one Erlang node. Easier communication, dependency management, supervision, fault-tolerance - you get it for free in this case, not mentioning maintaining only one 'node' in source control system.
The problem starts with CouchDB. It does not have decent build system which let you use it as one of independent Erlang node applications. So in this case you need to have at least 2 VMs (one acts as Couch daemon, the other one hosts your application)

Cloud computing: Learn to scale server up/down automatically

I'm really impressed with the power of cloud computing when it comes to the possibility to scale up and down your facilities depending on your load.
How can I shift my paradigm and learn to write my applications in that way? Write it once and forget(no matter of the future load) would be the best solution.
How can I practice my skills in that area?
Setup virtualization environment when I can add another VMs into the private cloud(via command line?) on some smart algorithms to foresee the load for some period of time?
Ideally I want to practice it without buying actual Cloud computing services and just on my hardware.
The only thing I want to practice here is app/web role and/or message queue systems scaling when current workers have too many jobs in queue. So let's rule out database scaling from the question's goal as too big topic.
One option I will throw out is to use a native Cloud execution framework. You might look at CloudIQ Platform. One component is CloudIQ Engine. It allows you to develop cloud native apps in C/C++, Java and .NET. You get the capabilities of scale up by simply adding workers to your cloud. The framework automatically distributes your applications to the new machine(s), and once installed, will begin sending work to them as requests come in. So in effect the cloud handles your queueing issue for you.
Check out the Download and Community links for more information.
You should try AWS- Amazon's offering a free tier that gives you storage, messaging and micro instances (only linux). you can start developing small try-outs without paying. writing an application that scales isn't that hard- try to break your flow into small, concurrent tasks. client-server applications are even easier- use a load balancer to raise\terminate servers by demand.

Resources