目录 1html
1. 前言 4java
2. 脚本类工具 4node
2.1. 双引号和单引号 4python
2.2. 取脚本完整文件路径 4linux
2.5. sed和awk使用外部变量 5github
2.6. awk给外部变量赋值 5redis
2.7. 字符串操做 6shell
4.14. screen、byobu和tmux分屏工具 11
4.18. dstat可取代vmstat/iostat/netstat/ifstat的工具 11
4.19. MultiTail相似tail的同时监控多个文档工具
12
7.1. valgrind和qcachegrind内存分析工具 19
12. process_monitor.sh进程监控重启工具 33
13.2. 批量上传文件工具:mooon_upload 35
本文是个大杂烩,内容为平常点滴的日积月累,持续更新当中,可关注博客(https://blog.csdn.net/Aquester或http://aquester.blog.chinaunix.net),查看最新版本。文中的内容,可帮忙开发提高分析和定位各种问题,好比找出致使IO负载高的进程等,以及一些简单的运维工做等。
单引号内的内容不会被展开,双引号内的内容会被展开。实践以下:
~> A=123 ~> B1="$A" ~> B2='$A' ~> echo $A 123 ~> echo $B1 123 ~> echo $B2 $A |
---|
但若是单引号外有双引号,则规则同双引号,如:
~> B3="'$A'" ~> echo $B3 '123' |
---|
返回是带全路径的文件路径,包括完整的文件名,即便以相对目录执行脚本,返回的目录部分也是完整的目录:
FILEPATH="$(readlink -f $0)" |
---|
取脚本所在目录路径:
BASEDIR="$(dirname $(readlink -f $0))" |
---|
在终端分别执行:
“MOOON_LOG_LEVEL=debug”和“export MOOON_LOG_LEVEL=debug” |
---|
上述二者有何不一样了?区别在于前者只对当前进程有效,而后者(环境变量)能够被子进程继承,也就是对子进程也有做用。
如需直接修改文件方式替换,只需sed后带参数“-i”。
sed 's/原字符串/替换字符串/' |
---|
sed "s/原字符串包含'/替换字符串包含'/" |
---|
sed 's?原字符串?替换字符串?' |
---|
不一样替换间使用分号分开。
x=MM sed 's/AB/'$x'/g' filename 或 sed 's/AB/'"$x"'/g' filename sed 's/'"$val"'//' filename awk '{ print "'$x'" }' filename |
---|
假设将值存在文件t中,文件t内容以下,只有一行:
a b c |
---|
须要将a、b和c分别赋给外部变量x、y和z,则脚本可写成以下:
eval $(awk '{ printf("x=%s\ny=%s\nz=%s",$1,$2,$3); }' ./t) echo $x echo $y echo $z |
---|
请注意printf函数中的换行符\n是必须的,起关键做用的是eval命令,它在不少场景有特别的用处。
~> str="abcdef" ~> strlen=${#str} ~> echo $strlen 6 |
---|
顺序遍历字符串的每个字符(“${str:$i:1}”中的数字1表示取几个字符):
~> str="abcdef" ~> strlen=${#str} ~> echo $strlen 6 ~> for ((i=0; i<$strlen; ++i)) do echo ${str:$i:1}; done a b c d e f |
---|
使用expr,判断expr的返回值,返回值为0表示是数字:
str1="123abc" str2="123000" $(expr $str1 + 0 > /dev/null 2>&1) echo $? $(expr $str2 + 0 > /dev/null 2>&1) echo $? |
---|
Linux系统自带的日志滚动工具logrotate由两部分组成:一是命令行工具logrotate,二是后台服务rsyslogd。
使用rsyslogd,只需简单的配置便可实现日志滚动。rsyslogd的配置文件为/etc/logrotate.conf,但通常不建议直接修改logrotate.conf,而是在目录/etc/logrotate.d下新增文件的方式。
logrotate.conf会include全部logrotate.d目录下的文件,语法是一致的,区别是logrotate.conf定义了默认的配置,而logrotate.d目录下为专有配置。
下列为redis的配置示例:
# cat /etc/logrotate.d/redis /usr/local/redis/log/redis-6379.log /usr/local/redis/log/redis-6380.log /usr/local/redis/log/redis-6381.log { rotate 2 minsize 100M nocompress missingok create 0664 redis redis notifempty } |
---|
经常使用配置项说明:
rotate | 指定日志文件备份数,若是值为0表示不备份 |
---|---|
minsize | 表示日志文件达到多大才滚动 |
nocompress | 表示是否压缩备份的日志文件 |
missingok | 若是日志丢失,不报错继续滚动下一个日志 |
notifempty | 日志文件为空时,不进行轮转,默认值为ifempty |
create | 指定建立新日志文件的属性,logrotate是以root运行的,若是目标日志文件非root运行,则这个必定要指定好 |
lspci | grep -i ethernet |
---|
lspci -vvv lspci -vvv -t |
---|
使用示例:
不一样发行版的Linux,重启服务可能有些区别,这里以CentOS为例重启crontab服务:
service crond restart |
---|
systemctl restart crond |
---|
其中service为老的重启服务方式,而systemctl是新的重启服务方式。service是一个脚本,而systemctl是一个可执行程序。
全称“System Activity
Reporter”,即系统活动状况报告,最为全面的系统性能分析工具之一,也可用来查看网络流量。
$ vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 1397364 3553340 775800 22420964 0 0 0 41 0 0 6 10 84 0 0 |
---|
$ iostat Linux 3.10.1-1-XXX-0041 (UN) 2018年12月12日 _x86_64_ (4 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 6.13 0.01 10.00 0.02 0.00 83.84 Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn sdb 0.11 0.11 3.66 3818251 131342429 sda 6.06 1.54 158.24 55370852 5672335360 dm-0 0.00 0.03 0.02 1126394 833860 dm-5 0.00 0.00 0.00 45657 5116 dm-6 0.00 0.00 0.00 45657 5116 dm-1 0.00 0.00 0.00 45658 5110 dm-2 0.00 0.00 0.00 45658 5116 dm-3 0.00 0.00 0.00 46478 5216 dm-4 0.00 0.00 0.00 43486 3369 dm-7 0.00 0.00 0.00 43269 3361 |
---|
参数“-m”指定刷新频率,单位为秒。
查看tps(每秒I/O次数):iostat -d -m
2(单位:MB,刷新间隔2秒),iostat -d -k 2(单位:KB)
查看扩展数据:iostat -x -m 2(刷新间隔2秒)
查看设备使用率和响应时间:iostat -d -x -k 2
3(刷新间隔2秒,一共循环3次)
iostat输出指标说明:
指标 | 说明 |
---|---|
%util | 每秒用于I/O操做的时间百分比,100%表示饱和,80%表示有20%的磁盘空间时间,标示了磁盘繁忙程度。 |
tps | 每秒I/O次数 |
await | 平均每次设备I/O操做的等待时间(单位:毫秒) |
svctm | 平均每次设备I/O操做的服务时间(单位:毫秒),值大小和磁盘性能有关。若是值和await接近,表示几乎无I/O等待。若是await远大于svctm,表示I/O队列等待过长。 |
avgrq-sz | 平均每次设备I/O操做的数据大小(扇区) |
avgqu-sz | 平均I/O队列长度,值越小越好 |
wMB/s | 每秒写入的M字节数 |
rMB/s | 每秒读取的M字节数 |
r/s | 每秒完成的读I/O设备次数 |
w/s | 每秒完成的写I/O设备次数 |
rsec/s | 每秒读扇区数 |
wsec/s | 每秒写扇区数 |
rrqm/s | 每秒合并的读I/O,VFS将请求发给FS时,FS会对读取相同块(Block)的请求进行合并。 |
wrqm/s | 每秒合并的写I/O |
htop为top的增强版本。
mpstat -P ALL 1 mpstat -I SUM 1 |
---|
示例(每秒显示一次):
mpstat -P ALL 1 |
---|
cat /proc/interrupts |
---|
grep eth1 /proc/interrupts |awk '{print $NF}' |
---|
cat /proc/irq/74/smp_affinity # 以中断74为例 |
---|
全称“List Open
Files”,可用来查看进程打开了哪些文件,也可用来查看一个文件被哪些进程打开了,或者一个端口是哪一个进程打开的等。
lsof -i:port,如:lsof -i:80 |
---|
lsof abc.txt |
---|
lsof -c abc |
---|
lsof +d /usr/local/ |
---|
lsof -d 4 |
---|
lsof -u username |
---|
lsof -p 12 |
---|
lsof -i:10888 -r 2 |
---|
ls +r 死循环执行,直到没有结果,如已没有程序占用端口号10888。
和lsof有些相似的功能,可查看文件、文件系统或套接字被哪些进程打开了。
用来模拟screen的detach的功能的小工具:http://dtach.sourceforge.net/。
$ dstat You did not select any stats, using -cdngy by default. ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 4 6 89 0 0 0| 746B 118k| 0 0 | 0 18B| 850 5461 8 9 82 0 0 0| 0 92k| 111k 71k| 0 0 |6888 15k 17 39 44 0 0 0| 0 96k| 107k 62k| 0 0 |7392 19k 2 3 94 0 0 0| 0 484k| 124k 171k| 0 0 |6855 13k |
---|
# dstat -l -m -r -c --top-io --top-mem --top-cpu ---load-avg--- ------memory-usage----- --io/total- ----total-cpu-usage---- ----most-expensive---- --most-expensive- -most-expensive- 1m 5m 15m | used buff cach free| read writ|usr sys idl wai hiq siq| i/o process | memory process | cpu process 0.14 0.14 0.14|2710M 407M 6067M 117G|0.01 3.34 | 0 0 100 0 0 0|process_mon 960k 639B|redis-server 412M|report_proxy 0.0 0.13 0.14 0.14|2710M 407M 6067M 117G| 0 0 | 0 0 100 0 0 0|redis-serve 13k 9360B|redis-server 412M|report_proxy 0.1 0.13 0.14 0.14|2710M 407M 6067M 117G| 0 0 | 0 0 99 0 0 0|process_mon2027k 1986B|redis-server 412M|report_proxy 0.0 0.13 0.14 0.14|2710M 407M 6067M 117G| 0 0 | 0 0 100 0 0 0|sap1002 30k 624B|redis-server 412M|report_proxy 0.1 0.13 0.14 0.14|2710M 407M 6067M 117G| 0 9.00 | 0 0 99 0 0 0|process_mon2024k 1986B|redis-server 412M|report_proxy 0.1 0.13 0.14 0.14|2715M 407M 6067M 117G| 0 28.0 | 0 1 99 0 0 0|redis-serve 38k 4339k|redis-server 412M|report_proxy 0.1 0.68 0.25 0.18|2723M 407M 6067M 117G| 0 5.00 | 1 1 98 0 0 0|crond 13M 180k|redis-server 412M|report_proxy 0.1 |
---|
能够交互式地运行或做为一个守护进程或同时两者兼备地运行,可替代ps、top、iotop和vmstat等,能够做为一个服务来监控远程机或者整个服务器集群。可以使用yum或apt-get安装,官网:http://collectl.sourceforge.net/。
collectl #<--------CPU--------><-----------Disks-----------><-----------Network----------> #cpu sys inter ctxsw KBRead Reads KBWrit Writes netKBi pkt-in netKBo pkt-out 37 37 382 188 0 0 27144 254 45 68 3 21 25 25 366 180 20 4 31280 296 0 1 0 0 25 25 368 183 0 0 31720 275 2 20 0 1 |
---|
collectl -sjmf -oT # <-------Int--------><-----------Memory-----------><------NFS Totals------> #Time Cpu0 Cpu1 Cpu2 Cpu3 Free Buff Cach Inac Slab Map Reads Writes Meta Comm 08:36:52 1001 66 0 0 2G 201M 609M 363M 219M 106M 0 0 5 0 08:36:53 999 1657 0 0 2G 201M 1G 918M 252M 106M 0 12622 0 2 08:36:54 1001 7488 0 0 1G 201M 1G 1G 286M 106M 0 20147 0 2 |
---|
collectl -sn --verbose -oT # NETWORK SUMMARY (/sec) # KBIn PktIn SizeIn MultI CmpI ErrIn KBOut PktOut SizeO CmpO ErrOut 08:46:35 3255 41000 81 0 0 0 112015 78837 1454 0 0 08:46:36 0 9 70 0 0 0 29 25 1174 0 0 08:46:37 0 2 70 0 0 0 0 2 134 0 0 |
---|
collectl -sJ -oTm # Int Cpu0 Cpu1 Cpu2 Cpu3 Type Device(s) 08:52:32.002 225 0 4 0 0 IO-APIC-level ioc0 08:52:32.002 000 1000 0 0 0 IO-APIC-edge timer 08:52:32.002 014 0 0 18 0 IO-APIC-edge ide0 08:52:32.002 090 0 0 0 15461 IO-APIC-level eth1 |
---|
简称PT(Percona Toolkit),可用来监控MySQL、MongoDB等。
pt-pmp -p pid |
---|
pt-visual-explain |
---|
pt-index-usage |
---|
磁盘IOPS测试工具。MAN手册:https://linux.die.net/man/1/fio,源代码:http://freshmeat.sourceforge.net/projects/fio/。
fio -filename=/dev/sdb -direct=1 -iodepth 16 -thread -rw=randwrite -ioengine=libaio -bs=4k -size=2G -numjobs=1 -runtime=100 -group_reporting -name=test |
---|
fio -filename=/dev/sdb -direct=1 -iodepth 16 -thread -rw=randread -ioengine=libaio -bs=4k -size=2G -numjobs=1 -runtime=100 -group_reporting -name=test |
---|
fio -filename=/dev/sdb -direct=1 -iodepth 16 -thread -rw=write -ioengine=libaio -bs=4k -size=2G -numjobs=1 -runtime=100 -group_reporting -name=test |
---|
fio -filename=/dev/sdb -direct=1 -iodepth 16 -thread -rw=read -ioengine=libaio -bs=4k -size=2G -numjobs=1 -runtime=100 -group_reporting -name=test |
---|
主要参数说明:
参数名 | 参数说明 |
---|---|
filename | 测试文件名称(一般选择须要测试盘的data目录) |
direct | 直接操做磁盘,绕过系统Buffer |
rw | 取值: |
bs | 单次I/O操做的块大小(假如bs值为4k,rw值为write,表示每次4k顺序写文件) |
rwmixwrite | 在混合读写的模式下写占的百分比,如“--rwmixwrite=20”表示写占20% |
size | 测试的文件大小 |
numjobs | 测试线程数 |
ioengine | 使用的I/O引擎,支持如下几种: |
group_reporting | 指标显示结果,汇总每一个进程的信息 |
runtime | 测试时长(单位:秒) |
nrfiles | 进程生成的文件数 |
zero_buffers | 用0初始化系统Buffer |
lockmem | 限定多少内存用于测试,如:--lockmem=1g |
randwrite 测试随机写
randread 测试随机读
randrw 测试随机读写
write 测试顺序写
read 测试顺序读
sync(基于read、write、fseek)
psync(基于pread、pwrite)
vsync(基于readv、writev)
libaio(Linux内核异步I/O)
posixaio(基于Posix标准的异步I/O:aoi_read、aoi_write)
solarisaio(基于Solaris原生异步I/O)
windowsaio(基于Windows原生异步I/O)
mmap(基于mmap、memcpy)
下载地址:https://github.com/akopytov/sysbench/releases。
一个开源的、模块化的、跨平台的多线程性能测试工具,能够用来进行CPU、内存、磁盘I/O、线程、数据库的性能测试。目前支持的数据库有MySQL、Oracle和PostgreSQL。
示例:测试fsync是否为实时fsync:
sysbench --test=fileio --file-fsync-freq=1 --file-num=1 --file-total-size=16384 --file-test-mode=rndwr prepare sysbench --test=fileio --file-fsync-freq=1 --file-num=1 --file-total-size=16384 --file-test-mode=rndwr run |
---|
运行时,若是遇到警告“Did you forget to run the prepare
step”,则表示须要先执行“prepare”。
Python脚本测试:
#!/usr/bin/python # time python fsync.py import os, sys, mmap # Open a file fd = os.open( "testfile", os.O_RDWR|os.O_CREAT|os.O_DIRECT ) m = mmap.mmap(-1, 512) for i in range (1,1000): os.lseek(fd,os.SEEK_SET,0) m[1] = "1" os.write(fd, m) os.fsync(fd) # Close opened file os.close( fd ) |
---|
示例:列出全部分区
# sfdisk -l |
---|
示例:列出全部分区
# fdisk -l |
---|
具备互动式操做界面的磁盘分区工具,参数-P表示显示分区表的内容,附加参数“s”会依照磁区的顺序显示相关信息。
一个由GNU开发的功能强大的磁盘分区和分区大小调整工具。
parted的图形化版本。
dmesg |grep SCSI
lsscsi
dmesg |grep -i raid
查看软RAID:cat /proc/mdstat
测试磁盘缓存读性能使用示例:hdparm -t /dev/sda(或)hdparm -Tt /dev/sda。
文件/etc/fstab的内容和mount输出是一致的。
挂载一块磁盘以前,须要先建立好文件系统。
根据进程ID,查看指定进程的当前工做目录(注意不是程序文件所在目录),格式:pwdx
pid,如pwdx 1。
根据进程名,查看进程的ID,格式:pidof 进程名,如:pidof init。
nice是进程的CPU优先级查看和调整工具,ionice是进程的IO优先级查看和调整工具。
根据进程ID,查看指定进程调用栈的工具,格式:pstack pid。
objdump
nm 常常用来查看共享库是否包含了某个符号
ldd 查看依赖关系工具
strings 列出符号
strip 删除符号表工具
Readelf
“ps”为“Process
Snapshot”的缩写,使用频繁的用来查看当前进程的快照工具,数据来源于虚拟文件“/proc”,若是输出结果的用户名太长,则会用数字型的用户ID替代。
ps支持三种风格的命令行参数:
UNIX 必须以“-”打头,能够分组
BSD 不能以“-”打头,也能够分组
GNU 以两个“-”打头\
三种风格能够混合使用,但可能有冲突,三种风格有些名称相同但含义不一样。以查看系统中全部进程为例:
标准语法:ps -ef或ps -eF等
BSD语法:ps aux或ps ax
查看进程树:
标准语法:ps -ejH
BSD语法:ps axjf
查看线程:
标准语法:ps -eLf
BSD语法:ps axms
查看root运行的全部进程:ps -U root -u root u。以指定格式查看:
ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
ps -Ao pid,tt,user,fname,tmout,f,wchan
只显示进程ID为42的进程名:ps -q 42 -o comm=。只syslogd的进程ID:ps -C syslogd -o
pid=。
“ps -ef”和“ps
-Af”相同,缘由是“-e”和“-A”做用相同。若是不想显示标题头,指定“--no-heading”便可。
ps -Ao pcpu,comm,pid,user,uid,tty --sort=-pcpu | head -n 6
说明:
-A 表示显示全部进程
pcpu CPU使用率真
comm 进程名(不包含路径)
pid 进程ID
user 用户名
--sort 指定按什么排序
显示CPU使用率最低的前5个进程:
ps -Ao pcpu,comm,pid,user,uid,tty --sort=pcpu | head -n 6
注意,这里是“-pcpu”,不是“pcpu”,前者按高到低排,后者从低到高排,顺序恰好相反。“pcpu”可用“%cpu”替代,效果彻底相同。
若是按物理内存排序,用“rss”替代“pcpu”,按虚拟内存排,用“vsz”替代“pcpu”便可。
ps -Ao rss,pcpu,comm,pid,user,uid,tty --sort=-rss| head -n 6
ps -Ao rss,pcpu,comm,pid,user,uid,tty --sort=rss| head -n 6
开源的内存分析和性能分析工具。qcachegrind是一个valgrind辅助工具,可视化方式查看valgrind性能分析结果。
Linux自带的功能强大的性能分析工具,可结合火焰图。使用方式,如:perf top -p
pid。自带了生成SVG格式的图形化工具timechart。
ss是一个能够替代netstat的网络链接查看工具(socket statistics)。
示例1:查看TCP监听
netstat -lpnt |
---|
示例1:查看TCP链接
netstat -lpna |
---|
ip是一个能够替代ifconfig和route等的网络管理工具,为iproute2套件中的一员,而ifconfig是net-tools中已被废弃使用的一个命令,许多年前就已经没有维护了。
ip addr add 192.168.31.13/24 dev eth1 |
---|
ip addr show eth1 |
---|
ip addr del 192.168.31.13/24 dev eth1 |
---|
ip route show |
---|
参数“-s”指定显示多少字节的包内容。
tcpdump -i eth1 -n -vv -x -e -s 600 # 仅二进制 tcpdump -i eth1 -n -vv -X -e -s 600 # 二进制和文本 |
---|
tcpdump -i eth1 -n -vv -X -e -s 600 -w x.cap |
---|
tcpdump -i eth1 host 192.168.31.1 and port 80 |
---|
tcpdump -i eth1 dst host 192.168.31.1 and dst port 80 |
---|
tcpdump -i eth1 |
---|
tcpdump udp port 10888 |
---|
tcpdump tcp port 80 |
---|
tcpdump host A and \(B or C \) # tcpdump host 127.0.0.1 and \(127.0.0.1 or 110.240.110.18 \) |
---|
tcpdump ip A and not B |
---|
tcpdump -i eth1 src host A |
---|
tcpdump -i eth1 dst host B |
---|
tcpdump tcp port 80 and host A |
---|
tcpdump -D |
---|
tcpdump -i any |
---|
tcpdump -v |
---|
更详细可使用“tcpdump -vv”和“tcpdump -vvv”。
tcpdump -v -X |
---|
tcpdump -v -XX |
---|
tcpdump -c 100 |
---|
tcpdump -w filename.log |
---|
tcpdump -n |
---|
tcpdump -s 500 |
---|
若是要捕获全部字节则为:tcpdump -s 0。
tcpdump -n "broadcast or multicast" |
---|
tcpdump -v "icmp or arp" |
---|
tcpdump -v arp |
---|
tcpdump -n "dst host 192.168.0.1 and (dst port 80 or dst port 443)" |
---|
tcpdump -n udp dst portrange 1-1023 |
---|
tcpdump dst port 23 |
---|
tcpdump -n dst net 192.168.1.0/24 |
---|
tcpdump -n src net 192.168.1.0/24 |
---|
$ ifstat #kernel Interface RX Pkts/Rate TX Pkts/Rate RX Data/Rate TX Data/Rate RX Errs/Drop TX Errs/Drop RX Over/Rate TX Coll/Rate lo 8546 0 8546 0 11845K 0 11845K 0 0 0 0 0 0 0 0 0 eth1 93020 0 41717 0 8867K 0 5969K 0 0 0 0 0 0 0 0 0 |
---|
按对端IP查看网络流量。
按进程查看网络流量:https://github.com/raboof/nethogs/releases。
全称“Socket CAT”,为netcat的增强版。
集成了traceroute和ping。
ethtool -S eth1 |
---|
ethtool -g eth1 |
---|
sar -n DEV 1 # 流量信息 sar -n EDEV 1 # 错误信息 sar -u 2 5 # 每2秒报告CPU使用率,共显示5行(次) sar -I 14 -o int14.file 2 10 每2秒报告14号中断,共显示10行(次),结果写入文件int14.file sar -f /var/log/sa/sa16 显示内存和网络统计,结果写入文件/var/log/sa/sa16 sar -A 显示全部统计 |
---|
可以使用tcpcopy工具将线上环境的流量引入到测试环境中,以将机器10.24.110.21的5000端口流量引流到机器10.23.25.11的5000端口为例:
tcpcopy -x 4077-10.23.25.11:5000 -s 10.23.25.12 -c 192.168.100.x -n 1 |
---|
route add -net 192.168.100.0 netmask 255.255.255.0 gw 10.23.25.12 |
---|
intercept -i eth1 -F tcp and src port 5000 |
---|
由于TCP链接是有回包的,因此须要辅助机器帮助接收回包,通常是直接丢弃掉。
有关/proc的内容很庞大,系统监控须要从这里读取大量数据,这里逐步记录一些经常使用到的。
内存大小和使用信息。
CPU个数和频率等CPU信息。
进程的各类信息,其中PID为进程ID,假设进程ID为2019,则路径为“/proc/2019”。一个进程所建立和打开的文件描述符,全在/proc/PID/fd下,以Linux的init进程为例:
# ls /proc/1/fd 0 1 10 11 12 13 14 15 16 17 2 20 21 22 24 25 26 27 28 29 3 30 31 32 33 34 37 38 39 4 5 6 7 8 9 |
---|
包括进程的命令行参数等都可以这个目录下获得。
该目录下存放的是以IRQ号命名的目录,如/proc/irq/40/表示中断号为40的相关信息。
该文件存放的是CPU位掩码(十六进制),修改该文件中的值能够改变CPU和某中断的亲和性。
该文件存放的是CPU列表(十进制),注意CPU核心个数用表示编号从0开始,如cpu0和cpu1等。
网络相关的:
可用来统计网卡流量。
文件系统相关:
/proc/sys/fs/file-max
/proc/sys/fs/file-nr
/proc/sys/fs/inode-nr
网络相关:
/proc/sys/net/core/somaxconn 控制TCP监听队列大小
/proc/sys/net/ipv4/tcp_fin_timeout 控制FIN_WAIT_2状态的超时时长
/proc/sys/net/ipv4/tcp_keepalive_intvl
内存相关:
/proc/sys/vm/drop_caches
/proc/sys/vm/overcommit_memory
咱们知道变量是会被子进程继承的,能够直接使用。有些状况下可能须要继承函数,以方便透明使用,方法很是简单,使用“export
-f”,注意参数“-f”,它表示函数的意思,不带参数的export只针对变量。
function ifprop() { echo ":$1=$2" } export -f ifprop |
---|
也可使用“typeset -fx”替代“export -f”。
基本上各发行版本均在/etc目录下有个后缀为“-release”的文件,该文件即存储了发行版本的版本号信息,如:
cat /etc/SuSE-release |
---|
cat /etc/slackware-version |
---|
cat /etc/redhat-release |
---|
netstat -ie|awk /broadcast/'{print $2}' netstat -ie|awk -F '[ :]+' /cast/'{print $4}' netstat -ie|awk -F '[ :]+' /cast/'{print $3}' |
---|
echo 3 > /proc/sys/vm/drop_caches |
---|
测试请参见:http://blog.chinaunix.net/uid-20682147-id-4209165.html。
cat /proc/net/tcp |
---|
cat /proc/net/udp |
---|
cat /proc/sys/net/core/rmem_default |
---|
cat /proc/sys/net/core/rmem_max |
---|
ps -mp 20693 -o THREAD,tid,time | sort -rn |
---|
这是一个python脚本工具,使用方法如:iotop -o |
---|
使用dmesg以前,须要先开启内核的IO监控:
echo 1 >/proc/sys/vm/block_dump或sysctl vm.block_dump=1 |
---|
而后可使用以下命令查看IO最重的前10个进程:
dmesg |awk -F: '{print $1}'|sort|uniq -c|sort -rn|head -n 10 |
---|
# iostat -x 1 3 avg-cpu: %user %nice %system %iowait %steal %idle 1.06 0.00 0.99 1.09 0.00 97.85 Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util sda 0.49 17.29 1.74 6.75 23.47 200.18 11.73 100.09 26.33 0.10 12.25 5.73 4.87 |
---|
找“await”值最大的设备(Device),如上的结果即为sda。而后使用mount找到sda挂载点,再使用fuser命令查看哪些进程在访问,如:
# fuser -vm /data |
---|
iptables命令操做只对当前登陆有效,若是需重启后也有效,可将操做放到/etc/rc.d/boot.local中,如:
/sbin/iptables -F /sbin/iptables -A INPUT -i eth0 -p tcp --sport 80 -j ACCEPT /sbin/iptables -A INPUT -i eth0 -p tcp -j DROP /sbin/iptables -A INPUT -i eth0 -p udp -j DROP |
---|
iptables是一个链的方式从前日后判断,若是前面的规则成立就不会日后继续,因此要注意顺序,每行对应一条规则。
参数“-A”是Append意思,也就是追加;参数“-I”是Insert意思,也就是插入;参数“-F”是Flush意思,表示清除(即删除)掉已有规则,也就是清空。
查看已有的规则,执行命令:
iptables -L -n |
---|
带行号显示结果(DEL操做须要指定行号):
# iptables -L -n --line-number Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:443 2 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:443 3 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:443 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:443 6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:443 8 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:80 9 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 10 DROP udp -- 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination |
---|
从上能够看到,iptables有三种规则链(Chain):
INPUT 用于指定输入规则,好比外部是能够访问本机的80端口;
OUTPUT 用于指定输出规则,好比本机是否能够访问外部的80端口;
FORWARD
用于指定端口转发规则(至关于rinetd功能),好比将8080端口的数据转到到80端口。
参数“-I”和参数“-A”须要指定链(Chain)名,其中“-I”的链名后还须要指定第几条(行)规则。
可经过“-D”参数删除规则,有两种删除方式,一是匹配模式,二是指定第几条(行)。也能够经过“-R”参数修改已有规则,另外“-L”参数后也能够跟链(Chain)名,表示只列出指定链的全部规则。“-j”参数后跟的是动做,即知足规则时执行的操做,能够为ACCEPT、DROP、REJECT和REDIRECT等。
在iptables的INPUT链的第一行插入一条规则(可访问其它机器的80端口):
iptables -I INPUT 1 -p tcp --sport 80 -j ACCEPT |
---|
在iptables的INPUT链尾追加一条规则(可访问其它机器的80端口):
iptables -A INPUT -p tcp --sport 80 -j ACCEPT |
---|
若是要让其它机器能够访问本机的80端口,则为:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT |
---|
插入前:
# iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- 0.0.0.0/0 0.0.0.0/0 DROP udp -- 0.0.0.0/0 0.0.0.0/0 |
---|
插入:
# iptables -I INPUT 1 -p tcp --sport 80 -j ACCEPT |
---|
插入后:
# iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:80 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 DROP udp -- 0.0.0.0/0 0.0.0.0/0 |
---|
追加前:
# iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- 0.0.0.0/0 0.0.0.0/0 DROP udp -- 0.0.0.0/0 0.0.0.0/0 |
---|
追加:
# iptables -I INPUT 1 -p tcp --sport 80 -j ACCEPT |
---|
追加后(ACCEPT将不能生效):
# iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- 0.0.0.0/0 0.0.0.0/0 DROP udp -- 0.0.0.0/0 0.0.0.0/0 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:80 |
---|
删除INPUT的第3条(即第3行,执行“iptables -L INPUT
--line-numbers”显示行号)规则:
iptables -D INPUT 3 |
---|
配置DNS客户端的方法很是简单,须要修改两个文件:
在这个文件里增长DNS服务器的IP地址,格式为:nameserver DNS服务器IP地址
如:
nameserver 192.168.1.46 |
---|
能够有多行nameserver,如:
nameserver 192.168.1.46 nameserver 219.133.38.2 nameserver 219.133.38.3 |
---|
在这个文件中增长以下内容便可:
hosts: files dns networks: files dns |
---|
如今便可ping域名了,如:ping
www.hadoopor.com。固然在ping以前要保证该机器是能够正常链接到DNS服务器的,DNS服务器的默认端口号为53,能够经过telnet命令来测试是否可以链接到DNS服务器,如:telnet
192.168.1.46 53。
有两种方式在crontab中定义变量:
A=123 * * * * * echo $A > /tmp/a.txt |
---|
注意在定义变量时不能使用$引用其它变量,以下面的作法错误:
A=123 B=$A |
---|
此文件定义变量的格式为:
NAME=VALUE |
---|
同crontab,也不能使用$引用其它变量。操做系统在登陆时使用的第一个文件是/etc/environment文件,/etc/environment文件包含指定全部进程的基本环境的变量。
千万注意,不要有“PATH=$PATH:/usr/local/jdk/bin”这样的用法,这将致使系统没法启动。
小技巧:想保持多台机器的crontab一致,但变量值不彻底相同,这个时候能够考虑将变量配置在/etc/environment中,这样crontab就能够相同了。
如机器1:
A=123 |
---|
机器2:
A=456 |
---|
二者的crontab配置:
* * * * * echo "$A" > /x.txt |
---|
通常不建议直接修改/etc/environment,而可采起在目录/etc/profile.d下新增一个.sh文件方式替代。但若是想crontab中生效,则只能修改/etc/environment,经测试/etc/profile.d方式不起做用。
另外注意在/etc/environment设置的变量,在shell中并不生效,但对crontab有效。
在安装一些系统时,须要修改hostname,好比安装Hadoop时须要修改主机名,并且主机名不能包含下划线。
实际上,主机名分三种(命令hostnamectl或hostnamectl
status可查看三种主机名):
“pretty”主机名,UTF8格式的主机名,这个仅供阅读,长度无限制;
“static”主机名,平常所称的主机名(traditional
hostname)。最多为64个字符,仅可包含“.”、“_”、“-”、“a-z”、“A-Z”和“0-9”这些字符,而且不能以“.”打头和结尾,也不能两个“.”连续;
“transient”主机名,内核维护的动态主机名,初始化为“static”主机名,默认为localhost。也为hadoop要求的主机名,它的约束规则同“static”主机名。若是存在“static”主机名,且不是“localhost”,那么将忽略“transient”主机名。“transient”主机名可被DHCP和mDNS修改。
当三种主机名相同时,“hostnamectl
status”只会显示“static”主机名,三种主机名的设置方法:
hostnamectl --pretty set-hostname NAME hostnamectl --static set-hostname NAME hostnamectl --transient set-hostname NAME |
---|
hostnamectl修改的主机名,在系统重启以前会一直有效,而hostname只对当次有效。若是不指定参数,则一次设置三种主机名:
hostnamectl set-hostname NAME |
---|
命令hostname不但能够查看主机名,还能够用它来修改主机名,格式为:hostname
新主机名。
在修改以前9.4.149.11对应的主机名为hadoop_10202,而9.4.149.6对应的主机名为hadoop_10203。二者的主机名均带有下划线,所以须要修改。为求简单,仅将原下划线去掉:
hostname hadoop10202
hostname hadoop10203
通过上述修改后,相似于修改环境变量,只临时有效,还须要修改相应的系统配置文件,以永久有效。
不一样的Linux发行版本,对应的系统配置文件可能不一样,SuSE 10.1是/etc/HOSTNAME:
# cat /etc/HOSTNAME hadoop_10202 |
---|
将文件中的“hadoop_10202”,改为“hadoop10202”。有些Linux发行版本对应的多是/etc/hostname文件,有些如CentOS和RedHat同时有/etc/hostname和/etc/sysconfig/network两个文件,修改/etc/hostname便可。
需注意:/etc/sysconfig/network的格式和/etc/hostname、/etc/HOSTNAME不一样,为:
HOSTNAME=主机名 |
---|
修改以后,须要重启网卡,以使修改生效,执行命令:/etc/rc.d/boot.localnet
start(不一样系统命令会有差别,这是SuSE上的方法,其它一些可能为:/etc/init.d/network
restart或service network
restart等),再次使用hostname查看,会发现主机名变了。
上述方法若是不能永久有效,则可以使用hostnamectl修改来修改永久有效。若是仍是不行,则可重启系统以使永久有效。
能够经过如下多种方法查看主机名:
hostname命令(也能够用来修改主机名,但当次仅当次会话有效)
hostnamectl命令(也能够用来修改主机名,系统重启前一直有效)
cat /proc/sys/kernel/hostname
cat /etc/hostname或cat /etc/sysconfig/network(永久性的修改,须要重启)
sysctl kernel.hostname(也能够用来修改主机名,但仅重启以前有效)
批量修改/etc/hostname工具(其它可参照):
https://github.com/eyjian/libmooon/blob/master/shell/set_hostname.sh |
---|
方法 | 效果 |
---|---|
hostname | 当次登陆临时有效,新登陆或从新登陆后无效 |
hostnamectl | 系统重启以前一直有效,重启后无效 |
/etc/hostname | 只有在系统重启后才有效 |
使用process_monitor.sh监控进程,当进程挂掉后,可以在两三秒内将进程重拉起,而且支持同一程序以不一样参数启动多个实例,和不一样用户以相同参数启动多个实例。
下载:https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh。
通常建议将process_monitor.sh放在/usr/local/bin目录下,并设置好可执行权限,放在crontab中运行。
* * * * * /usr/local/bin/process_monitor.sh "/data/redis/bin/redis-server 6379" "/data/redis/bin/redis-server /data/redis/conf/redis-6379.conf" * * * * * /usr/local/bin/process_monitor.sh "/data/redis/bin/redis-server 6380" "/data/redis/bin/redis-server /data/redis/conf/redis-6380.conf" |
---|
* * * * * /usr/local/bin/process_monitor.sh "/usr/local/jdk/bin/java -Dzookeeper" "/data/zookeeper/bin/zkServer.sh start" |
---|
process_monitor.sh启动后,会在/tmp目录下建立以“/process_monitor-”打头的日志文件,假设root用户运行process_monitor.sh,则日志全路径为:/tmp/process_monitor-root.log。
远程批量工具包含:
批量命令工具mooon_ssh;
批量上传文件工具mooon_upload;
批量下载文件工具mooon_download。
可执行二进制包下载地址:
https://github.com/eyjian/libmooon/releases
源代码包下载地址:
https://github.com/eyjian/libmooon/archive/master.zip
批量工具除由三个工具组成外,还分两个版本:
C++版本
GO版本
当前C++版本比较成熟,GO版本至关简略,但C++版本依赖C++运行时库,不一样环境须要特定编译,而GO版本可不依赖C和C++运行时库,因此不需编译便可应用到普遍的Linux环境。
使用简单,直接执行命令,即会提示用法,如C++版本:
$ mooon_ssh parameter[-c]'s value not set usage: -h[]: Connect to the remote machines on the given hosts separated by comma, can be replaced by environment variable 'H', example: -h='192.168.1.10,192.168.1.11' -P[36000/10,65535]: Specifies the port to connect to on the remote machines, can be replaced by environment variable 'PORT' -u[]: Specifies the user to log in as on the remote machines, can be replaced by environment variable 'U' -p[]: The password to use when connecting to the remote machines, can be replaced by environment variable 'P' -t[60/1,65535]: The number of seconds before connection timeout -c[]: The command is executed on the remote machines, example: -c='grep ERROR /tmp/*.log' -v[1/0,2]: Verbosity, how much troubleshooting info to print |
---|
参数名 | 默认值 | 说明 |
---|---|---|
-u | 无 | 用户名参数,可用环境变量U替代 |
-p | 无 | 密码参数,可用环境变量P替代 |
-h | 无 | IP列表参数,可用环境变量H替代 |
-P | 22,可修改源码,编译为经常使用端口号 | SSH端口参数,可用环境变量PORT替代 |
-c | 无 | 在远程机器上执行的命令,建议单引号方式指定值,除非要执行的命令自己已经包含了单引号有冲突。使用双引号时,要注意转义,不然会被本地shell解释 |
-v | 1 | 工具输出的详细度 |
-thr | 1 | 线程数,当线程数大于2时,并发执行;若是值为0,表示线程数和IP数相同 |
参数名 | 默认值 | 说明 |
---|---|---|
-u | 无 | 用户名参数,可用环境变量U替代 |
-p | 无 | 密码参数,可用环境变量P替代 |
-h | 无 | IP列表参数,可用环境变量H替代 |
-P | 22,可修改源码,编译为经常使用端口号 | SSH端口参数,可用环境变量PORT替代 |
-s | 无 | 以逗号分隔的,须要上传的本地文件列表,能够带相对或绝对目录 |
-d | 无 | 文件上传到远程机器的目录,只能为单个目录 |
-thr | 1 | 线程数,当线程数大于2时,并发执行;若是值为0,表示线程数和IP数相同 |
mooon_upload -s=/etc/hosts -d=/etc |
---|
mooon_ssh -c='md5sum /etc/hosts' |
---|
mooon_ssh -c='crontab -l' |
---|
mooon_ssh -c='rm -f /tmp/crontab.empty;touch /tmp/crontab.empty' mooon_ssh -c='crontab /tmp/crontab.emtpy' |
---|
mooon_ssh -c='crontab /tmp/crontab.online' |
---|
由于awk用单引号,因此参数“-c”的值不能使用单引号,因此内容须要转义,相对其它来讲要复杂点:
mooon_ssh -c="netstat -ie | awk -F[\\ :]+ 'BEGIN{ok=0;}{if (match(\$0, \"eth1\")) ok=1; if ((1==ok) && match(\$0,\"inet\")) { ok=0; if (7==NF) printf(\"%s\\n\",\$3); else printf(\"%s\\n\",\$4);} }'" |
---|
不一样的环境,IP在“netstat
-ie”输出中的位置稍有不一样,因此awk中加了“7==NF”判断,但仍不必定适用于全部的环境。须要转义的字符包含:双引号、美圆符和斜杠。
$ export H=192.168.31.9,192.168.31.10,192.168.31.11,192.168.31.12,192.168.31.13 $ export U=kafka $ export P='123456' $ mooon_ssh -c='/usr/local/jdk/bin/jps -m' [192.168.31.15] 50928 Kafka /data/kafka/config/server.properties 125735 Jps -m [192.168.31.15] SUCCESS [192.168.31.16] 147842 Jps -m 174902 Kafka /data/kafka/config/server.properties [192.168.31.16] SUCCESS [192.168.31.17] 51409 Kafka /data/kafka/config/server.properties 178771 Jps -m [192.168.31.17] SUCCESS [192.168.31.18] 73568 Jps -m 62314 Kafka /data/kafka/config/server.properties [192.168.31.18] SUCCESS [192.168.31.19] 123908 Jps -m 182845 Kafka /data/kafka/config/server.properties [192.168.31.19] SUCCESS ================================ [192.168.31.15 SUCCESS] 0 seconds [192.168.31.16 SUCCESS] 0 seconds [192.168.31.17 SUCCESS] 0 seconds [192.168.31.18 SUCCESS] 0 seconds [192.168.31.19 SUCCESS] 0 seconds SUCCESS: 5, FAILURE: 0 |
---|
$ mooon_ssh -c='/data/kafka/bin/kafka-server-stop.sh' -u=kafka -p='123456' -h=192.168.31.15,192.168.31.16,192.168.31.17,192.168.31.18,192.168.31.19 [192.168.31.15] No kafka server to stop command return 1 [192.168.31.16] No kafka server to stop command return 1 [192.168.31.17] No kafka server to stop command return 1 [192.168.31.18] No kafka server to stop command return 1 [192.168.31.19] No kafka server to stop command return 1 ================================ [192.168.31.15 FAILURE] 0 seconds [192.168.31.16 FAILURE] 0 seconds [192.168.31.17 FAILURE] 0 seconds [192.168.31.18 FAILURE] 0 seconds [192.168.31.19 FAILURE] 0 seconds SUCCESS: 0, FAILURE: 5 |
---|