day28:检测磁盘io|自定义时段查看tomcat 日记|打印城市名字|代码上线|统计网站并发量...
2019獨角獸企業重金招聘Python工程師標準>>>
1、有一臺阿里云的機器,接到反映說服務器的磁盤 io 很高,登錄服務器查看,并沒有發現問題,懷疑是間歇性的,看到造成磁盤 io 高的是mysql,去 show? processlist,準備考慮些個腳本, 5s 秒檢測一次磁盤 io(即是檢測5次,然后求平均值)?,但 io 大于 70 時,則登錄mysql去查詢?show proceslist 并記錄 /tmp/mysq_processlist.log;
安裝 isstat 命令:? ?yum? ?install? -y? ? sysstat
分析:1):磁盤磁盤 io 的命令, 可以用 iostat -xd 1 5 (1分鐘一次,打印5次),? 注意看%util 這一列; 加上 -d 選項,表示只查看磁盤device,默認會顯示CPU的;
[root@localhost_002 shell100]# iostat -xd 1 6|grep sda|tail -n5|awk '{print $NF}' #過濾最后一列 8.72 0.00 0.00 0.00 0.00 [root@localhost_002 shell100]# iostat -xd 1 6|grep sda|tail -n5|awk '{print $NF}'|cut -d . -f1 0 0 0 0 0 [root@localhost_002 shell100]# iostat -xd 1 6|grep sda|tail -n5|awk '{print $NF}'|cut -d . -f1|xargs|sed 's/ /+/g'|bc 0注釋:iostat -x 1 6 第一次的值不準(忽略),用 tail -n5 過濾取后面的 5次,最后一列%util,使用 awk '{print $NF}'來取出來,默認保留兩位小數,只去整數部分 cut -d .? -f1,用?xargs 把多列變成一行,然后用sed 's/ /+/g' 把空格替換成 + 號,最終用 bc 來求和;
2):那么如何查看mysql 的內容:? ? ? ? mysql? -uroot? -pnihao123!? ?-e? "show list? processlist"
[root@localhost_002 shell100]# mysql -uroot -pnihao123! -e "show processlist" Warning: Using a password on the command line interface can be insecure. +----+------+-----------+------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+------+---------+------+-------+------------------+ | 16 | root | localhost | NULL | Query | 0 | init | show processlist | +----+------+-----------+------+---------+------+-------+------------------+如上:會顯示 warning 警告信息,其實也沒有多大關系,看著很不爽,也可以去掉的;? ? mysql_config_editor? set? --user=root --password
[root@localhost_002 ~]# mysql_config_editor set --user=root --password Enter password: [root@localhost_002 ~]# ls -ld .mylogin.cnf -rw------- 1 root root 100 1月 21 14:48 .mylogin.cnf然后在當前目錄下會生成一個文件?mylogin.cnf,然后再次執行時則mysql 后面跟要執行的命令即可;不會出現警告信息;
[root@localhost_002 ~]# mysql -e "show full processlist" +----+------+-----------+------+---------+------+-------+-----------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+------+---------+------+-------+-----------------------+ | 17 | root | localhost | NULL | Query | 0 | init | show full processlist | +----+------+-----------+------+---------+------+-------+-----------------------+做實驗,我們可以設置成大于 util% 大于 0 則寫入 /tmp/mysql_processlist.log里;
[root@localhost_002 shell100]# cat 81.sh #!/bin/bash #這個腳本用來檢測磁盤io #日期: 2019-01-24 #作者: yuanhh if ! iostat &>/dev/null thenyum install -y sysstat fi while : do sum=`iostat -xd 1 6|grep sda|tail -n5|awk '{print $NF}'|cut -d . -f1|xargs|sed 's# #+#g'|bc`b=$[$sum/5]if [ $b -ge 0 ]thenecho "`date` util% is $b" >>/tmp/mysql_processlist.logmysql -uroot -pnihao123! -e "show full processlist" >>/tmp/mysql_processlist.logfi sleep 5 done #執行腳本: [root@localhost_002 shell100]# sh 81.sh #查看腳本下的文件: [root@localhost_002 shell100]# cat /tmp/mysql_processlist.log 2019年 01月 24日 星期四 12:29:42 CST util% is 0 Id User Host db Command Time State Info 11 root localhost NULL Query 0 init show full processlist 2019年 01月 24日 星期四 12:29:52 CST util% is 0 Id User Host db Command Time State Info 12 root localhost NULL Query 0 init show full processlist 2019年 01月 24日 星期四 12:30:02 CST util% is 0 Id User Host db Command Time State Info 13 root localhost NULL Query 0 init show full processlist注釋:如上腳本內容輸入,每行會輸入 util% 及mysql 下show processlist 的內容;
? a=`echo "scale=2;$sum/5"`|bc? ?這個命令會取平均值,并保留兩位小數;
2、寫一個截取tomcat catalina.out日志的腳本 tomcat實例t1-t4
# find /opt/TOM/ -name catalina.out /opt/TOM/t1/logs/catalina.out /opt/TOM/t3/logs/catalina.out /opt/TOM/t4/logs/catalina.out /opt/TOM/t2/logs/catalina.out?
參考答案
#!/bin/bash #這個腳本用來查看Tomcat日志 #作者:猿課-阿銘 www.apelearn.com #日期:2018-12-12LANG=en logfile="/opt/TOM/$1/logs/catalina.out"#將當天的英文月、數字日期、數字年作為變量賦值給d_mdy d_mdy=`date "+%b %d, %Y"`#判斷參數個數 if [ $# -ne 2 ] && [ $# -ne 3 ] thenecho "你提供的參數個數不對,請提供2個或者3個參數。例:sh $0 t1 08:01:00 14:00:00" exit 1 fi#判斷第一個參數是否符合要求 if ! echo $1|grep -qE '^t1$|^t2$|^t3$|^t4$' thenecho "第一個參數必須是t1、t2、t3或t4"exit 1 fi #判斷時間有效性 judge_time() {date -d "$1" +%s &>/dev/nullif [ $? -ne 0 ]thenecho "你提供的時間$1格式不正確"exit 1fi }#將24小時制時間轉換為12小時 tr_24_12() {date -d "$1" +%r }#判斷提供的時間點是否在日志中出現 judge_time_in_log() {if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfilethenecho "你提供的時間$1在日志$logfile中不曾出現,請換一個時間點"exit 1fi }#判斷第2個參數是否合法 judge_time $2#判斷起始時間點是否出現在日志里 judge_time_in_log $2#如果提供第3個參數 if [ $# -eq 3 ] then#判斷第3個參數是否合法judge_time $3#判斷起始時間是否早于結束時間t1=`date -d "$2" +%s`t2=`date -d "$3" +%s`if [ $t2 -lt $t1 ]thenecho "你提供的時間$2比$3要晚,應該把早的時間放到前面"exitfi#判斷提供的結束時間點是否出現在日志中judge_time_in_log $3 fi#取起始時間所在行行號 begin_n=`grep -n "$d_mdy $(tr_24_12 $2)" $logfile|head -1|awk -F ':' '{print $1}'`#取結束時間所在行行號,并用sed截取日志內容 if [ $# -eq 3 ] thenn=`grep -n "$d_mdy $(tr_24_12 $3)" $logfile|tail -1|awk -F ':' '{print $1}'`#結束日期所在行的下一行才是日志的內容end_n=$[$n+1]sed -n "$begin_n,$end_n"p $logfile elsesed -n "$begin_n,$"p $logfile fi?
3、讓用戶輸入多個城市的名字(可以是中文),要求不少于 5 個,然后把這些城市存到一個數組里,最后用 for 把它們打印處理;分析如下:
首先用戶交互:用到 read -p:
要判斷用戶輸入個數是否符合要求;? if 判斷
賦值數組的方式:? a=(1 2 3 4 5)? ? ? ? ? ? ? ? ? ?echo ${a[@]}? ? ? ?=====? ? ?echo? ${a[*]}
[root@localhost_002 shell100]# a=(1 2 3 4 5) [root@localhost_002 shell100]# echo ${a[@]} 1 2 3 4 5 [root@localhost_002 shell100]# echo ${a[*]} 1 2 3 4 5接下來先寫腳本:腳本內容如下:
[root@localhost_002 shell100]# cat 83.sh #!/bin/bash #這個腳本用來打印城市名字 #日期: 2019-01-24 #作者: yuanhh read -p "請輸入城市名字: " city n=`echo $city|awk '{print NF}'` if [ $n -lt 5 ] thenecho "請重新輸入城市個數;"exit fi name=($city) for i in `seq 0 $[${#name[@]-1}]` do echo ${name[$i]} done #執行腳本: [root@localhost_002 shell100]# sh 83.sh 請輸入城市名字: beijing shanghai nanjing shanxi guangdong beijing shanghai nanjing shanxi guangdong注釋:如上,用戶腳本輸入:使用 read? -p? "請輸入城市名字 :" city? 把值賦予變量 city;
根據要求判斷名字不能少于 5 個, 用awk '{print NF}'?則可以,表示打印列數,? ?awk的常用選項:? NR(行)? ? ? ? ? NF(列)
如果是 awk? '{print $NF}' 則表示打印最后一列的內容;? ? ? ? ? ? ? ? ?awk? '{print? ?NF}'? ? ? ? ? 則表示總共的列數;
如果是awk? '{print $NR}' 則表示打印第一行的內容;? ? ? ? ? ? ? ? ? awk? '{print? ?NR}'? ? ? ? ? 則表示總共的行數;??
[root@localhost_002 shell100]# cat 222.txt aaa bbb ccc ddd eee fff [root@localhost_002 shell100]# awk '{print $NF}' 222.txt ccc fff [root@localhost_002 shell100]# awk '{print NF}' 222.txt 3 3 [root@localhost_002 shell100]# awk '{print $NR}' 222.txt aaa eee [root@localhost_002 shell100]# awk '{print NR}' 222.txt 1 2然后用if 判斷輸入的列數是否小于,如果是,則告示用戶并退出此腳本;
下面需要把這個city變量存放在到數組里;因為city 這個變量是個字符串,賦值方法特殊,怎么做呢?? ? ?name=($city)? ? echo? ${name[@]}
首先需要把city變量賦予數組name,然后在使用? echo ${name[@]}? 來打印;
[root@localhost_002 shell100]# city='beijing shanghai guangdong nanjing shanxi' #賦個變量city [root@localhost_002 shell100]# echo $city #打印一下city變量 beijing shanghai guangdong nanjing shanxi [root@localhost_002 shell100]# name=($city) #把這個變量賦予數組name [root@localhost_002 shell100]# echo ${city[@]} #打印這個數組 beijing shanghai guangdong nanjing shanxi [root@localhost_002 shell100]# echo ${city[*]} #打印這個數組,方法同上一樣 beijing shanghai guangdong nanjing shanxi按照要求:下面需要用 for 循環把數組的內容打印出來;可以用for 來遍歷這個數組個數;然后分別打印每個位的內容;默認是從 0 開始的;
查看數組個數:? echo? ${#name[@]}?
查看數組位數:? echo ${name[0]}? ?echo ${name[1]}? ? 0 表第一位,以此類推,所以原來第五位 是第四位;
[root@localhost_002 shell100]# echo ${#name[@]} #打印數組位數; 5 [root@localhost_002 shell100]# echo ${name[0]} #打印數組的第一位; beijing [root@localhost_002 shell100]# echo ${name[1]} shanghai [root@localhost_002 shell100]# echo ${name[4]} #打印數組的第五位; shanxi [root@localhost_002 shell100]# echo ${name[5]} #所以只有五位了;然后用for 來循環位數依次打印每一位;? ? for? ?i? in? `seq 0? $[${#name}-1]`;do? ?echo ${name[$i]};done
4、有一個業務,有3臺服務器(A B C)做了負載均衡,由于規模臺下目前未使用自動化運維工具,有新的需求時,開發同事會把變更代碼上傳到其中一臺服務器A上,但是其他2臺服務器也需要做相同變更;需要寫一個腳本,把A上的代碼同步到B和C上;要考慮到不需要同步的目錄(upload? logs? info.php)
分析:同步的需求的話,可以rsync服務或者使用 expect 分發腳本的命令;不過不需要使用交互,則沒必要用expect 腳本;
而 rsync 遠程同步有兩種方式:
1):一種是通過ssh同步,需要做秘鑰驗證,這樣登錄時才不需要輸入密碼;方便但是不安全;
2):另一個是通 rsync 服務同步;需要在 B 和 C 上配置rsync 服務端服務,讓那些來連接,通過推的方式來做;雖然繁瑣,但是安全;
本次通過第一種方式來,首先需要配置秘鑰驗證,讓 A 分別擁有 B 和 C 的公鑰,并且免密碼登錄;
然后定義好要同步的網站目錄:? dir=/data/wwwroot/111.com
[root@localhost_002 111.com]# pwd /data/wwwroot/111.com [root@localhost_002 111.com]# ls 123.php admin.php image index.php info.php logs upload? ? ? ? ? ?
定義 B 和 C 的 IP 地址:? ? ? B_IP=192.168.149.131? ? ? ? ? ? ? ? ? ? ? ? ? ? C_IP=192.168.149.133
然后 rsync 命令來寫成一個 rs(){? ? ? ? ?}? 的函數;? 注意用? --exclude="logs"? ?--exclude="tmp"? --exclude="upload"? ?--exelude="caches"來過濾;
然后寫一個 read? -p 交互的方式,由用戶判斷是否選擇同步;? read? -p " please input? ?y/n:??" c
那么用戶如何判斷呢,通過 case? $c in? 判斷是? yes? 或者? no? 或者? exit? 則運行對應的命令;
腳本命令如下:
在rs(){ }里面#上函數中$1表示函數的第一個參數,即下面的IP地址;
? 在shell中# \ 這個斜杠表示換行符;用在shell命令下,相當于把換行脫義了,就不是換行了,比如有時候覺得一條命令很長,為了規范美觀,則可以把一條命令放在多行來執行,就可以用 \ 這個符號來分割;
如下命令:它的結果還是會打印? ls? /tmp/下的內容; 等于把一條命令多行來寫;
[root@localhost_002 shell100]# cat 111.sh #!/bin/bash ls \ /tmp/ [root@localhost_002 shell100]# sh 111.sh #127.0.0.1.diff curl.err換行符: 還有 \n, 只有? echo -e 是才用到 -n;?
[root@localhost_002 shell100]# echo -e "123\n456" 123 456 # \ 的用法: [root@localhost_002 shell100]# echo "12 \ > 34" 12 34腳本如下:
[root@localhost_002 shell100]# cat 84.1.sh #!/bin/bash #這個腳本用來rsync 代碼上線 #日期: 2019-01-24 #作者: yuanhh dir=/data/wwwroot/111.com B_IP=192.168.149.131 #C_IP=192.168.149.132 rs(){rsync -azP -e 'ssh -p 56888' \--exclude="logs" \--exclude="upload" \--exclude="info.php" $dir $1:$dir } #上函數中$1表示函數的第一個參數,即下面的IP地址; # \ 這個斜杠表示換行符; read -p "該腳本將會把本機$dir下的文件同步到$B_IP和$C_IP上,是否要繼續? y|n ": c case $c in y|n)rs $B_IP# rs $C_IP;;n|N)exit;;*)echo "請輸入y or n;";; esac #執行腳本: [root@localhost_002 shell100]# sh 84.1.sh 該腳本將會把本機/data/wwwroot/111.com下的文件同步到192.168.149.131和上,是否要繼續? y|n :y sending incremental file list 111.com/ 111.com/123.php21 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=4/6) 111.com/admin.php12 100% 11.72kB/s 0:00:00 (xfr#2, to-chk=3/6) 111.com/index.php17 100% 16.60kB/s 0:00:00 (xfr#3, to-chk=2/6) 111.com/image/ 111.com/image/kaola.jpg780,831 100% 2.59MB/s 0:00:00 (xfr#4, to-chk=0/6)此時同步完成:可以去 rs_B (192.168.149.131)這臺機器上查看 目錄是同步過來;? ?/data/wwwroot/111.com
[root@localhost_03 ~]# ls /data/wwwroot/111.com/111.com/ 123.php admin.php image index.php此時發現在 rs_B 機器上同步過來了文件;此腳本完成;?
5、需要統計網站并發量(1秒內有多少請求);用shell腳本;借助 zabbix 成圖;
假設日記路徑??/usr/local/nginx/logs/access.log
分析:大概分析一下每分鐘的日記內容,假如是1000條;我們要統計的是上一秒內的日記條數;
那么怎么統計上一秒的日記呢;一般日記格式如下:
192.168.149.135 - - [14/Dec/2018:17:30:07 +0800] "GET / HTTP/1.1" 200 640 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
可以看到日期格式 日期/月份/年份:小時:分鐘:秒,那么上一秒也就是減去 1 秒之前的日記條數;? ? ? ? date -d "-1 second"? +%Y:%H:%M:%S
[root@localhost_002 shell100]# date +%d/%b/%T 24/Jan/22:15:09 [root@localhost_002 shell100]# date -d "-1 second" +%d/%b/%T 24/Jan/22:14:38在本例中,可以用一個 變量 t 來表示;用在后面的過濾;? ? t=`date -d "-1 second" +%d/%b/%Y%T`
然后用 tail -n1000? $log|grep -c "$t"? ? ? ? ? ? ? ? ? ? ? ? ?#$log 表示日記路徑的變量;
然后 echo $n 打印即可;
[root@localhost_03 111.com]# cat 85.sh #!/bin/bash LANG=en t=`date -d "-1 second" +%d/%b/%Y:%T` log=/usr/local/nginx/logs/access.logn=`tail -n1000 $log|grep -c "$t"` echo $n #執行腳本: [root@localhost_03 111.com]# sh 85.sh 0?
轉載于:https://my.oschina.net/yuanhaohao/blog/3005701
總結
以上是生活随笔為你收集整理的day28:检测磁盘io|自定义时段查看tomcat 日记|打印城市名字|代码上线|统计网站并发量...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: swift4.2 - 一个自定义view
- 下一篇: 2018年香港私楼落成量达2.1万个 创