言成言成啊 | Kit Chen's Blog

CentOS7服务管理器及应用自启动

发布于2022-09-02 00:56:40,更新于2024-12-12 11:33:26,标签:java devops  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

一、bash管理脚本

1.1 绘图工具

绘图需安装idea的插件plantUML-Integration

只需要上图一个就可以,别的也不需要装。

启动服务的逻辑如下

关闭服务的逻辑如下

1.2 逻辑实现

在/root路径下创建entrance文件,实现逻辑如下

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env bash
# 2>&1的含义
# 1表示标准输出
# 2表示标准错误输出
# 2>&1表示将标准错误输出重定向到标准输出

# 配置jar程序的pid保存文件
jar_pid=/root/jar_pid
# 配置jar的绝对路径
jar=/root/http-proxy-boot.jar

if [ "$1" = "start" ]; then
# 如果jar_pid文件存在
if [ -f "$jar_pid" ]; then
# 如果jar_pid文件有值
if [ -s "$jar_pid" ]; then
echo "Existing PID file found during start."
# 如果jar_pid文件可读
if [ -r "$jar_pid" ]; then
PID=`cat "$jar_pid"`
# 与直接执行命令相比, 这样可以抑制输出
ps -p $PID >/dev/null 2>&1
# 等于0
if [ $? -eq 0 ] ; then
echo "$jar appears to still be running with PID $PID. Start aborted."
echo "If the following process is not a $jar process, remove the PID file and try again:"
ps -f -p $PID
exit 1
else
echo "Removing/clearing stale PID file."
# 与直接执行命令相比, 这样可以抑制输出
rm -f "$jar_pid" >/dev/null 2>&1
if [ $? != 0 ]; then
# 可写权限
if [ -w "$jar_pid" ]; then
cat /dev/null > "$jar_pid"
else
echo "Unable to remove or clear stale PID file. Start aborted."
exit 1
fi
fi
fi
else
echo "Unable to read PID file. Start aborted."
exit 1
fi
else
rm -f "$jar_pid" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ ! -w "$jar_pid" ]; then
echo "Unable to remove or write to empty PID file. Start aborted."
exit 1
fi
fi
fi
fi
# 将命令行参数往前移一个. 比如sh test.sh 1 2, 在shift前, $1=1 $2=2, 在shift后, $1=2
shift
# eval是将字符串解析为命令执行,如 eval "ls -l"就相当于直接运行性ls -l
eval "nohup java -jar \$jar >/dev/null 2>&1 &"
# 将pid写入到jar_pid文件中
echo $! > "$jar_pid"
echo "$jar started."
elif [ "$1" = "stop" ]; then
sleep=5
# 当force为1时, 执行kill -9
force=0
shift
# 若文件存在
if [ -f "$jar_pid" ]; then
# 若jar_pid有值
if [ -s "$jar_pid" ]; then
# kill -0不影响进程执行,而是检查进程是否正在运行
kill -0 `cat "$jar_pid"` >/dev/null 2>&1
# 如果大于0表示异常
if [ $? -gt 0 ]; then
echo "PID file found but either no matching process was found or the current user does not have permission to stop the process. Stop aborted."
exit 1
fi
else
echo "PID file is empty and has been ignored."
fi
else
echo "$jar_pid was set but the specified file does not exist. Is $jar running? Stop aborted."
exit 1
fi
# 与直接kill -15相比, 这样可以抑制输出
kill -15 `cat "$jar_pid"` >/dev/null 2>&1
if [ -f "$jar_pid" ]; then
while [ $sleep -ge 0 ]; do
# kill -0不影响进程执行,而是检查进程是否正在运行
kill -0 `cat "$jar_pid"` >/dev/null 2>&1
# 如果大于0表示异常, 表示进程已被关闭
if [ $? -gt 0 ]; then
rm -f "$jar_pid" >/dev/null 2>&1
# 如果删除失败
if [ $? != 0 ]; then
if [ -w "$jar_pid" ]; then
cat /dev/null > "$jar_pid"
force=0
else
echo "The PID file could not be removed or cleared."
fi
fi
echo "$jar stopped."
break
fi
if [ $sleep -gt 0 ]; then
sleep 1
fi
if [ $sleep -eq 0 ]; then
echo "$jar did not stop in time."
if [ $force -eq 0 ]; then
echo "PID file was not removed."
fi
echo "To aid diagnostics a thread dump has been written to standard out."
# kill -3 与 kill -15 类似, 只是kill -3 会多了一步生成核心存储,用于后续调试。kill -3适用于程序无响应时
kill -3 `cat "$jar_pid"`
fi
# 自减
sleep=`expr $sleep - 1`
done
fi
KILL_SLEEP_INTERVAL=5
if [ $force -eq 1 ]; then
if [ -f "$jar_pid" ]; then
PID=`cat "$jar_pid"`
echo "Killing $jar with the PID: $PID"
kill -9 $PID
while [ $KILL_SLEEP_INTERVAL -ge 0 ]; do
kill -0 `cat "$jar_pid"` >/dev/null 2>&1
if [ $? -gt 0 ]; then
rm -f "$jar_pid" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ -w "$jar_pid" ]; then
cat /dev/null > "$jar_pid"
else
echo "The PID file could not be removed."
fi
fi
echo "The $jar process has been killed."
break
fi
if [ $KILL_SLEEP_INTERVAL -gt 0 ]; then
sleep 1
fi
KILL_SLEEP_INTERVAL=`expr $KILL_SLEEP_INTERVAL - 1 `
done
if [ $KILL_SLEEP_INTERVAL -lt 0 ]; then
echo "$jar has not been killed completely yet. The process might be waiting on some system call or might be UNINTERRUPTIBLE."
fi
fi
fi
else
echo "commands:"
echo " start Start jar"
echo " stop Stop jar"
fi

启动和关闭命令如下

1
2
sh /root/entrance start
sh /root/entrance stop

二、systemed服务管理器

2.1 基础

systemd 是现代 Linux 发行版中的服务管理器。其中的配置文件通常位于

  • /usr/lib/systemd/system :系统基础服务所在目录
  • /etc/systemd/system/ :用户配置服务,优先级高于同名配置文件的系统基础服务

配置文件格式如下

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
[Unit]
Description=My Custom Service # 服务的描述
Documentation=https://meethigher.top # 相关文档链接
Requires=dependency.service # 当前服务所依赖的服务
Wants=optional-dependency.service # 可选的依赖服务
Before=another.service # 在该服务之前启动
After=network.target # 在网络服务启动后启动
Conflicts=other.service # 与此服务冲突的服务

[Service]
Type=simple # 服务的启动类型(simple, forking, etc.)
ExecStart=/usr/bin/my-executable # 启动服务时执行的命令
ExecStartPre=/usr/bin/pre-start-script # 启动前执行的命令
ExecStartPost=/usr/bin/post-start-script # 启动后执行的命令
ExecStop=/usr/bin/my-executable stop # 停止服务时执行的命令
ExecReload=/usr/bin/my-executable reload # 重新加载服务时执行的命令
Restart=on-failure # 失败后重启的策略
RestartSec=5 # 重启前等待的秒数
User=myuser # 以哪个用户身份运行服务
Group=mygroup # 以哪个组身份运行服务
Environment=MY_ENV_VAR=value # 设置环境变量
WorkingDirectory=/var/lib/myservice # 服务的工作目录
StandardOutput=journal # 标准输出到日志系统
StandardError=journal # 标准错误输出到日志系统
TimeoutStartSec=30 # 启动超时时间
TimeoutStopSec=30 # 停止超时时间

[Install]
WantedBy=multi-user.target # 指定服务在多用户目标下的依赖
RequiredBy=other.target # 指定哪些目标依赖于该服务

Type的常见类型如下

  • simple
    • 默认类型。systemd 会立即启动指定的服务,并将其视为主进程。
    • 服务的主进程在启动后保持运行。此类型适合那些简单服务。
  • forking
    • 表示服务会在启动时派生一个子进程,并且主进程会退出。systemd 会将子进程视为服务。
    • 服务的启动过程分为两个阶段:首先启动主进程,然后主进程分叉出子进程,并退出。适合传统的守护进程(daemon)类型的服务。
  • oneshot
    • 用于一次性任务。systemd 会等待命令执行完成,并根据返回值决定服务的状态。
    • 适合那些不需要常驻内存的任务,比如初始化或配置操作。Type=oneshot 的服务会被视为已完成,即使它可能会在后台执行某些操作。
  • notify
    • 表示服务将在启动完成后向 systemd 发送通知。服务在发送通知之前将被视为未启动。
    • 适用于那些需要时间进行初始化的服务。服务在启动过程中可以使用 sd_notify 函数与 systemd 通信,表明已成功启动。
  • idle
    • 在系统空闲时启动服务,适合那些不需要立即启动的服务。
    • 该服务会在所有其他活动服务都处于空闲状态时启动。适合背景任务。
  • dbus
    • 表示服务将通过 D-Bus 进行通信。服务在成功注册到 D-Bus 后才会被视为已启动。
    • 适用于那些需要与 D-Bus 交互的服务。服务必须在启动时提供一个 D-Bus 名称。

2.2 配置Jar包开机自启

先放上一个奇技淫巧的做法,但是不太适用Jar的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat > /usr/lib/systemd/system/http-proxy-boot.service <<EOF
[Unit]
Description=http-proxy-boot
After=network.target
[Service]
Type=forking
# restart时, 先执行ExecStop, 再执行ExecStart
ExecStart=/root/entrance start
ExecStop=/root/entrance stop
PrivateTmp=true
# kill按理说,应该返回状态0,但是java比较特殊,返回的是143
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
EOF

最后放一个适用于Jar的配置。

sh test.sh表示直接执行test.sh脚本

sh -c “test.sh”表示-c后面的内容,是一个字符串命令,这个字符串命令可以是test.sh脚本的实际内容

1
2
3
4
5
6
7
8
9
10
11
12
cat >/etc/systemd/system/http-proxy-boot.service<<EOF
[Unit]
Description=http-proxy-boot
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/sh -c "java -jar http-proxy-boot.jar --spring.config.location=application.yml >/dev/null 2>&1"
WorkingDirectory=/root/tjava
[Install]
WantedBy=multi-user.target
EOF

管理命令

1
2
systemctl start|stop|restart|enable|disable|is-enabled http-proxy-boot
systemctl daemon-reload

三、参考致谢

如何在统信UOS系统中设置tomcat开机启动_统信uos系统部署tomcat-CSDN博客

tomcat/bin/catalina.sh at main · apache/tomcat

发布:2022-09-02 00:56:40
修改:2024-12-12 11:33:26
链接:https://meethigher.top/blog/2022/auto-jar/
标签:java devops 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏