I'm learning to deploy Spring Boot apps on AWS EC2. And I know how to automate app launch, when I start the EC2 instance, I don't need to manually use the command java -jar java-service.jar, I just add this command in the /etc/rc.local file and that is all. But I have 2 microservice, and I want to start both of them automatically, but if I try to add both commands in the /etc/rc.local it's not working, only the first service will start, the second service will not start.
So I have the commands added like this:
And after I start the EC2 instance only the first service is started:
Thank you!
I am not a unix expert, but I see the only issue in running 2 java commands from terminal is that unless the first command returns, the next command is not executed. So, I think the solution would be run the 1st command in some interactive mode so that the other commands can be executed simultaneously.
There are ways in unix shell to run a command in background. I found this useful link - https://www.maketecheasier.com/run-bash-commands-background-linux/
In bash terminal, a command can be made to run in background by appending it with &. So, I think you should be able to start both jars if you do something like -
java -jar /home/ec2-user/first.jar &
java -jar /home/ec2-user/second.jar
I recommend to use Systemd.
Create a Systemd unit file for every microservice, save it in /etc/systemd/system/my-app.service. Something like that:
[Unit]
Description=My Java app
After=syslog.target network.target
[Service]
EnvironmentFile=/etc/sysconfig/my-app-env
WorkingDirectory=/my/app/home
ExecStart=/usr/bin/java $JAVA_OPTS -jar my-app.jar
KillMode=process
User=my-app-user
Restart=on-failure
[Install]
WantedBy=multi-user.target
Then, run:
systemctl daemon-reload
systemctl enable --now my-app
After that, you can use:
systemctl status my-app
systemctl stop my-app
systemctl start my-app
Another solution is to bundle your jars into Docker images. This of course requires Docker runtime and adds an overhead, but it also has some benefits:
Complete separation of jar files. Easily use different java versions.
No need to worry about differences of local and ec2 environment.
Easily scale to 3 or more jars.
Use Docker Cli to build and start containers. Works great in a Devops Pipeline.
You can read here to learn how to create Spring Boot Docker images. After you build an image. You start it like this.:
docker run -p 8080:8080 springio/gs-spring-boot-docker
You can run as many docker run commands you need, one after another.
I am not sure which system you are using in starting application:
For linux base system, you can use crontab to schedule the task when the server reboot.
Follow this steps:
Download crontab
#apt-get install cron
Edit the file file to enable the task
crontab -e
(Choose Vim or nano to edit the task)
Add this code to your server
#reboot /usr/bin/java -jar XXXXX.jar
Save your file
Check the result
crontab -l
#systemctl status cron
This method works in my Debian system. For more details, you can refer to
How to automatically run program on Linux startup
If you are running from bash, then join two jar commands with "&" like below.
java -jar /home/ec2-user/first.jar&java -jar /home/ec2-user/second.jar
coupon service
Run the command 'java -jar /home/ec2-user/coupon-service-0.0.1-SNAPSHOT.JAR'
Press CTRL+Z, type bg, press Enter, type disown, press Enter.
product service
Run the command 'java -jar /home/ec2-user/product-service-0.0.1-SNAPSHOT.JAR'
Press CTRL+Z, type bg, press Enter, type disown, press Enter.
NOTE: Both services should have different ports.
Related
I am new to Java. I have hapi fhir server running on AWS by cloning this repository (https://github.com/hapifhir/hapi-fhir-jpaserver-starter)
I run my server with follwing command: "sudo mvn -e jetty:run"
--
My Problem:
As soon as I log out of AWS, my server stops. When I am logged in to my AWS instance via the .pem file, AWS instance running with ubuntu 18.04 LTS with nginx server.
Thanks
The ideal approach to execute or setup a java application on AWS is to run it as a daemon by setting up systemd script or init in linux.
In your case the application stops as soon as you close the terminal, because you are starting it in the terminal without the nohup command, when the terminal is closed the application is also stopped since the controlling thread is stopped. If you just want to launch the application on a separate background thread without going through the hassle of actually setting it up as a service in linux , you can use the nohup command (setting up a systemd to register the java application as a service is the preferred approach) :
nohup java -jar yourjarName &
run it as daemon:
"sudo mvn -e jetty:run &"
The & makes the command run in the background.
From man bash:
If a command is terminated by the control operator &, the shell
executes the command in the background in a subshell. The shell does
not wait for the command to finish, and the return status is 0.
So I'm deploying my Spring Boot application on an Ubuntu LTS Server. It is built with maven and running with embedded Tomcat.
I'm still new to the deployment process, what I did was:
Log into server via ssh
use scp to upload my_application.zip
unzip it in ssh
java -jar my_application.jar
Now all of that works perfectly fine and I've been using it like that for quiet some time. Now I have to make the Application to stay online and available after logging out of the shell.
I have read some documentation about running processes in background on Linux and I've tried it with nohup java -jar myApplication.jar &, with the screen command and with bg. All of them worked fine while I'm logged into the ssh.
Here comes my problem:
As soon as I end the ssh session the Web App is still available (so the process clearly didn't stop) but it just looks & behaves really weird.
CSS is not applied, JS does not work etc.
My guess would be that some paths or file system accesses are messed up, but I have no idea at all how that could origin from the ssh session.
(When I log back into ssh everything is working fine again)
Would be great if someone has a clue here
If your server has encrypted home directory, it will get re-encrypted once you log out and therefore your script will stop working. It does not have a lot of sense to have encrypted homes on servers so you can disable it.
Or just run the script from different directory and avoid working with files under home directory.
I think you should use systemd for this case.
Also You can add new system user for your app.
You can find more information here:
Spring Boot: 59.2.2 Installation as a systemd service
Ubuntu Wiki: Systemd For UpstartUsers
For example:
Create file myunit.service
[Unit]
Description=MySpringService
After=syslog.target
After=network.target
After=mysql.service
[Service]
Type=forking
PIDFile=/work/www/myunit/shared/tmp/pids/service.pid
WorkingDirectory=/work/www/myunit/current
User=myunit
Group=myunit
Environment=RACK_ENV=production
OOMScoreAdjust=-1000
ExecStart=/usr/local/bin/bundle exec service -C /work/www/myunit/shared/config/service.rb --daemon
ExecStop=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop
ExecReload=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart
TimeoutSec=300
[Install]
WantedBy=multi-user.target
Copy file to /etc/systemd/system/
Run:
systemctl enable myunit
systemctl start myunit
Using normal spring mvn commands, I can start a spring boot application from command line and terminate it with Control+c. I however have created a bunch of services which I will dockerize later. For now they are plain java jar files generated by mvn. How do I use a python script or a Bash script to start them one by one and then use a script to terminate them. Is there some way where i start it and script won't block and the app will have a name that i can later use to stop the app?
I would follow the documentation to install Spring-Boot application as a Unix/Linux service.
All you have to do is to add this dependency to your pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
After adding the plugin you should install and create a symlink to your application (exact part of documentation):
Assuming that you have a Spring Boot application installed in
/var/myapp, to install a Spring Boot application as an init.d service
simply create a symlink:
$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
Once installed,
you can start and stop the service in the usual way. For example, on a
Debian based system:
$ service myapp start
Then you are able to create a bash script to start, stop or restart your applications in a clean way.
You could use a script to achieve this. For example a startup.sh may look like this. It will start the application and write the process id to /path/to/app/pid.file
#!/bin/bash
nohup java -jar /path/to/app/hello-world.jar > /path/to/log.txt 2>&1 &
echo $! > /path/to/app/pid.file
And a shutdown.sh may look like this.
#!/bin/bash
kill $(cat /path/to/app/pid.file)
You can find more detail in my post. https://springhow.com/start-stop-scripts-for-spring-boot-applications/
You can launch each jar with the following command (in a bash script):
java -jar service1.jar &
Then, you can kill each process with the following command (in a bash script):
pkill -f service1.jar
pkill will terminates all processes containing the provided name. Be careful that your keyword only identifies your process, so you don't terminate other processes by mistake.
This script make it easy, auto find newest version of jar file:
https://github.com/tyrion9/spring-boot-startup-script
./bootstrap.sh start
./bootstrap.sh stop
./bootstrap.sh restart
I am running my project as jar using java -jar command in Linux machine. As soon as this program run , It produces logs in another directory. Running my program this way requires me to keep the shell open. Now If I have to see the logs , I can't do that in the same shell. I am forced to do that by either doing the duplicate session or new session. Is there any way I can run the jar as background process and see the logs in the same shell ?
If you don't care about it staying alive, something as simple as nohup java -jar myjar.jar & should work. If you need it to be automatically restarted if it crashes or start automatically at boot, you'll want to look into something like systemd or monit.
my server program needs to be launched on the startup of an EC2 instance. At the minute im just launching it from my SSH with the following commands:
java -jar ~/DocumentManager/DocumentServer-0.2.jar
I tried adding this to the .bashrc and /etc/rc.local files but they only seem to work when i ssh in.
Anyone know how to make it so an instance of my application is launched when the computer boots?
Thanks,
Ben
It's possible you can create a script java_server_launch.sh like this:
#! /usr/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
JAVA=/usr/bin/java
MY_SERVER=/home/your_username/DocumentManager/DocumentServer-0.2.jar
USER=your_username
/bin/su - $USER -c "$JAVA -jar $MY_SERVER &"
Put your script under /etc/init.d directory, and then use the command:
update-rc.d java_server_launch.sh defaults
more on update-rc.d command by using man update-rc.d.
Hope this help.
Regards.
Add ampersand(symbol '&') at the end of the command.
For example, in your case, java -jar ~/DocumentManager/DocumentServer-0.2.jar &
Old question, but my answer might be helpful for people who look in future.
You can also run your program as a service which automatically run on ec2 container reboot. Below link worked for me:
https://medium.com/#lizlieholleza/run-your-java-application-as-a-service-in-an-ec2-instance-amazon-linux-d7c7b4c0b2f4