72. SpringBoot应用部署 - 在linux环境将jar制作成service

# 72. SpringBoot应用部署 - 在linux环境将jar制作成service

# 概述

基本的java -jar运行方式,和这种运行方式的缺陷。

# Java -jar运行?

Linux 运行jar包基本命令:

# 当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出
java -jar XXX.jar

# &代表在后台运行。当前ssh窗口不被锁定,但是当窗口关闭时,程序中止运行。
java -jar XXX.jar &
1
2
3
4
5

nohup命令, nohup 意思是不挂断运行命令,当账户退出或终端关闭时,程序仍然运行

# 当用 nohup 命令执行作业时,缺省情况下该作业的所有输出被重定向到nohup.out的文件中。
nohup java -jar XXX.jar &  

# 输出重定向到temp.txt文件
nohup java -jar XXX.jar >temp.txt &  

# 程序在后台运行,当ssh窗口关闭,程序正常运行,且不会输出文件
nohup java -jar xx.jar >/dev/null 2>&1 & 
1
2
3
4
5
6
7
8

# 这种运行方式的缺陷

这种运行方式有何缺陷呢?

  1. 不优雅
  2. 无法向Linux服务一样简单易用,具备start,stop,restart等service操作方式。以及开机自启等。

# 在Linux环境封装service

加入我们编译出了一个tech_arch-0.0.1-RELEASE.jar,如何将它封装成service呢?

# 文件准备

[root@docker opt]# tree -a
.
└── tech_doc
    ├── bin
    │   ├── logs
    │   │   └── service.2018-10-31.log
    │   └── tech_arch-0.0.1-RELEASE.jar
    └── tech_doc
1
2
3
4
5
6
7
8

# 创建启动文件

tech_doc

[root@docker opt]# cat tech_doc/tech_doc
#!/bin/sh

#------------------------------------------------
# function: services start
# author: farerboy
# home: /opt/tech_doc/bin
# log: /var/log/tech_doc/process
#------------------------------------------------

HOME=/opt/tech_doc/bin
LOGHOME=/var/log/tech_doc/process


function serviceLoad()
{
  b=''
  i=0
  while [ $i -le  100 ]
  do
      printf "$1:[%-50s]%d%%\r" $b $i
      sleep 0.3
      i=`expr 2 + $i`
      b=#$b
  done
  echo
}

function svcStart()
{
  echo "Starting $2 ..."
  cd $1
  PID=$(ps -ef | grep "$4" | grep -v grep | awk '{print $2}')
  if [ -z "$PID" ]; then
          nohup java -jar $3  > $5 2> $6 &
    serviceLoad $SERVICE_NAME
          echo "$2 started ..."
  else
          echo "$2 is already running ..."
  fi
}

function svcStop()
{
  PID=$(ps -ef | grep "$1" | grep -v grep | awk '{print $2}')
  if [ -z "$PID" ]; then
          echo "$2 already stopped ..."
  else
    kill $PID
        echo "$2 is stoping ..."
  fi
}

function do_start()
{
  for FILE in `ls $HOME | grep jar`
  do
    FILE_NAME=$FILE
    SERVICE_JAR_PACKAGE_PATH=$HOME/$FILE
    SERVICE_NAME=${FILE_NAME%-[0-9]*}
    SERVICE_LOG_PATH="$LOGHOME/$SERVICE_NAME.log"
    SERVICE_ERR_LOG_PATH="$LOGHOME/$SERVICE_NAME.err"

    svcStart $HOME $SERVICE_NAME $SERVICE_JAR_PACKAGE_PATH $FILE_NAME $SERVICE_LOG_PATH $SERVICE_ERR_LOG_PATH
  done
}

function do_stop()
{
    for FILE in `ls $HOME | grep jar`
  do
    FILE_NAME=$FILE
    SERVICE_NAME=${FILE_NAME%-[0-9]*}
    SERVICE_PID_PATH="/tmp/$SERVICE_NAME.pid"

    svcStop $FILE_NAME $SERVICE_NAME
    sleep 1
  done
}

function do_check()
{
    for FILE in `ls $HOME | grep jar`
  do
    FILE_NAME=$FILE
    SERVICE_NAME=${FILE_NAME%-[0-9]*}
    PID=$(ps -ef | grep $FILE_NAME | grep -v grep | awk '{print $2}')
  if [ -z "$PID" ]; then
          echo "$SERVICE_NAME $PID is not running ..."
  else
        echo "$SERVICE_NAME $PID is running ..."
  fi

    sleep 1
  done
}

case "$1" in
    start)

        do_start
        echo start successful

    ;;
    stop)

        do_stop
        echo stop successful

    ;;
    restart)

        do_stop
              sleep 2
        do_start
        echo restart successful

    ;;
    status)

        do_check

    ;;
    *)
    echo "Usage: {start|stop|restart|status}" >&2
    exit 3
    ;;
esac
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

# 制作服务

在init.d下创建服务

[root@docker init.d]# tree -a
.
├── functions
├── netconsole
├── network
├── README
└── tech-doc
1
2
3
4
5
6
7

tech-doc内容如下:

[root@docker opt]# cd /etc/init.d
[root@docker init.d]# ls
functions  netconsole  network  README  tech-doc
[root@docker init.d]# tree -a
.
├── functions
├── netconsole
├── network
├── README
└── tech-doc

0 directories, 5 files
[root@docker init.d]# ^C
[root@docker init.d]# cat tech-doc
#!/bin/sh
#
# /etc/init.d/tech-doc
# chkconfig: 2345 60 20
# description: ms.
# processname: tech-doc

SCRIPT_HOME=/opt/tech_doc

case $1 in
    start)
        sh $SCRIPT_HOME/tech_doc start
    ;;
    stop)
        sh $SCRIPT_HOME/tech_doc stop
    ;;
    restart)
        sh $SCRIPT_HOME/tech_doc stop
        sh $SCRIPT_HOME/tech_doc start
    ;;
    status)
        sh $SCRIPT_HOME/tech_doc status
    ;;
    *)
    echo "Usage: {start|stop|restart|status}" >&2
    exit 3
    ;;
esac
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 赋予权限

chmod 777 /etc/init.d/tech-doc
1

# 开机自启

chkconfig --list
chkconfig tech-doc on
1
2

# 查看端口

netstat -nltp
1

# 查看防火墙

systemctl status firewalld
1

# 示例源码

https://github.com/realfarerboy/tech-farerboy-spring-demos