本文以jar包为例(war包是同样的操作流程)。
以springboot工程为例。
我打包用的maven。
在pom文件中可以约束最终的jar包名称:
mvn clear 再然后 mvn install 这些都没什么好说的。
通过xftp或别的方式,将jar包放入服务器某个目录:
yml文件放入jar包的同一个目录,内容是常规的springboot-yml文件内容,注意yml格式:
一会儿启动的时候会以服务器这个yml文件配置的内容为准👆👆👆
而不是项目中的yml文件👇👇👇
此文件内容为java虚拟机启动时的参数:
配置jvm内存:一般只改abc这三个地方:
a = b 并且 c = a*(2/3)
单位:g 或者 m
如果你怕这么配置有啥问题,你可以临时恶补一下java虚拟机的知识,反正我这儿好几个工具jar包这么配没啥问题。
VM_OPTIONS="-Xms512m -Xmx512m -Xss256K -Xmn384m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:-UseLargePages -XX:-UseBiasedLocking"-Xss根据你的接口或者定时任务的每次调度的数据大小,可以适当增大一些。
我这儿命名为boot.sh
先上脚本,文章后面会介绍:怎么用?脚本内容的含义?
#!/bin/bash APP_NAME=$1 YUM_FILE_PATH=$2 [ -r jvm_opt ] && source jvm_opt ##检查配置文件存在且可读,则将其souce VM_OPT=${VM_OPTIONS:-Xms1g -Xmx1g -Xss256K -Xmn600m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:-UseLargePages -XX:-UseBiasedLocking} # 提示输入参数 usage() { echo app_name=$APP_NAME vm_opt=$VM_OPT yum=$YUM_FILE_PATH echo "Usage: ./boot.sh [APP_NAME] [YML_NAME] [start|stop|restart|status]" exit 1 } # 检查程序是否在运行 is_exist(){ # 获取PID PID=$(ps -ef |grep ${APP_NAME} | grep -v $0 |grep -v grep |awk '{print $2}') # -z "${pid}"判断pid是否存在,如果不存在返回1,存在返回0 if [[ -z "${PID}" ]]; then # 如果进程不存在返回1 echo "进程不存在" return 1 else # 进程存在返回0 echo "进程存在" return 0 fi } # 启动方法 start(){ is_exist if [[ $? -eq "0" ]]; then echo "${APP_NAME} is already running, PID=${pid}" else nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 & PID=$(echo $!) echo "${APP_NAME} start success, PID=$! YUM_FILE_PATH=${YUM_FILE_PATH}" fi } # 停止方法 stop(){ is_exist if [[ $? -eq "0" ]]; then kill -9 ${PID} echo "${APP_NAME} process stop, PID=${PID}" else echo "There is not the process of ${APP_NAME}" fi } # 重启进程函数 restart(){ stop echo "${APP_NAME} 准备重启..." sleep 5 start } # 查看进程状态 status(){ is_exist if [[ $? -eq "0" ]]; then echo "${APP_NAME} is running, PID=${PID}" else echo "There is not the process of ${APP_NAME}" fi } case $3 in "start") start ;; "stop") stop ;; "restart") restart ;; "status") status ;; *) usage ;; esac exit 0
cd /opt/tools/es-tasks
chmod 777 boot.sh
777是什么意思?
linux中权限是用二进制表示的。
先看一个控制台的例子:
看看这一列,第一个位置的 - 或者 d 这种文件描述符咱们先不用看,先从第二个位置的r开始看:
一共有9个位置 rwxrwxrwx 共三组 rwx,分别对应了 三个角色(拥有者、群组、其他人) 对这个文件或文件目录的权限。
“r - -” 就是只有【读】权限,对应二进制的 100
“- w -” 就是只有【写】权限,对应二进制的 010
“- -x” 就是只有【执行】权限,对应二进制的 001
分别翻译成十进制,“r - -” 就是400,"- w -“就是020,”- - x"就是001
那么:
如果是"rw-“就是有【读、写】权限,没有【执行】权限,对应的就是420
如果是"r-x"就是有【读、执行】权限,没有【写】权限,就是401
如果是”-wx"就是有【写、执行】权限,没有【读】权限,对应的就是021(这种设计一般不存在,都能改能执行了,就不能读吗),这里只是说明权限逻辑举例需要。
所以 “rwx” 就是421,而4+2+1=7(777就是从这来的),那么 “chmod 777 file” 这个指令的含义就是:将此文件的【读、写、执行】权限赋予给【拥有者、群组、其他人】这些角色。
当然:
1、如果你只想将此文件的【读、写、执行】权限赋予给【自己】或【自己的群组】,只需要 “chmod 700 file” 或者 “chmod 770 file” 就行。
2、 如果你只想将此文件的【读、写】权限赋予给自己或自己的群组,只需要"chmod 600 file"或者"chmod 660 file"就行了。
3、如果你想让【自己和自己组】拥有【读、写、执行】权限,而【其他人】只能【读】,只需要"chmod 774 file"。
所谓 linux权限,就这么简单。至于用户和用户组,也很简单,阁下可自行查阅其他资料学习,我就不赘述了。
请跟随我回到主题(这篇文章讲啥来着?看看标题,咱们继续)
启动
./boot.sh xxx.jar application.yml start
停止
./boot.sh xxx.jar application.yml stop
重启
./boot.sh xxx.jar application.yml restart
查看是否在运行
./boot.sh xxx.jar application.yml status
#!/bin/bash
写在 .sh 脚本文件最开头第一行。
这个是必须要写的,linux系统不同的话,写法上可能会有一丢丢区别,我这里是CentOS7。
APP_NAME= YUM_FILE_PATH=
声明了两个变量,指向 $1 和 $2。
$1 对应的是咱们启动命令的:
./boot.sh xxx.jar application.yml start/stop/restart/status
其中的xxx.jar这一部分。
bash解释器是按照空格进行命令的切割,而 xxx.jar 在第【1】位置,所以是$1 (第【0】位置是 ./boot)。
$2同理。
这两句话的意思就是,声明这俩变量,并且让APP_NAME=xxx.jar,让YUM_FILE_PATH=application.yml
[ -r jvm_opt ] && source jvm_opt
检查这个jvm_opt文件,如果存在并且可读,就把它的内容加载进来。
VM_OPT=${VM_OPTIONS:-Xms1g -Xmx1g -Xss256K -Xmn600m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:-UseLargePages -XX:-UseBiasedLocking}
声明一个VM_OPT变量,让它等于后面这个${VM_OPTIONS : …},这里面的VM_OPTIONS就是从jvm_opt文件中取出来的变量。
意思是:如果取到了,就让VM_OPT=VM_OPTIONS,如果没取到,就让VM_OPT等于冒号后面的这一长串值。
usage() { echo app_name=$APP_NAME vm_opt=$VM_OPT yum=$YUM_FILE_PATH echo "Usage: ./boot.sh [APP_NAME] [YML_NAME] [start|stop|restart|status]" exit 1 }
此方法在脚本被非正常执行时触发,比如说你./boot.sh start就想执行,xxx.jar也不写
那它就提示你 “Usage: ./boot.sh [APP_NAME] [YML_NAME] [start|stop|restart|status]” 一个正常命令格式是什么。
is_exist(){ # 获取PID PID=$(ps -ef |grep ${APP_NAME} | grep -v第三个方法,用于启动jar包
|grep -v grep |awk '{print }') # -z "${pid}"判断pid是否存在,如果不存在返回1,存在返回0 if [[ -z "${PID}" ]]; then # 如果进程不存在返回1 echo "进程不存在" return 1 else # 进程存在返回0 echo "进程存在" return 0 fi }
start(){ is_exist if [[ $? -eq "0" ]]; then echo "${APP_NAME} is already running, PID=${pid}" else nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 & PID=$(echo $!) echo "${APP_NAME} start success, PID=$! YUM_FILE_PATH=${YUM_FILE_PATH}" fi }
其中,"is_exist"是调用了上面讲的第二个方法。
然后拿着 is_exist() 方法运行的结果(0或者1)来决定要不要启动。
这一段脚本总体意思也很简单,判断进程是否已经存在,如果存在就提示;不存在就静默启动,启动完了提示success。
其中:
nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 &
这一段就是在启动了。 “>” 代表输出,log代表同级目录下的日志文件log.file,如果启动后log文件不存在则会自动创建。
">log"意思是把程序的输出内容写到log这个文件中去。
顺便提一嘴奥
一个 > 号 “>”
会把之前的覆盖掉,也就是说,每次重启jar包,之前log中的内容就没了。
好处也很明显,不会造成文件膨胀,排查本次启动后问题时也会很方便。
两个 > 号 “>>”
在之前的文件内容的基础上,不断追加新的内容。
我springboot工程一般都用到日志框架,这些框架会把日志,按日期写入某个文件夹内的一个个文件中去,所以我一般脚本这个位置写 一个">“符号,也就是”>log"
继续看这段脚本:
nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 &
“2>&1” 意思是 把程序的 标准错误输出 也重定向到 标准输出。
在linux中,标准输入用0表示,标准输出用1表示,标准错误输出用2表示。
最后一个 “&” 代表静默启动,“别占用我控制台一直打印” 就这个意思。
stop(){ is_exist if [[ $? -eq "0" ]]; then kill -9 ${PID} echo "${APP_NAME} process stop, PID=${PID}" else echo "There is not the process of ${APP_NAME}" fi }
非常好理解:进程存在否?存在就杀掉进程然后提示;不存在就直接提示。
restart(){ stop echo "${APP_NAME} 准备重启..." sleep 5 start }
也很好理解:先停止,睡5秒,再启动。
status(){ is_exist if [[ $? -eq "0" ]]; then echo "${APP_NAME} is running, PID=${PID}" else echo "There is not the process of ${APP_NAME}" fi }
这个就不用说了,只是调用了一下 is_exist() 方法然后根据0或1的返回,给我们提示运行状态而已。
case in "start") start ;; "stop") stop ;; "restart") restart ;; "status") status ;; *) usage ;; esac exit 0
前面讲过,$3就是咱们启动命令:
./boot.sh xxx.jar application start/stop/restart/status
其中的 start / stop / restart / status 这个部分。
脚本根据我们输入的其中一个选项,执行不同的方法。
" *)usage ;; " 的意思是我们输入的东西不在【start / stop / restart / status】这个范围内,就会走 usage() 方法,也就是提示我们正常的格式。
“esac” 就是 “case” 反过来写,是脚本中的一种语法,类似于【 " if " 与 " fi "】。
“exit 0” 意思是运行正常退出脚本程序。
tail -100f log
我一般用这几个命令
1、实时查看100行日志
more log
2、搜索日志中内容
然后敲 “/”
再然后输入你要搜索的内容,回车。
如果输入错了,按 ctrl + backspace(退格) 往前删。
简单好用,相当于一个雏形,支持高度diy。
但是要小心,别在脚本中写自己拿不准的指令。
vi boot.sh
比如说你就想用springboot工程resources下的那个yml配置,不愿意把它提取出来,脚本改起来也很简单,只要找到 $, 把 $ 后面的数字改成你命令中对应的位置就ok。
比如:
先删掉 YUM_FILE_PATH=$2 这个变量(所有引用到这个变量的地方也给改改好奥)
把脚本最后的
case $3 in …
其中的$3
改成你 start/stop/restart/status 这个指令的位置
假如说你指令是这么写的:
./boot.sh xxx.jar start
那就把./boot.sh脚本中的所有 $3 改成 $2。
很明显嘛,你变短了,数字也就变少了。
…
话说回来,稍微有点规模的项目一般也用不着这玩意,docker、k8s集群部署会更省心。
就有时候一些工具类的小玩意用一下还是蛮不错的。
ok,完活!
上一篇:CS、BS架构详解,一文带你搞懂