[Java] Chạy file .jar như một service trên linux

1. Bài toán

Xin chào, mình là lập trình viên Java.
Vừa rồi mình gặp tình huống là sau khi code trên IDE xong, thì clean & build ra file .jar để deploy chạy trên server (Linux).

Đây là câu lệnh mà sử dụng để chạy file .jar không thông qua IDE

java -jar -Dspring.profiles.active=test application.jar

Trong đó "-Dspring.profiles.active=test" là khai báo profile để chạy, có thể không cần care tới đoạn này, nếu file .jar của bạn không có các profile khác nhau (ví dụ profile: dev, test, prod...).
Tuy nhiên điều này phát sinh vấn đề là mình luôn phải treo cửa sổ terminator, chỉ cần close terminator hoặc Ctrl + C thôi là service application.jar lập tức sẽ bị stop.
Mình không thể lúc nào cũng ssh vào server, rồi treo cửa sổ terminator như vậy mãi được.

2. Giải pháp

Đây là giải pháp mình cũng google xong lượm nhặt chỗ này 1 ít, chỗ kia 1 ít, rồi chắp vá, lắp ráp lại cho hoàn chỉnh thôi.
Mình cũng đã search google, chưa thấy có bài nào viết bằng Tiếng Việt, nên mạnh dạn viết bài chia sẻ 😄 hehe

// Lưu ý: cái này mình thực hiện trên server Ubuntu 14.04, nếu bạn muốn thực hiện trên server Linux nhân khác, sẽ cần tùy chỉnh lại.

2.1 Step-By-Step

Bạn có để ý khi để start, stop, restart 1 service nào đó trên ubuntu. Thì bạn sẽ cần phải gõ lệnh với format kiểu kiểu như sau

service your-service-name start

Vậy giờ mình muốn chạy ứng dụng của mình cũng kiểu như vậy thì làm sao?

  1. Cd vào đường dẫn
cd /etc/init.d/
  1. Tạo 1 file với tên bất kỳ.
    Ví dụ: myservice.
nano myservice

// mình thích nano, và ghét vim
Và paste vào bên trong file có format nội dung như sau

#!/bin/sh
SERVICE_NAME=myservice
PATH_TO_JAR=/home/share/application.jar
LOG_DIR =/home/share/log.txt
PID_PATH_NAME=/tmp/application-pid
case $1 in
   start)
       echo "Starting $SERVICE_NAME ..."
       if [ ! -f $PID_PATH_NAME ]; then
           nohup java -jar -Dspring.profiles.active=test $PATH_TO_JAR  >> $LOG_DIR 2>&1&
           echo $! > $PID_PATH_NAME
           echo "$SERVICE_NAME started ..."
       else
           echo "$SERVICE_NAME is already running ..."
       fi
   ;;
   stop)
       if [ -f $PID_PATH_NAME ]; then
           PID=$(cat $PID_PATH_NAME);
           echo "$SERVICE_NAME stoping ..."
           kill $PID;
           echo "$SERVICE_NAME stopped ..."
           rm $PID_PATH_NAME
       else
           echo "$SERVICE_NAME is not running ..."
       fi
   ;;
   restart)
       if [ -f $PID_PATH_NAME ]; then
           PID=$(cat $PID_PATH_NAME);
           echo "$SERVICE_NAME stopping ...";
           kill $PID;
           echo "$SERVICE_NAME stopped ...";
           rm $PID_PATH_NAME
           echo "$SERVICE_NAME starting ..."
           nohup java -jar -Dspring.profiles.active=test $PATH_TO_JAR >> $LOG_DIR 2>&1&
           echo $! > $PID_PATH_NAME
           echo "$SERVICE_NAME started ..."
       else
           echo "$SERVICE_NAME is not running ..."
       fi
   ;;
esac 
  1. Để chạy được myservice, bạn bắt buộc phải gán quyền cho file này.
sudo chmod 777 myservice

// Không liên quan, cơ mà mình thích quyền 777

  1. Thử nghiệm với command thôi
service myservice start

And log:

Starting myservice ...
myservice is already running ...

2.2 Giải thích

1. Về đường dẫn /etc/init.d/

  • Chỉ là đường dẫn mặc định của ubuntu 14.04 để chứa lệnh command service.

2. Format của file tại bước (2) ở trên là như thế nào?

  • Nó chỉ là đoạn shell script bình thường, chả có gì đặc biệt.

3. Giải thích các biến tại bước (2)

  • SERVICE_NAME => tên của service, bạn thích đặt thế nào cũng được, lúc xem monitor các process của ubuntu, tên cái service này nó sẽ hiển thị.
  • PATH_TO_JAR => đường dẫn trỏ tới file .jar cần chạy
  • LOG_DIR => bây giờ chạy như 1 service rồi, thì tất nhiên cần phải có 1 chỗ để ghi log lại. (Lúc trước muốn xem log thì xem trực tiếp tại cửa sổ terminator khi chạy java)
  • PID_PATH_NAME => sử dụng cái này chỉ để đánh dấu cái pid (mã ID process cái service của minh), mục đích để khi gõ command stop, nó sẽ sử dụng cái pid đó để kill process.
service myservice stop
  • Sao giờ chạy file .jar, lại cần cái từ "nohup" ở đầu làm gì thế? => nohup chỉ là giúp lệnh java chạy của mình sẽ luôn được thực thi, ngay cả khi mình ngắt kết nối ssh tới server.

Thanks for reading


All Rights Reserved