I have 5 Spring Boot web applications but have only one Server (low-end).
What is the best way to deploy all 5 in one Server? Having only one web container (Tomcat) and deploy all of them as separate war files on the same Tomcat or run all 5 on different Tomcat containers (Spring Boot default behavior)?
What is your recommendation by considering performance and maintenanability?
IMHO, if you're running a resource-constrained server, your best bet is to deploy all of your applications as war files under a single tomcat instance. Running multiple servers would just add un-needed overhead.
If you have little resources on your server, you don't have much choice. Each Java virtual machine has a significant overhead, so running separate containers will make you reach the limits of your low-end server earlier.
You will have to deploy your wars in the same tomcat server, with different servlet contexts.
However, if you have sufficient RAM, the cleanest way in my opinion is creating docker images and running the standalone spring-boot jars in each container.
My recommendations are:
If these WARs are independent of each other, deploy them in a different Web server, not only Tomcat or whatever container you're using, but also in either different virtual server, dedicated server or Cloud instances.
Deploying in different "virtual server" you can scale horizontally, so this is good for future workloads.
Deploy a load balancer from your hosting provider, or you can use Nginx for doing that.
Hope this helps!
From my experience, using container such as docker is the easiest way to maintenance multiple spring-boot applications. When you have a new server, it can be migrated easily, and the application can be updated without interrupting other applications. But you may need to spend extra time to learn how to use the container.
If using Tomcat, it is recommended to separate the tomcat instances. One tomcat for each WAR file. Putting multiple WAR files in one tomcat can make the maintenance difficult. Tomcat hot deployment / auto deploy tends to have some errors which require you to restart the whole tomcat
Related
I´m trying to get more familiar with Docker because everyone talks about it and everyone loves it. I know how Docker works in general, but I don´t understand how to used it in practice.
In my case, I have several web applications running on Tomcat. As far as I understand, it´s common to have one Docker container per application. But what does that mean in my case?
Should I have several containers each running Tomcat which in turn runs one web application? Or would I have only one container with Tomcat where all web applications are deployed on?
Understand why you will dockerise all your applications which are running in single tomcat instances ?
Lets say if your tomcat goes down then all your application will go down. So
Docker with microservices is the trend which tells a docker container should not have mutiple applications running i.e single resposibilty model.Avoid one container being responsible for multiple aspects of your overall application.
What will happen if you put all your applications in single docker ?
Availability : if container goes down all application will go down. Example : If you have ecommerce application and if offers service goes down then you should be able to do other stuff other that checking offers.
Deployment : If you need to deploy an application then all application will go down. for example : if you want to deploy offers update would it be correct to stop all running users which may be doing payments or other stuff?
Application Load and scaling :Lets say you have the modules, Payment, offers and shipping. I would expect the offer module will have more load than all others. So we can horizotal scale the offers service. But if we would have all application in single container then all application will be scaled which waste of resources.
Refer a nicely written nginx tech blog : https://www.nginx.com/blog/introduction-to-microservices/
Let me know if you have any questions more to ask. feel free to add comment.
Generally, it is better to run a Tomcat Docker Container for each .war app with filebeat or any other log shipping program in conjunction with single or fewer frontend containers. So 2 Frontend Web Containers for High Availability with 4 Tomcat Containers each serving a Tomcat app.
I'm complete able to configure spring boot in both cases, the question here is which of them are more robust and is the more recommended, because I didn't find in the spring boot documentation the recommended way to deploy it in a production environment, my concerns about use the embedded container are:
If I want to set it as a Windows or Linux service, is the jar file the best option?
If I use the jar file I'm not going to have access to restart the server.
Maybe in the future I need more applications in the same container.
If I restart the machine I have to execute again the java -jar.
The question in general is which is better use the jar file and execute it as java -jar jarname.jar in production or change the packaging to war set the tomcat as provided and set the generated war in an empty tomcat.
I hope you can help me.
---EDIT---
Many times the answer is depends, this is for a normal web application or REST web service.
jar packaging is perfectly suitable for production and you should rather fallback to war only if you really have to - which is often the case when you cannot control your deployment environment (which is often the case in large enterprises).
There is a chapter in Spring Boot Reference about setting up Spring Boot based application as a Unix/Linux/Windows service: Installing Spring Boot applications.
Regarding your concern:
Maybe in the future I need more applications in the same container.
With embedded containers if you need more applications running on the same machine, you should start two applications separately, each running on different port and effectively you will end up with two containers running - which is good, applications are better isolated from each other.
About a month ago I had the question like yours.
Let me share my conclusion:
1) JAR:
You can run independently every appliction with different ports (in linux, java -jar ... > app_logs.log &) and you can route it (e.g. nginx). Note that, restarting is not problem. You can write custom bash script (like this: ps aux | grep appname and kill by PID)
But there are some problems with configuring production app. Property files will archived into jar.
2) WAR
You can deploy into container and just run it. Easy managing at the server. If you want to re-configure app, open properties file from unarchived folder inside container, change it as need and restart container. So, managing and configuring will be easy.
But, if you want to run another app in this server with another port, then you must install another copy of container and config it.
So, in my practice, using war app easier than jar to manage and re-configure.
I don't know that much about Windows services but on Linux you can add the execution of a jar to a RC-Scripts (and thus make the application start at a certain run-level). For a spring boot app you just have to symlink to the jar and you can start/stop/etc like any other service, see: Spring Boot application as a Service
restart the machine or the JVM? A shutdown mechanism is built into spring boot, you just have to activate it (and you should enable security machanism so that not anybody can do that), see: How to shutdown a Spring Boot Application in a correct way?
Spring-Boot enables microservices - so the idea is to have one embedded webapp-container for each webapp/microservice. This reduces the risk of losing all services when only one is going down.
Yes. and you have to execute catalina.sh|bat start after every restart. Or you add an appropriate startup script (see 1.)
I sense that you'd rather do it the old-fashioned way. Despite the 'matter of taste' answer, there is one argument pro-jar: the only dependency is the JVM! The rest (the web-app-container, db-drivers, other libraries) is all part of the package you deliver. And if you decide to change the container for the next release, so will it be.
One more reason to use "war" file in production.
Springboot masked an error Jetty threw whereas WAR deployed in Jetty correctly caught it ( though issue below is still under review )
https://github.com/spring-projects/spring-boot/issues/8917#issuecomment-294673487
I don't know much about server kind of things, But my recommendation is
If you are using Monolithic application, better to use war with
external tomcat.
If you are using for Micro Service applications, use embedded
tomcat with different port. And each micro service applications are
independent from each other.
In the past when a new webapp or set of services was to be deployed, it was common practice to be given a new vm with tomcat installed on to deploy to. With my current position the client is only giving me one linux instance to deploy several webapps to. (Small internal usage, 0 scaling. Deploying to a single AWS EC2 linux machine)
The applications are required to be given unique domains. ie app1 and app2 could be mapped to smallapp1.com:8080/app1/login and smallerapp2.com:8080/app2/login (ports are for example only and not a requirement)
I currently have two installations of tomcat8 running on the instance and each application is deployed to a unique tomcat install and running on different ports. (one is 8080 and the other 8081).
If I were to want to deploy a handful of other small applications would I be better off using individual tomcat installations or should I be using Virtual Hosting?
I am new to deployment. In the past I was handed a deployment destination and procedure. In the new position I was simply given credentials to a single instance. I am not sure what is better practice or in which situation which is better than another. If it matters, each application is only ever going to be used by a maximum of 20 users at the same time.
TL;DR Using multiple installations of tomcat on the same instance or using the same tomcat installation to host multiple applications.
Virtualhosts is a better option because you are not bloating the server with several installations that could conflict with each other, and you are to take 1 port for each instance of tomcat.
Keep in mind that tomcat is a better solution for Java web applications, if you are not running servlets or JSPs you are better off using Apache Http server.
I have several applications running under Tomcat and some applications running on WebLogic. I need to bring them all together under a single domain and also share the static resources among all applications.
I am thinking of using the Apache web server as a front controller and use the WebLogic proxy plugin to route requests to applications running on WebLogic and Tomcat plugin to route requests to applications running on Tomcat.
Is there any disadvantage to this approach? Or is there any other better solution?
I'd :
put shared resources to a predefined NFS, defined in & accessed from both app servers
set caching on and serve static content from apache
distribute applications among physical servers based on their memory and cpu requirements
Apache Derby has an option to run its "Network Server" as a web application in a servlet container (derby.war).
The problem is then how to deploy other applications that depend on derby in the same container to load after derby loads (preferable in a Tomcat container).
From what I recall there is no way to control the order of web application initialization in Tomcat.
Has anybody gotten derby.war to work in a multiple web application environment?
You'll probably find it easier and more reliable to run the Network Server in a separate standalone process of its own, rather than as part of the Tomcat process. It will make it easier to start, stop, control, and administer your Derby databases separately from your applications.
I had a similar issue too, but with HSQLDB. I went to using standalone instances.