0.查看所有java进程GC情况:for i in `jps|egrep -v "Jps|Launcher" |cut -d" " -f1`;do pwdx $i; jstat -gcutil $i ;done
1.统计每个java进程的线程数:for i in `ps aux|grep java|awk '{print $2}'` ;do echo pid:$i; jstack $i |grep java.lang.Thread.State|awk '{print $2}'|sort|uniq -c;done
2.统计TCP连接状态:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
3.统计每个IP的连接数:netstat -anp| awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr|more
4.统计每个进程的网络连接数:netstat -anp|awk '{print $7}'|awk -F/ '{print $1}'|sort|uniq -c | sort -nr|more
5.统计日志文件里接口被调用次数:grep RestChannelHandler global.log|cut -d"," -f3|cut -d"?" -f1|sort |uniq -c |sort -nr |more
grep '14/Nov/2017:09:4[0,1,2,3,4]' access.log|awk '{print $2}'|sort -nr |uniq -c
6.替换文件里指定字符串:sed -i "s/10.10.30.247/localhost/g" `grep 10.10.30.247 -rl */conf/*` 或者:find -name *.shtml|xargs perl -pi -e 's|10.10.30.247|localhost|g'
7.同步目录:rsync -av -e 'ssh -p 10007' 192.168.1.3:/root/server103 /root/
8.实时查看正在执行的sql语句: /usr/sbin/tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'
tcpdump -i em2 port 53|grep 10.59.96.211
9.删除空目录:find /data -type d -empty | xargs -exec rmdir; 删除空文件:for emp in `/usr/bin/find -size 0` ;do /bin/rm $emp;done
删除五天前的文件:find /temp -mtime +5 -type f -exec rm -rf {} \;
10.批量kill进程 : ps -efww|grep sqlr-listener|grep -v grep|cut -c 9-15|xargs kill -9
11.列出所有jvm可选参数:java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
12.同时跟踪fork和vfork出来的进程 strace -f -F -p 123
13.网络流量的分析iptraf ,dstat
14.ldd /usr/bin/mysqldump 列出使用哪些so及路径
15.测试zk: echo stat |nc localhost 2181
16.sed 删除第一个单词
sed -r 's/[a-zA-Z]+ //1' your-file
cat soa_report.txt |grep HiveClient|awk -F'size:' '{print $2}'|sed -r 's/[0-9]+//1'
删除每行开头的所有空格
sed 's/^[ ]//g' test
17.查看网络连接状态统计:ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}'
18.视频压缩
ffmpeg -i Wildlife.wmv-y -ab 32 -ar 44100 -r 15 -b 520000 -qscale 4 Wildlife_mencoder.flv
ffmpeg -i 1115.mp4 -qscale 4 1115compress.mp4
19.代码统计:find . -name "*.m" -or -name "*.h" |xargs grep -v "^$"|wc -l
代码统计:find ./ -name "*.swift"|xargs cat| wc -l
20.分组统计
如果要统计每个网址出现的次数, 实现类似于mysql group by的效果. 将wc -l 换成:
awk '{a[$1]++}END{for (j in a) print j","a[j]}'
输出格式: 分组,出现的次数
最大数/最小数/平均数统计
基于上一个例子, 如果我们提取的是一个数字, 要进行最大数/最小数/平均数的统计, 需要用到awk管道了, 将wc -l 换成:
awk '{if(min==""){min=max=$1}; if($1>max) {max=$1}; if($1< min) {min=$1}; total+=$1; count+=1} END {print total/count, min, max}'
21.慢日志查询:
cat search_test/logs/run.log_2015-09-11.log |awk '{print $4}'|awk -F: '{if($2>1000){slow+=1};count+=1} END {print count,slow}'
统计resin accesslog大于1秒的记录
zcat access_107.105.2016-07-10.log.1650.gz |awk '{if($12>1000000){slow+=1;slowtime+=$12};count+=1}END{print slow,slowtime,slowtime/slow,count}'
分钟统计:
for i in {0..5};do DT="2016:20:$i" ; zcat access_107.*|grep $DT |awk '{if($12>2000000){slow+=1;slowtime+=$12};count+=1}END{print $4,slow,slowtime,slowtime/slow,count}'; done
22.nc 端口转发
nc -l -p $localport -c “nc $remotehost $remoteport”
nc -l -p 8000 -c “nc LAN-IP 8000″
nc -l 9009 | nc -nvv 10.10.10.239 9009
23.curl显示请求头部信息,指定Header
curl -v http://10.5.121.144/top/soa/RankService -H "soa_appid:bk" -H "soa-appsign:7e7ec59d" -d '{"jsonrpc":"2.0","method":"findAllByGameCode","params":[["1000022"]],"id":100}'
curl返回响应时间:
curl -w %{time_connect}:%{time_starttransfer}:%{time_total} http://test.newgame.173.com/soa/v1/GameService -d '{"method":"search","params":[{"page":1,"pageSize":20}],"id":1,"jsonrpc":"2.0"}' -s -o /dev/null
curl --connect-timeout 2 --keepalive-time 1 --max-time 1 -w %{time_connect}:%{time_starttransfer}:%{time_total} http://test.newgame.soa.173.com/search/soa/SearchService
24.dubbo服务状态监测
echo status -l |nc -i 1 10.5.15.222 20880
25.SYN_without_MSS 肉鸡对外洪水攻击排查
dstat+nethogs
ps aux 查找可疑进程
26.循环字符串数组,分别取文件路径和文件名
#!/bin/bash
set -o nounset
#set -o errexit
DIRNAME=/usr/bin/dirname
BASENAME=/bin/basename
BASE_PATH=`$DIRNAME $0`
cd $BASE_PATH
a="/global/soalog/20170408/20/198.sea.internal.com.log /global/soalog/20170407/15/sea5.log /global/soalog/20170709/15/10.59.107.146_v2.log"
arr=($a)
for i in ${arr[@]};
do
echo $i""
FILE_NAME=`$BASENAME $i`
echo $FILE_NAME
DIR_NAME=`$DIRNAME $i`
echo $DIR_NAME
done
27.编码转换,GBK转UTF-8
for i in *.log ;do echo $i;iconv -f GBK -t UTF-8 $i -o utf8/$i; done
28play game
[ $[ $RANDOM % 6 ] == 0 ] && echo "You die" || echo "Lucky boy";
linux-AWK
常用命令:
输出第1列和第4例
- awk '{print $1, $4}' netstat.txt
格式化输出, C语言的printf没什么两样
- awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}' netstat.txt
过滤记录, 下面过滤条件为:第三列的值为0 && 第6列的值为LISTEN
-
awk '$3==0 && $6=="LISTEN" ' netstat.txt
-
awk ' $3>0 {print $0}' netstat.txt
需要表头的话,我们可以引入内建变量NR
- awk '$3==0 && $6=="LISTEN" || NR==1 ' netstat.txt
这里 NR==1 与 {print $0} 效果相同, 都是表示把表头打印出来.
- awk '$3==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt
内建变量
-
$0: 当前记录(这个变量中存放着整个行的内容)
-
$1~$n: 当前记录的第n个字段,字段间由FS分隔
-
FS: 输入字段分隔符 默认是空格或Tab
-
NF: 当前记录中的字段个数,就是有多少列
-
NR: 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
-
FNR: 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
-
RS: 输入的记录分隔符, 默认为换行符
-
OFS: 输出字段分隔符, 默认也是空格
-
ORS: 输出的记录分隔符,默认为换行符
-
FILENAME: 当前输入文件的名字
-
awk '$3==0 && $6=="ESTABLISHED" || NR==1 {printf "%02s %s %-20s %-20s %s\n",NR, FNR, $4,$5,$6}' netstat.txt
指定分隔符
- awk 'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd
- awk -F: '{print $1,$3,$6}' /etc/passwd
如果你要指定多个分隔符,你可以这样来
- awk -F '[;:]'
以\t作为分隔符输出
- awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
字符串匹配, ~ 表示模式开始。/ /中是模式。这就是一个正则表达式的匹配。
- awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
其实awk可以像grep一样的去匹配第一行
- awk '/LISTEN/' netstat.txt
我们可以使用 “/FIN|TIME/” 来匹配 FIN 或者 TIME
- awk '$6 ~ /FIN|TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
模式取反
- awk '$6 !~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
或者
- awk '!/WAIT/' netstat.txt
折分文件, awk拆分文件很简单,使用重定向就好了。下面这个例子,是按第6例分隔文件,相当的简单(其中的NR!=1表示不处理表头)。
- awk 'NR!=1{print > $6}' netstat.txt
把指定的列输出到文件
- awk 'NR!=1{print $4,$5 > $6}' netstat.txt
if-else-if语句,可见awk其实是个脚本解释器
- awk 'NR!=1{if($6 ~ /TIME|ESTABLISHED/) print > "1.txt"; else if($6 ~ /LISTEN/) print > "2.txt"; else print > "3.txt" }' netstat.txt
统计
计算所有的C文件,CPP文件和H文件的文件大小总和
- ls -l *.cpp *.c *.h | awk '{sum+=$5} END {print sum}'
统计各个connection状态
- awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}' netstat.txt
统计每个用户的进程的占了多少内存
- ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'
END的意思是“处理完所有的行的标识”,即然说到了END就有必要介绍一下BEGIN,这两个关键字意味着执行前和执行后的意思
- BEGIN{ 这里面放的是执行前的语句 }
- END {这里面放的是处理完所有的行后要执行的语句 }
- {这里面放的是处理每一行时要执行的语句}
环境变量, 我们来看看怎么和环境变量交互:(使用-v参数和ENVIRON,使用ENVIRON的环境变量需要export)
#从file文件中找出长度大于80的行 awk 'length>80' file
#按连接数查看客户端IP netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr
#打印99乘法表 seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'
参考:https://coolshell.cn/articles/9070.html
Linux 系统磁盘满处理方法
1.使用find命令,找出占用空间较大的文件
find / -type f -size +5G —找到大于5G的文件,有work权限的情况下可以使用
find . -type f -size +10000k --linux 下查找大于10M的文件
find -type f -size +500k -and -size -1000k --查找大小为500KB到1000KB之间的文件:
2.使用du命令
du -h --max-depth=1 /home/work/elongorder/ ----max-depth=1 查看子目录的层级,当前为1层
du -h /home/work/elongorder/tomcat_8200/ | sort -n —让文件按大小排序
du -s -h ./* --看下目录下面的占用情况
du -h --max-depth=1 /home/work/ |grep G|sort -n --没有work权限下使用,找出占用磁盘空间最大的目录进入逐步查找
du -hs /home --查看/home 占用空间
Linux vmstat命令
vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令,一个是Linux/Unix都支持,二是相比top,我可以看到整个机器的CPU,内存,IO的使用情况,而不是单单看到各个进程的CPU使用率和内存使用率(使用场景不一样)。
一般vmstat工具的使用是通过两个数字参数来完成的,第一个参数是采样的时间间隔数,单位是秒,第二个参数是采样的次数,如:
root@ubuntu:~# vmstat 2 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 3498472 315836 3819540 0 0 0 1 2 0 0 0 100 0
2表示每个两秒采集一次服务器状态,1表示只采集一次。
实际上,在应用过程中,我们会在一段时间内一直监控,不想监控直接结束vmstat就行了,例如:
root@ubuntu:~# vmstat 2
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 3499840 315836 3819660 0 0 0 1 2 0 0 0 100 0
0 0 0 3499584 315836 3819660 0 0 0 0 88 158 0 0 100 0
0 0 0 3499708 315836 3819660 0 0 0 2 86 162 0 0 100 0
0 0 0 3499708 315836 3819660 0 0 0 10 81 151 0 0 100 0
1 0 0 3499732 315836 3819660 0 0 0 2 83 154 0 0 100 0
这表示vmstat每2秒采集数据,一直采集,直到我结束程序,这里采集了5次数据我就结束了程序。
好了,命令介绍完毕,现在开始实战讲解每个参数的意思。
r 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。
b 表示阻塞的进程,这个不多说,进程阻塞,大家懂的。
swpd 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。
free 空闲的物理内存的大小,我的机器内存总共8G,剩余3415M。
buff Linux/Unix系统是用来存储,目录里面有什么内容,权限等的缓存,我本机大概占用300多M
cache cache直接用来记忆我们打开的文件,给文件做缓冲,我本机大概占用300多M(这里是Linux/Unix的聪明之处,把空闲的物理内存的一部分拿来做文件和目录的缓存,是为了提高 程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用。)
si 每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。
so 每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上。
bi 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒
bo 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。
in 每秒CPU的中断次数,包括时间中断
cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
us 用户CPU时间,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。
sy 系统CPU时间,如果太高,表示系统调用时间长,例如是IO操作频繁。
id 空闲 CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。
wt 等待IO CPU时间。
1. top找到目标进程,记下pid
2. top –p pid, 并用shift+h打开线程模式
这样可以看到这个进程中,到底哪个线程占用大量cpu
记下threadid,tid
3. jstack查看该线程实时的stack情况
jstack [pid]|grep -A 10 [tid(16进制)] , 10表示打印stack的长度,可以选择打印更多的stack信息
比如,jstack 21125|grep -A 10 52f1
linux_shell_find命令
使用find查找文件
基本格式:find path expression
1.按照文件名查找
(1)find / -name httpd.conf #在根目录下查找文件httpd.conf,表示在整个硬盘查找
(2)find /etc -name httpd.conf #在/etc目录下文件httpd.conf
(3)find /etc -name ‘srm’ #使用通配符*(0或者任意多个)。表示在/etc目录下查找文件名中含有字符串‘srm’的文件
(4)find . -name ‘srm*’ #表示当前目录下查找文件名开头是字符串‘srm’的文件
2.按照文件特征查找
(1)find / -amin -10 # 查找在系统中最后10分钟访问的文件(access time)
(2)find / -atime -2 # 查找在系统中最后48小时访问的文件
(3)find / -empty # 查找在系统中为空的文件或者文件夹
(4)find / -group cat # 查找在系统中属于 group为cat的文件
(5)find / -mmin -5 # 查找在系统中最后5分钟里修改过的文件(modify time)
(6)find / -mtime -1 #查找在系统中最后24小时里修改过的文件
(7)find / -user fred #查找在系统中属于fred这个用户的文件
(8)find / -size +10000c #查找出大于10000000字节的文件(c:字节,w:双字,k:KB,M:MB,G:GB)
(9)find / -size -1000k #查找出小于1000KB的文件
3.使用混合查找方式查找文件
参数有: !,-and(-a),-or(-o)。
(1)find /tmp -size +10000c -and -mtime +2 #在/tmp目录下查找大于10000字节并在最后
(2)find / -user fred -or -user george #在/目录下查找用户是fred或者george的文件文件
(3)find /tmp ! -user panda #在/tmp目录中查找所有不属于panda用户的文件