运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化

简介:
原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://dgd2010.blog.51cto.com/1539422/1674188

运维经验分享作为一个专题,目前共7篇文章

  1. 运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本

  2. 运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化

  3. 运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行Shell脚本的问题(一)

  4. 运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析

  5. 运维经验分享(五)-- 改进的java进程管理的服务控制脚本

  6. 运维经验分享(六)-- 深究crontab不能正确执行Shell脚本的问题(二)

  7. 运维经验分享(七)-- Linux Shell之ChatterServer服务控制脚本第三次优化

====================================分割线======================================

最近开发人员提出新的需求,想将ChatterServer服务控制脚本放到ChatterServer根目录下的bin目录下,并向一次性可以部署多个实例,因此这一个需求引发了多个改变:

1.不再使用service进行控制,仍然保留status、start、stop和restart功能

2.BASEDIR不再使用绝对路径而要使用相对路径,例如BASEDIR=..

3.SERVICEPORT要从ChatterServer根目录下的conf目录中的文件中读取

4.日志目录logs将不再手动创建,控制脚本需要自己创建logs目录

针对以上4点变更,改进如下

1.去掉service控制,只需要将此脚本放到ChatterServer根目录下的bin目录下执行(实际上更简单了)

2.既然要使用相对路径而不使用绝对路径就要正确设置Shell脚本的当前工作目录,否则非但脚本不好用(log和pid都无法正常生成),还会导致ChatterServer的核心命令行无法使用(无法读取到相对路径下的配置文件)

3.要想SERVICEPORT从ChatterServer根目录下的conf目录中的文件中读取,非常简单,但疑难问题在于排查上,例如grep对dos文件格式(file format)的文件非常不友好,会对脚本中后面的命令产生巨大影响(特别是echo以及变量(以$开头的字符串)几乎会乱掉),因此在使用grep前,必须将此文件的内容通过dos2unix命令来转化,除非开发人员乐意将文件格式从dos手动改为unix(可以参考《UNIX/Linux环境编程必须需要注意的问题总结》)

4.相当于多了一层异常检测而已,比较简单,看新的ChatterServer服务控制脚本就会明白。

经过二次“优化”改造的脚本如下:

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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/bin/bash
#chkconfig: 345 86 14
#description: Startup and shutdown script for ChatterServer(Port:$SERVICEPORT))
VERSION=1.0.0-snapshot
BASEDIR=..
# choose LOGDIR as standard of work directory
LOGDIR=$( pwd )/$BASEDIR /logs
if  [[ ! -d $LOGDIR ]];  then
     mkdir  $LOGDIR
fi
#SERVICEPORT=29093
#SERVICEPORT=`grep ^port $(pwd)/../conf/constant.properties | awk -F '=' '{print $2}'`
# NOTE: $(pwd)/../conf/constant.properties file fileformat must be unix NOT dos in shell scripts, or will cause some unknown error
# NOTE: grep is vrey sensitive to dos fileformat or unix fileformat
# apt-get install dos2unix
PORTFILE=$( pwd )/.. /conf/constant .properties
SERVICEPORT=$( cat  $PORTFILE | dos2unix |  grep  ^port |  awk  -F  '='  '{print $2}' )
PIDFILE=$LOGDIR /chatter .pid
SERVER=$( pwd )/$BASEDIR /chatter- $VERSION\.jar
BASENAME=chatter
ARGS= "-Xms2g -Xmx4g -Xmn4g -Xss128k -XX:MaxPermSize=64m -XX:-UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=30 -XX:SurvivorRatio=6"
# -Xms2g -Xmx2g -Xmn2g -Xss128k -XX:MaxPermSize=64m -XX:-UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=30 -XX:SurvivorRatio=6
status() {
     # The judgment priority: pid > port > piffile
     # netstat run by common user will get some error output, so we put those error outout to /dev/null
     if  [[ $( netstat  -anop 2> /dev/null  grep  $SERVICEPORT |  grep  LISTEN) || -f $PIDFILE ]]; then
         #pid=$(cat $PIDFILE)
         pid=$( ps  -ef |  grep  java |  grep  $BASENAME |  grep  - v  grep  awk  '{print $2}' )
         if  [[ $pid !=  ""  && $( ps  -ef |  grep  $pid |  grep  - v  grep ) ]];  then
             echo  "SUCCESS: ChatterServer(Port:$SERVICEPORT) is OK"
             exit  0
         else
             echo  "ERROR: ChatterServer(Port:$SERVICEPORT) pid is NOT exist"
             exit  1
         fi
     elif  [[ ! $( netstat  -anop 2> /dev/null  grep  $SERVICEPORT |  grep  LISTEN) ]];  then
             echo  "ERROR: ChatterServer(Port:$SERVICEPORT) port is NOT listen"
             exit  1
     elif  [[ ! -f $PIDFILE ]];  then
         echo  "ERROR: ChatterServer(Port:$SERVICEPORT) pid file is NOT exist"
         exit  1
     else
         echo  "ERROR:  ChatterServer(Port:$SERVICEPORT) is NOT running"
         exit  1
     fi
}
 
start() {
     if  [[ -e $PIDFILE ]];  then
         echo  "ERROR: pidfile $PIDFILE exist, ChatterServer(Port:$SERVICEPORT) has started with pid $(cat $PIDFILE)"
         # pid file can be deleted
         /bin/rm  -f $PIDFILE
         exit  1
     fi
     if  [[ -e $SERVER ]];  then
         echo  "INFO: Starting ChatterServer(Port:$SERVICEPORT)"
         # Start ChatterServer core daemon
         # Why using "date +"%Y%m%d""? Because we just need restart this once per day
         # For ChatterServer wiil find some file in $BASEDIR
         cd  $LOGDIR/../
         #nohup java -jar $SERVER $ARGS >>$LOGDIR/console-$(date +"%Y%m%d").out 2>&1 &
         java -jar $SERVER $ARGS >>$LOGDIR /console- $( date  + "%Y%m%d" ).out 2>&1 &
         #java -jar $SERVER $ARGS >$LOGDIR/console.out 2>&1 &
         RETVAL=$?
         # shell do NOT need home directory
         ## For ChatterServer wiil find some file in $BASEDIR
         cd   $LOGDIR/.. /bin
         if  [[ $RETVAL - eq  0 ]];  then
             ## $! --> Expands to the process ID of the most recently executed background (asynchronous) command.
             #echo $! > $PIDFILE
             # For java performance issue, port 29092 will listen latter, we will waiting for 2 second
             sleep  2
             # get pid var
             # TODO remove debug info
             #echo "DEBUG: "
             #ps -ef | grep $BASENAME | grep -v grep | awk '{print $2}'
             # end debug
             #pid=$(ps -ef | grep java | grep $BASENAME | grep -v grep | awk '{print $2}')
             pid=$( netstat  -anop 2> /dev/null  grep  $SERVICEPORT |  grep  LISTEN |  awk  '{print $7}'  awk  -F  '/'  '{print $1}' )
         # send pid number to pid file
             echo  $pid > $PIDFILE
             # Those lines will remove in next release
             # TODO remove debug info
             #echo "DEBUG: live 1"
             # For java performance issue, port 29092 will listen latter, so we change judgment conditions
             if  [[ $( netstat  -anop 2> /dev/null  grep  $SERVICEPORT |  grep  LISTEN) || -f $PIDFILE ]];  then
                 echo  "SUCCESS: ChatterServer(Port:$SERVICEPORT) start OK"
                 # Setting up start log 
                 echo  "[ $(date +" %D %T ") ] SUCCESS: ChatterServer(Port:$SERVICEPORT) started with pid $(cat $PIDFILE) "  >>$LOGDIR /service .log
             fi
             # TODO remove debug info
             #echo "DEBUG: live 2"
             # -Those lines will remove in next release
             #echo "SUCCESS: ChatterServer start OK"
             ## Setting up start log 
             #echo "[ $(date +"%D %T") ] SUCCESS: ChatterServer started with pid $(cat $PIDFILE) " >>$LOGDIR/service.log
         else
             echo  "ERROR: ChatterServer(Port:$SERVICEPORT) start failed"
             # Setting up start log 
             echo  "[ $(date +" %D %T ") ] ERROR: ChatterServer(Port:$SERVICEPORT) start failed "  >>$LOGDIR /service .log
             exit  $RETVAL
         fi
     else
         echo  "ERROR: Couldn't find $SERVER"
         # TODO We just think this is not essential
         # Do NOT setting up log here
         exit  1
     fi
 
}
stop() {
     if  [[ -e $PIDFILE ]];  then
         pid=$( cat  $PIDFILE)
         #if kill -TERM $PIDFILE >/dev/null 2>&1
         # TODO remove debug info
         #echo "DEBUG: $LOGDIR/console-$(date +"%Y%m%d").out"
         # Ubuntu can NOT use "usleep", so use "sleep" instead
         # usleep 100000 
         if  kill  -TERM $pid >>$LOGDIR /console- $( date  + "%Y%m%d" ).out &&  sleep  1
             then
             echo  "SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with TERM"
             # Setting up stop log 
             echo  "[ $(date +" %D %T ") ] SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with TERM "  >>$LOGDIR /service .log
             # Because we can NOT use usleep , so we must comment out sleep 1 next
             #sleep 1
             # Ubuntu can NOT use "usleep", so use "sleep" instead
             # usleep 100000 
         elif  kill  -KILL $pid > /dev/null  2>&1 &&  sleep  1
             then
             echo  "SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with KILL"
             # Setting up stop log 
             echo  "[ $(date +" %D %T ") ] SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with KILL "  >>$LOGDIR /service .log
             # Because we can NOT use usleep , so we must comment out sleep 1 next 
             #sleep 1
         else
             echo  "ERROR: ChatterServer(Port:$SERVICEPORT) stop faild"
             # Setting up stop log 
             echo  "[ $(date +" %D %T ") ] ERROR: ChatterServer(Port:$SERVICEPORT) stop failed "  >>$LOGDIR /service .log
             exit  1
         fi
         # Remove pid file
         if  [[ -f $PIDFILE ]];  then
             /bin/rm  -f $PIDFILE
         fi
     else
         echo  "ERROR: No ChatterServer(Port:$SERVICEPORT) running"
         # TODO We just think this is not essential
         # Do NOT setting up log here
         exit  1
     fi
}
 
restart() {
     echo  "INFO: Restarting ChatterServer(Port:$SERVICEPORT)"
     stop
     # Those lines will remove in next release
     if  [[ $( netstat  -anop 2> /dev/null  grep  $SERVICEPORT |  grep  LISTEN) ]];  then
         echo  "WARNNING: port $SERVICEPORT is in using, must waiting"
         sleep  5
         if  [[ $( netstat  -anop 2> /dev/null  grep  $SERVICEPORT |  grep  LISTEN) ]];  then
             echo  "WARNNING : port $SERVICEPORT is still in using, must waiting"
             sleep  2
         fi
     fi
     # -Those lines will remove in next release
     # Do NOT using sleep any seconds here with stop() function used
     start
}
 
case  $1  in
     status)
         status
         ;;
     start)
         start
         ;;
     stop)
         stop
         ;;
     restart)
         restart
         ;;
     help|*)
         echo  "Usage: $0 {status|start|stop|restart|help} with $0 itself"
         exit  1
         ;;
esac
# replace "exit 0" with ":"
#exit 0
:

--end--

====================================分割线======================================

运维经验分享作为一个专题,目前共7篇文章

  1. 运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本

  2. 运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化

  3. 运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行Shell脚本的问题(一)

  4. 运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析

  5. 运维经验分享(五)-- 改进的java进程管理的服务控制脚本

  6. 运维经验分享(六)-- 深究crontab不能正确执行Shell脚本的问题(二)

  7. 运维经验分享(七)-- Linux Shell之ChatterServer服务控制脚本第三次优化

本文出自 “通信,我的最爱” 博客,请务必保留此出处http://dgd2010.blog.51cto.com/1539422/1674188

目录
相关文章
|
2月前
|
人工智能 运维 自然语言处理
别再靠“救火”过日子了:智能运维,正在重塑IT服务的未来
别再靠“救火”过日子了:智能运维,正在重塑IT服务的未来
307 15
|
2月前
|
存储 人工智能 运维
别再靠脚本“救火”了!让智能数据治理接管你的运维世界
别再靠脚本“救火”了!让智能数据治理接管你的运维世界
236 14
|
2月前
|
Linux 网络安全 Docker
盘古栈云,创建带ssh服务的linux容器
创建带ssh服务的linux容器
306 146
|
5月前
|
机器学习/深度学习 消息中间件 人工智能
别只会写脚本了!看看机器学习是怎么帮运维“摸鱼”的
别只会写脚本了!看看机器学习是怎么帮运维“摸鱼”的
148 13
|
3月前
|
缓存 安全 Linux
六、Linux核心服务与包管理
在没有网络的情况下,使用系统安装光盘是获取RPM包的常用方法。场景二:配置本地文件镜像源 (使用系统安装光盘/ISO)(检查RPM包的GPG签名以保证安全) 或。YUM/DNF包管理工具 (yum/dnf)(此处可以放置您为本主题制作的思维导图)处理依赖问题的危险选项 (应极力避免)(覆盖文件、替换已安装包)。(list) 则是列出文件。(query file) 是。(假设系统安装光盘已挂载到。信息 (verbose)。(upgrade) 选项。(all) 已安装的包。(package) 选项
395 11
|
3月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
471 9
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
425 0
Linux系统初始化脚本
|
3月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
400 2
|
2月前
|
存储 运维 监控
57_大模型监控与运维:构建稳定可靠的服务体系
随着大语言模型(LLM)技术的快速发展和广泛应用,如何确保模型在生产环境中的稳定运行、高效服务和安全合规已成为企业和开发者面临的关键挑战。2025年,大模型服务已从实验室走向各行各业的核心业务流程,其运维复杂度也随之呈指数级增长。与传统软件系统不同,大模型服务具有参数规模庞大、计算密集、行为不确定性高等特点,这使得传统的运维监控体系难以满足需求。
|
5月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
723 1

热门文章

最新文章