Linux上开机自动运行-jar注册为服务

启动JAR

1
nohup java -jar xxx.jar >temp.txt 2>&1 &

设置内存占用

1
java -jar -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128M xxx.jar

说明:

  1. 堆内存:最小256M,最大512M。(对象使用的内存)

  2. 永久内存:最小64M,最大128M。(类使用的内存,PermGen)

参数详解

  • -Xms256m -Xmx512m 堆内存:最小256M,最大512M。(对象使用的内存)
  • -XX:PermSize=64M -XX:MaxPermSize=128M 永久内存:最小64M,最大128M。(类使用的内存,PermGen)

设置日志中文编码

1
nohup java -Dfile.encoding=utf-8 -jar xxx.jar >temp.txt &

查看内存占用

查看pid

1
lsof -i:8895

查看内存占用

1
jmap -heap pid

结果

Attaching to process ID 19438, please wait…
Debugger attached successfully.
Server compiler detected.
JVM version is 25.221-b11

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 2147483648 (2048.0MB)
NewSize = 89128960 (85.0MB)
MaxNewSize = 715653120 (682.5MB)
OldSize = 179306496 (171.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
capacity = 651689984 (621.5MB)
used = 405279136 (386.5043029785156MB)
free = 246410848 (234.99569702148438MB)
62.18894657739592% used
From Space:
capacity = 5242880 (5.0MB)
used = 4774176 (4.553009033203125MB)
free = 468704 (0.446990966796875MB)
91.0601806640625% used
To Space:
capacity = 14680064 (14.0MB)
used = 0 (0.0MB)
free = 14680064 (14.0MB)
0.0% used
PS Old Generation
capacity = 252182528 (240.5MB)
used = 38105624 (36.340354919433594MB)
free = 214076904 (204.1596450805664MB)
15.110334685835173% used

27080 interned Strings occupying 2811288 bytes.

查看某个进程的对象占用对象最大的命令:

1
jmap -histo pid | head -n 20

注册服务 开机自启

添加服务

新建 文件

1
vi /etc/init.d/8908.sh

内容

JDK8

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
#!/bin/sh
# chkconfig: 2345 85 15
# description:auto_run

#JAR根位置
JAR_ROOT=/data/wwwjarapi/schoolfile/

#JAR位置
JAR_PATH="$JAR_ROOT"schoolfile-0.0.1-SNAPSHOT.jar

#LOG位置
LOG_PATH="$JAR_ROOT"log.txt

# 手动加载 /etc/profile
. /etc/profile

#开始方法
start() {
cd $JAR_ROOT
nohup java -Dfile.encoding=utf-8 -jar -Xms256m -Xmx512m -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=512M $JAR_PATH >$LOG_PATH 2>&1 &
echo "$JAR_PATH start success."
}

#结束方法
stop() {
kill -9 `ps -ef|grep $JAR_PATH|grep -v grep|grep -v stop|awk '{print $2}'`
echo "$JAR_PATH stop success."
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Userage: $0 {start|stop|restart}"
exit 1
esac

注意

/etc/profile 文件通常在用户登录时由用户会话(如 bash 会话)读取并执行。

init.d 脚本是在系统启动时由 init 进程(或 systemd)执行的,它们运行在系统级别,而不是用户会话级别。

所以init.d 中的脚本读取不到 /etc/profile 文件中的环境变量。

我们可以使用. /etc/profile进行手动加载。

注意:

-XX:PermSize-XX:MaxPermSize:从 Java 8 开始,永久代(PermGen)已经被元空间(Metaspace)取代,所以如果你使用的是 Java 8 及更高版本,-XX:PermSize-XX:MaxPermSize 这两个参数就没有意义了,需要使用 -XX:MetaspaceSize-XX:MaxMetaspaceSize 来替代。

批量修改配置

1
find . -type f -name "*.sh" -exec sed -i 's/-Xms256m -Xmx512m/-Xms1g -Xmx2g/g' {} \;

JDK17

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
#!/bin/sh
# chkconfig: 2345 85 15
# description:auto_run

#JAR根位置
JAR_ROOT=/data/wwwjarapi/schoolfile/

#JAR位置
JAR_PATH="$JAR_ROOT"schoolfile-0.0.1-SNAPSHOT.jar

#LOG位置
LOG_PATH="$JAR_ROOT"log.txt

#开始方法
start() {
cd $JAR_ROOT
nohup java -Dfile.encoding=utf-8 -jar -Xms256m -Xmx512m -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=256M $JAR_PATH >$LOG_PATH 2>&1 &
echo "$JAR_PATH start success."
}

#结束方法
stop() {
kill -9 `ps -ef|grep $JAR_PATH|grep -v grep|grep -v stop|awk '{print $2}'`
echo "$JAR_PATH stop success."
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Userage: $0 {start|stop|restart}"
exit 1
esac

注意

这里添加了一个2>&1,是因为:

如果只重定向了标准输出(stdout)到logfile.txt,而没有处理标准错误输出(stderr),那么错误信息依旧会在控制台输出,而导致没有完全后台执行。

2>&1 是 Unix 和 Linux shell 脚本中用于重定向的一个表达式。

这里它用于合并两种输出流:标准错误输出 (stderr) 和标准输出 (stdout)。

具体来说:

  • 1 代表标准输出 (stdout),即命令执行后产生的正常输出。
  • 2 代表标准错误输出 (stderr),即命令执行过程中产生的错误信息。

2>&1 的作用是将标准错误输出 (stderr) 重定向到标准输出 (stdout) 所指向的位置。

这通常与另一个重定向一起使用,以便将 stdout 和 stderr 都写入同一个文件或者都显示在终端上。

添加执行权限

给sh文件和jar可执行权限

1
2
chmod +x /etc/init.d/8908.sh
chmod +x /data/wwwjarapi/schoolfile/schoolfile-0.0.1-SNAPSHOT.jar

设置开机启动

首先,添加为系统服务

1
chkconfig --add 8908.sh

开机自启动

1
chkconfig 8908.sh on

查看

1
chkconfig --list

启动

1
service 8908.sh start

停用

1
service 8908.sh stop

查看启动情况

1
lsof -i:8908

删除服务

1
chkconfig --del 8908.sh

防火墙

1
2
3
firewall-cmd --zone=public --permanent --add-port=8908/tcp
firewall-cmd --reload
firewall-cmd --zone=public --list-ports

批量执行

schoolcloudapi.sh

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
#!/bin/sh
# chkconfig: 2345 85 15
# description:auto_run

server_names=(8301 8302 8304 8305 8306 8307 8308 8309 8310)

# 手动加载 /etc/profile
. /etc/profile

status(){
for server_name in ${server_names[@]}
do
netstat -tuln | grep -q :$server_name
if [ $? -eq 0 ]; then
echo "$server_name is start"
else
echo "$server_name is stop"
fi
done
}

#开始方法
start() {
for server_name in ${server_names[@]}
do
service $server_name.sh start
done
echo "all start success."
}

#结束方法
stop() {
for server_name in ${server_names[@]}
do
service $server_name.sh stop
done
echo "all stop success."
}

case "$1" in
status)
status
;;
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Userage: $0 {start|stop|restart}"
exit 1
esac