centos 随机启动脚本编写
先说下问题背景
目前手上开发的产品是springboot微服务的,我们用jenkins来做的部署,部署脚本如下:
1.build脚本 负责从git服务器拉脚本
2.微服务脚本:
#!/bin/sh
appname=${JOB_NAME}
echo "${WORKSPACE}"
echo "Stopping $appname Application"
kill -9 $(netstat -nlp | grep :${port} | awk '{print $7}' | awk -F"/" '{ print $1 }')
rm -f /www/app/$appname-1.0.jar
cp /var/lib/jenkins/workspace/build_folder/$appname/target/$appname.jar /www/app/$appname.jar
chmod 777 /www/app/$appname.jar
\cp /var/lib/jenkins/workspace/build_folder/$appname/src/main/resources/py/* /www/app/
chmod 777 /www/app/*.py
echo "Starting $appname Application"
BUILD_ID=${JOB_NAME}-${port} nohup java -jar -Xms128m -Xmx256m /www/app/$appname.jar --server.port=${port} --spring.profiles.active=${profiles}&
echo "Running $appname Application"
微服务脚本大概就是先去kill -9 掉原有的app进程,然后删除app.jar,copy git下新的app.jar到 /www/app/ 目录下,然后chmod,最后启动jar
对于刚开始的测试项目,这个脚本好像没有什么问题,但是这个里面其实有几个隐藏的问题。
1.当服务器重启,所有服务会down掉。特别对于aws服务器,有时还会被收掉,你的服务down掉了,你都不知道。
2.如果某些服务意外down掉,服务器也不会感受到,需要额外加逻辑去处理这种异常
3.kill -9的方式并不属于进程的正常关闭。
网上搜了很多springboot的部署资料,发现都没有关于这方面的。
所以下面的方法也是自己想出来的,并不代表行业标准解决方案。
通过写 app.service 来启动所有的jar。
好处:
centos 的app.sevice可以随机启动,这点毋容置疑,而且还可以设置down掉之后重启服务,这正是我需要的,但是必须要修改jenkins部署脚本。
先说app.service如何写:
[Unit]
Description=SM EDU Simulator Service
After=sm-edu-api-registry.service
[Service]
User=jenkins
Group=jenkins
ExecStart=/usr/bin/java -jar -Xms128m -Xmx256m /www/app/simulator.jar --server.port=8083 --spring.profiles.active=dev
ExecReload=/usr/bin/ps -ef | grep simulator | grep -v grep | awk '{print $2}' | xargs kill -9 && /usr/bin/java -jar -Xms128m -Xmx256m /www/app/simulator.jar --server.port=8083 --spring.profiles.active=dev
ExecStop=/usr/bin/ps -ef | grep simulator | grep -v grep | awk '{print $2}' | xargs kill -9
Restart=always
[Install]
WantedBy=multi-user.target
After表示在某个进程之后启动
User和Group设置主要是以某个用户去启动
Type=
- 设置进程的启动类型,必须是下列值之一:simple, forking, oneshot, dbus, notify, idle 之一。
- 如果设为"simple"(设置了 ExecStart= 但未设置 BusName= 时的默认值),那么表示 ExecStart= 所设定的进程就是该服务的主进程。 如果此进程需要为其他进程提供服务,那么必须在该进程启动之前先建立好通信渠道(例如套接字),以加快后继单元的启动速度。
- "dbus"(设置了 ExecStart= 与 BusName= 时的默认值)与"simple"类似,不同之处在于该进程需要在 D-Bus 上获得一个由 BusName= 指定的名称。 systemd 将会在启动后继单元之前,首先确保该进程已经成功的获取了指定的 D-Bus 名称。设置为此类型相当于隐含的依赖于 dbus.socket 单元。
- "oneshot"(未设置 ExecStart= 时的默认值)与"simple"类似,不同之处在于该进程必须在 systemd 启动后继单元之前退出。 此种类型通常需要设置 RemainAfterExit= 选项。
- 如果设为"forking",那么表示 ExecStart= 所设定的进程将会在启动过程中使用 fork() 系统调用。这是传统UNIX守护进程的经典做法。 也就是当所有的通信渠道都已建好、启动亦已成功之后,父进程将会退出,而子进程将作为该服务的主进程继续运行。 对于此种进程,建议同时设置 PIDFile= 选项,以帮助 systemd 准确定位该服务的主进程,进而加快后继单元的启动速度。
- "notify"与"simple"类似,不同之处在于该进程将会在启动完成之后通过 sd_notify(3) 之类的接口发送一个通知消息。 systemd 将会在启动后继单元之前,首先确保该进程已经成功的发送了这个消息。 如果设置为此类型,那么 NotifyAccess= 将只能设置为"all"或者"main"(默认)。 注意,目前 Type=notify 尚不能在 PrivateNetwork=yes 的情况下正常工作。
- "idle"与"simple"类似,不同之处在于该进程将会被延迟到所有的操作都完成之后再执行。 这样可以避免控制台上的状态信息与 shell 脚本的输出混杂在一起。
ExecStart=
- 在启动该服务时需要执行的命令行(命令+参数)。有关命令行的更多细节可参见后文的"命令行"小节。 仅在设置了 Type=oneshot 的情况下,才可以设置任意个命令行(包括零个),否则必须且只能设置一个命令行。 多个命令行既可以在同一个 ExecStart= 中设置,也可以通过设置多个 ExecStart= 来达到相同的效果。 如果设为一个空字符串,那么先前设置的所有命令行都将被清空。 如果不设置任何 ExecStart= 指令,那么必须确保设置了 RemainAfterExit=yes 指令。 命令行必须以一个绝对路径表示的可执行文件开始,并且其后的那些参数将依次作为"argv[1] argv[2] ..."传递给被执行的进程。 如果在绝对路径前加上可选的"@"前缀,那么其后的那些参数将依次作为"argv[0] argv[1] argv[2] ..."传递给被执行的进程。 如果在绝对路径前加上可选的"-"前缀,那么即使该进程以失败状态(例如非零的返回值或者出现异常)退出,也会被视为成功退出。 可以同时使用"-"与"@"前缀,且顺序任意。 如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。 如果某个无"-"前缀的命令行执行失败,那么剩余的命令行将不会被执行,同时该单元将变为失败(failed)状态。 当未设置 Type=forking 时,这里设置的命令行所启动的进程将被视为该服务的主守护进程。
ExecStartPre=, ExecStartPost=
- 设置在执行 ExecStart= 之前/后执行的命令行。语法规则与 ExecStart= 完全相同。 如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。 如果某个无"-"前缀的命令行执行失败,那么剩余的命令行将不会被执行,同时该单元将变为失败(failed)状态。 仅在所有无"-"前缀的 ExecStartPre= 命令全部执行成功的前提下,才会继续执行 ExecStart= 命令。 ExecStartPost= 命令仅在服务已经被成功启动之后才会运行,判断的标准基于 Type= 选项。 具体说来,对于 Type=simple 或 Type=idle 就是主进程已经成功启动;对于 Type=oneshot 来说就是主进程已经成功退出; 对于 Type=forking 来说就是初始进程已经成功退出;对于 Type=notify 来说就是已经发送了"READY=1"; 对于 Type=dbus 来说就是已经取得了 BusName= 中设置的总线名称。 注意,不可将 ExecStartPre= 用于需要长时间执行的进程。 因为所有由 ExecStartPre= 派生的子进程都会在启动 ExecStart= 服务进程之前被杀死。
ExecReload=
- 这是一个可选的指令,用于设置当该服务被要求重新载入配置时所执行的命令行。语法规则与 ExecStart= 完全相同。 另外,还有一个特殊的环境变量 $MAINPID 可以用于表示主进程的PID,例如可以这样使用: /bin/kill -HUP $MAINPID 注意,像上例那样,通过向守护进程发送复位信号,强制其重新加载配置文件,并不是一个好习惯。 因为这是一个异步操作,所以不适用于需要按照特定顺序重新加载配置文件的服务。 我们强烈建议将 ExecReload= 设置为一个能够确保重新加载配置文件的操作同步完成的命令行。
ExecStop=
- 这是一个可选的指令,用于设置当该服务被要求停止时所执行的命令行。语法规则与 ExecStart= 完全相同。 执行完此处设置的命令行之后,该服务所有剩余的进程将会根据 KillMode= 的设置被杀死(参见 systemd.kill(5) 手册)。 如果未设置此选项,那么当此服务被停止时,该服务的所有进程都将会根据 KillMode= 的设置被立即全部杀死。 与 ExecReload= 一样,也有一个特殊的环境变量 $MAINPID 可以用于表示主进程的PID 一般来说,仅仅设置一个结束服务的命令,而不等待其完成,是不够的。 因为当此处设置的命令执行完之后,剩余的进程会被 SIGKILL 信号立即杀死,这可能会导致数据丢失。 因此,这里设置的命令必须是同步操作,而不能是异步操作。
Restart=
- 当服务进程正常退出、异常退出、被杀死、超时的时候,是否重新启动该服务。 "服务进程"是指 ExecStart=, ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost=, ExecReload= 中设置的进程。 当进程是由于 systemd 的正常操作(例如 systemctl stop|restart)而被停止时,该服务不会被重新启动。 "超时"可以是看门狗的"keep-alive ping"超时,也可以是 systemctl start|reload|stop 操作超时。
- 该选项可以取下列值之一:no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always "no"(默认值)表示不会被重启。"always"表示会被无条件的重启。 "on-success"表示仅在服务进程正常退出时重启,所谓"正常退出"是指: 退出码为"0",或者进程收到 SIGHUP, SIGINT, SIGTERM, SIGPIPE 信号并且退出码符合 SuccessExitStatus= 的设置。 "on-failure"表示仅在服务进程异常退出时重启,所谓"异常退出"是指: 退出码不为"0",或者进程被强制杀死(包括"core dump"以及收到 SIGHUP, SIGINT, SIGTERM, SIGPIPE 之外的其他信号), 或者进程由于看门狗或者 systemd 的操作超时而被杀死。 对于 on-failure, on-abnormal, on-abort, on-watchdog 的分别适用于哪种异常退出。
Unit 的状态
systemctl status
命令用于查看系统状态和单个 Unit 的状态
[root@DaMoWang ~]# systemctl status # 显示系统状态
[root@DaMoWang ~]# sysystemctl status httpd.service # 显示单个 Unit 的状态
[root@DaMoWang ~]# systemctl -H root@192.168.94.104 status httpd.service # 显示远程主机的某个 Unit 的状态
Unit 管理
对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)
[root@DaMoWang ~]# systemctl start httpd.service # 立即启动一个服务
[root@DaMoWang ~]# systemctl stop httpd.service # 立即停止一个服务
[root@DaMoWang ~]# systemctl restart httpd.service # 重启一个服务
[root@DaMoWang ~]# systemctl kill httpd.service # 杀死一个服务的所有子进程
[root@DaMoWang ~]# systemctl reload httpd.service # 重新加载一个服务的配置文件
[root@DaMoWang ~]# systemctl daemon-reload # 重载所有修改过的配置文件
[root@DaMoWang ~]# systemctl show httpd.service # 显示某个 Unit 的所有底层参数
[root@DaMoWang ~]# systemctl show -p CPUShares httpd.service # 显示某个 Unit 的指定属性的值
[root@DaMoWang ~]# systemctl set-property httpd.service CPUShares=500 # 设置某个 Unit 的指定属性
在最后遇到一个坑,发现jenkins没有权限执行systemctl
为了不破坏安全性。
最后解决方案为 在系统级别加入service,但是在部署时,不用service。jenkins还是保持之前的脚本。
centos 随机启动脚本编写的更多相关文章
- redhat nginx随机启动脚本
开机自动启动nginx 1. 扔脚本进去/etc/init.d/ 2. 授权 chmod +x nginx 3. 一旦抛出:binsh^M错误就执行编码改写 设置do ...
- rsync随机启动脚本
服务端 #!/bin/sh # chkconfig: # description: Saves and restores system entropy pool for \ #create by xi ...
- nginx的编译安装以及启动脚本编写
Nginx的编译安装和启动脚本的编写 Nginxd的功能强大,可以实现代理.负载均衡等企业常用的功能.下面介绍一下nginx的编译安装方法: 1. 下载 官方下载地址:http://nginx.org ...
- [转]CentOS开机启动脚本
转载自http://www.2cto.com/os/201306/220559.html 我的一个Centos开机自启动脚本的制作 一.切换到/etc/init.d/ 二.制作sh脚本 v ...
- nginx二进制编译-启动脚本编写
首先先把这个文件上传到root目录下,并解压 #tar zxf nginx-1.11.2.tar.gz 写脚本 # vi nginx-running.sh 内容如下 #!/bin/bash #chkc ...
- centos LNMP第一部分环境搭建 LAMP LNMP安装先后顺序 php安装 安装nginx 编写nginx启动脚本 懒汉模式 mv /usr/php/{p.conf.default,p.conf} php运行方式SAPI介绍 第二十三节课
centos LNMP第一部分环境搭建 LAMP安装先后顺序 LNMP安装先后顺序 php安装 安装nginx 编写nginx启动脚本 懒汉模式 mv /usr/local/php/{ ...
- linux shell 之尝试编写 企业级 启动脚本
企业Shell面试题10:开发企业级MySQL启动脚本 说明: MySQL启动命令为: 1 /bin/sh mysqld_safe --pid-file=$mysqld_pid_file_path 2 ...
- 自己编写服务启动脚本(一):functions文件详细分析和说明
本文目录: 1.几个显示函数2.action函数3.is_true和is_false函数4.confirm函数5.pid检测相关函数 5.1 checkpid.__pids_var_run和__pid ...
- Centos 配置开机启动脚本启动 docker 容器
Centos 配置开机启动脚本启动 docker 容器 Intro 我们的 Centos 服务器上部署了好多个 docker 容器,因故重启的时候就会导致还得手动去手动重启这些 docker 容器,为 ...
随机推荐
- Coherent Calculator
计算逻辑 输入想要的参数后点击以下按钮进行计算和调整: Formula Bigger N Smaller N Bigger M Smaller M 所以在这个策略中Ft被Fixed在输入的值,其他的三 ...
- zblog模板怎么安装?zblog主题安装教程
有很多初次使用zblog的新手还会问我“zblog模板怎么安装?”,那么本文就专门给大家介绍下zblog主题安装教程. zblog现在分为zblogasp和zblogphp两个版本,两个版本的模板主题 ...
- java-selenium 框架例子
package mavenweb2; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.o ...
- 在Mac 搭建robotframework 环境 遇到ride.py 打不开的方法(没试过,先记录在此)
折腾来一下午,遇到了好多坑 坑 1.不要用pip 下载wxpython 2.不要用mac自带的python 3.不要自己下载wxpython 步骤: 1. 安装homebrew, /usr/bin/r ...
- ubuntu18.04 install rar
sudo apt-get update #如果好久没有更新资源建议update一次 sudo apt-get install rar #安装rar sudo apt-get install unrar ...
- JavaScript this指向问题
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,this最终指向调用它的对象. 1.函数调用模式: 当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的.在此种模式下, ...
- (三)Centos之安装Xshell
Xshell就是一个远程控制Centos的软件:(用XShell比较方便,试用的都知道,界面也人性化) 详细介绍请看 百度百科 我随便百度下载了一个中文版的 给下地址 http://pan.baid ...
- 建立django项目的完整流程
简单的django登录项目 1.首先建立工程,建立工程请参照:https://www.cnblogs.com/effortsing/p/10394511.html 2.在Firstdjango工程项目 ...
- MySQL创建触发器样例
# init DROP TABLE IF EXISTS students; DROP TABLE IF EXISTS class; # 创建测试用的班级表 CREATE TABLE class ( c ...
- jQuery调用WCF
jQuery要调用WCF,首先要创建service.svc服务文件,这里边需要注意: [ServiceContract(Namespace = "")] [AspNetCompat ...