linux_work_cmd - leeqx/leeqx.github.io GitHub Wiki
- 性能排查指令
uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
- perf
- perf stat -B -r 10 -p 4623
- perf record -e cycles -a -p 4623 -g
perf report -g - perf top -p 4623 -K
- c\c++文件提示 文件开始处包含了不明中文字符,如果确认没有明文显示的中文类字符,那么可以用vi打开,然后:set nobomb ,保存即可 通常这种情况是因为存储是采用了有bomb的utf8
- pmap 内存泄漏调试
gdb pmap 内存泄漏检测 - Epoll事件事件检测
网络断开常用检测方法 1、处理正常网络断开 (1) select 捕捉可读事件,read返回0 (2) epoll 捕捉可读事件,read返回0 (3) 主动 read 返回错误 (4) 主动 write 返回错误
2、处理异常网络断开
(1) 应用层KeepAlive检测
在应用层协议加入心跳握手机制,维护服务端跟客户端之间的连通状态,是最普遍最保险的办法。 客户端定时向服务端发送探测包,若服务端回应则说明服务端在线,否则作离线处理;服务端也可对长期未发送探测包的客户端作离线处理。 该方案所有系统都支持,跨平台性好;对端跟自身出现网络故障都能检测到。不足之处在于它需要应用层协议支持,程序内部需要长期维护心跳握手包,相对比较繁琐。 (2) 传输层KeepAlive检测 除了应用层 KeepAlive 检测机制外,TCP 内部也集成了 KeepAlive 机制,默认关闭,开启它很方便。对端跟自身出现网络故障都能检测到。但不是所有的系统都支持,而且有些系统虽然支持但会影响到所有套接字,消耗额外的宽带和流量,不建议使用。 //启用心跳机制,如果您想关闭,将keepAlive置零即可
setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive));
//启用心跳机制开始到首次心跳侦测包发送之间的空闲时间
setsockopt(fd,SOL_TCP,TCP_KEEPIDLE,(void *)&start,sizeof(start));
//两次心跳侦测包之间的间隔时间
setsockopt(fd,SOL_TCP,TCP_KEEPINTVL,(void *)&interval,sizeof(interval));
//探测次数,即将几次探测失败判定为TCP断开
setsockopt(fd,SOL_TCP,TCP_KEEPCNT,(void *)&count,sizeof(count));
(3) 网络层KeepAlive检测 Ping 命令几乎是所有平台的网络连通性检测命令,走网络层 ICMP 协议,这里考虑使用 popen 函数调用系统自带的 Ping 命令来封装网络连通性检测函数。它实际上也是一种网络层的 KeepAlive 机制。 int checkConnect(char *dst, int cnt)
{
FILE stream;
sprintf(cmdBuf, "ping %s -c %d -i 0.2 | grep time= | wc -l", dst, cnt);
stream = popen(cmdBuf, "r");
fread(recvBuf, sizeof(char), sizeof(recvBuf)-1, stream);
pclose(stream);
if (atoi(recvBuf) > 0) return 0;
return -1;
}
dst 指定要检测的目的地址,cnt 指定 Ping 尝试的次数,-i 参数指定 Ping 尝试的超时时间。 (4) 应用层监控内核消息机制 Netlink 是一种特殊的套接字,为2.6.14及更高版本的Linux所特有,通过它,应用层程序可以方便地向内核订制指定消息,如网卡上下线。也可以设置或查询配置,如IP、路由、网络流量信息等。 a、创建一个 netlink 套接字: fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
b、绑定路由多播组,监控网卡信息: addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK; //指定接收路由多播组消息
bind(fd, (struct sockaddr)&addr, sizeof(addr));
c、监听套接字,一旦可读,解析其内容,实时监控网卡上下线事件。 优点:实时性高,使用方便。 缺点:跨平台性不佳,只能检测自身网络故障。 (5) 应用层网卡信息轮询机制 网卡信息轮询机制就是定期调用 ioctl 函数执行如下操作: struct ifconf ifc;
struct ifreq ifrcopy;
//获取网卡信息列表
ioctl(fd, SIOCGIFCONF, (char *)&ifc);
//获取网卡上下线状态
ioctl(fd, SIOCGIFFLAGS, &ifrcopy);
//获取 MAC 地址
ioctl(fd, SIOCGIFHWADDR, (char *)(&ifrcopy);
//获取 IP 地址
ioctl(fd, SIOCGIFADDR, (char *)&ifrcopy);
//获取广播地址
ioctl(fd, SIOCGIFBRDADDR, &ifrcopy));
缺点: a、跨平台性不佳。 可以成功移植到 Linux、Android、Windows平台,但由于 iPhone 平台上获取MAC跟IP的参数不同,需特殊处理。 b、实时性跟灵活性不高。 c、耗费资源,影响性能。 d、只能检测自身网络故障
(epoll事件检测)
0. linux 内存
[root@server ~]# free -m
total used free shared buffers cached
Mem: 249 163 86 0 10 94
-/+ buffers/cache: 58 191
Swap: 511 0 511
其中:
total 内存总数
used 已经使用的内存数
free 空闲的内存数
shared 多个进程共享的内存总额
buffers Buffer Cache和cached Page Cache 磁盘缓存的大小
-buffers/cache 的内存数:used - buffers - cached
+buffers/cache 的内存数:free + buffers + cached
可 用的memory=free memory+buffers+cached
有了这个基础后,可以得知,我现在used为 163MB,free为86,buffer和cached分别为10,94
- tcpdump 抓包只输出 data部分(hex)
tcpdump -t tcp -s 0 port 9101 -i any -A -v -nn -c 10 -x 2>/dev/null|grep -v ">"|grep -v TCP|grep 0x|sed "s/0x0000:/####/g"|tr -t "\n" " "|awk '{a="";for(i=2;i<NF;i++){ if($i=="####"){i=i+39; print a;a=""}else if(substr($i,length($i),1)!=":"){ a=a$i}} print "\n"}'|awk '{print substr($1,105)}'
遇到0x0000: 则是新的一本数据包的开始;
最后过滤掉前面的105个字节(tcp协议信息)。
-
out of socket memory linux 内核提示这个错误信息(dmesg 查看内核消息),产生这个错误信息的两个原因: 0. orphan socket 太多(孤儿) 0. tcp socket memory用尽了
查看内存页面大小
$ getconf PAGESIZE
4096查看孤儿socket配置
$ cat /proc/sys/net/ipv4/tcp_max_orphans
查看系统分配给tcp的内存
$ cat /proc/sys/net/ipv4/tcp_mem
69618 92825 139236
第一个数字表示,当 tcp 使用的 page 少于 69618 时,kernel 不对其进行任何的干预 第二个数字表示,当 tcp 使用了超过 92825 的 pages 时,kernel 会进入 “memory pressure” 第三个数字表示,当 tcp 使用的 pages 超过 139236 时,我们就会看到题目中显示的信息查看socket实际链接等情况
$ cat /proc/net/sockstat sockets: used 116 TCP: inuse 3 orphan 0 tw 4 alloc 4 mem 110 UDP: inuse 1 mem 1 UDPLITE: inuse 0 RAW: inuse 0 FRAG: inuse 0 memory 0 可以看到,实际使用的 mem(110) 远远小于 69618,所以,“Out of socket memory”的错误是由于第一种情况引起的。
-
vmstat 查看系统虚拟内存等使用情况 vmstat 2 3 #没两秒采集一次采集3次
-
linux /proc/pid/syscall /proc/pid/syscall可以协助定位系统调用的问题
ubuntu:~ # cat /proc/8443/syscall
0 0x7 0x70f000 0x1000 0x0 0x7f33e1532e80 0x7f33e1532ed8 0x7fff3a6b8718 0x7f33e128cf00
第一个数字是系统调用号,后面是参数。不同的系统调用所需的参数个数不同。这里的字段数是按最大参数数量来的,所以不一定每个参数字段都有价值。那么怎么知道系统调用号对应哪个系统调用呢?在头文件 /usr/include/asm/unistd_64.h 中都有定义。也可以用个小脚本来快速查找:
#!/bin/bash
# usage: whichsyscall <syscall_nr>
nr="$1"
file="/usr/include/asm/unistd_64.h"
gawk '$1=="#define" && $3=="'$nr'" {sub("^__NR_","",$2);print $2}' "$file"
- vim 删除空行:g/^$//d
- linux 查看网卡统计信息
-n参数很有用,他有6个不同的开关:
DEV | EDEV | NFS | NFSD | SOCK | ALL
。DEV显示网络接口信息,EDEV显示关于网络错误的统计数据,NFS统计活动的NFS客户端的信息,NFSD统计NFS服务器的信息,SOCK显示套 接字信息,ALL显示所有5个开关。它们可以单独或者一起使用。我们现在要用的就是-n DEV了。-u显示cpu统计信息;-q 查看平均负荷;-r 查看内存信息;-W 查看页面交换情况;-b查看I/O和传送率
输入命令:sar –n DEV 1 4 // 每秒钟采集一次,共4次
- git 删除远程分支
0. 首先在本地分支:
git branch -D branchname
0. 然后git push origin :branchname
注意:origin 与: 之间的空格是必须的
- mysqldump innodb
mysqldump备份不锁表:加上--lock-tables=false参数,如果是innodb,则加上--single-transcation比较好。
-
mysql 表结构同步
-
导出结构不导出数据
mysqldump --opt -d 数据库名 -u root -p > xxx.sql -
导出数据不导出结构
mysqldump -t 数据库名 -uroot -p > xxx.sql -
导出数据和表结构
mysqldump 数据库名 -uroot -p > xxx.sql -
导出特定表的结构
mysqldump -uroot -p -B 数据库名 --table 表名 > xxx.sql -
schemasync 同步表结构:
schemasync [options] <source> <target>
# source/target 格式: mysql://user:pass@host:port/database
- mysql 快速dump数据
sample: mydumper -u root -S /tmp/mysql.sock.3306 -o /usr/local/backup/3306 --less-locking
-B database
-T tables
-h host
-p passwd
-S sockefile
--less-locking Minimize locking time on InnoDB tables.
load数据:
/myloader -u root -p 'xxxxx' -B test -d /home/mysql/
-
高并发tcp配置
/etc/sysctl.conf :
net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_orphans = 102400 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_tw_recycle = 1(慎用) net.ipv4.tcp_tw_reuse = 1(慎用) net.ipv4.tcp_max_tw_buckets = 30000 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 8192 net.ipv4.tcp_keepalive_time = 60 net.ipv4.tcp_keepalive_intvl = 15 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.ip_local_port_range = 1024 65000 net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1800
more /proc/sys/net/core/somaxconn echo 50000 > /proc/sys/net/core/somaxconn
cat /proc/sys/net/ipv4/tcp_tw_recycle # 默认值0:不自动回收,谨慎使用,会再某些特殊场景下(NAT)如果时间戳不对会导致连接连不上 echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
cat /proc/sys/net/ipv4/tcp_tw_reuse echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
cat /proc/sys/net/ipv4/tcp_syncookies echo 0 > /proc/sys/net/ipv4/tcp_syncookies
vm.swappiness = 0 net.ipv4.neigh.default.gc_stale_time=120 net.ipv4.conf.all.rp_filter=0 net.ipv4.conf.default.rp_filter=0 net.ipv4.conf.default.arp_announce = 2 net.ipv4.conf.all.arp_announce=2 net.ipv4.tcp_max_tw_buckets = 5000 net.ipv4.tcp_syncookies = 0 # SYN等待队列溢出时,启用cookies来处理 0关闭1启用 net.ipv4.tcp_max_syn_backlog = 10240 # 表示未收到客户端确认信息的连接(SYN消息)最大长度 net.ipv4.tcp_synack_retries = 2 # 重试次数 net.ipv4.conf.lo.arp_announce=2 net.ipv4.tcp_tw_reuse = 1 # 空的TCP回收利用 0关闭 1启用 net.ipv4.tcp_tw_recycle = 1 # 加快TCP回收 0关闭 1启用 net.core.somaxconn = 262144 # 限制监听(LISTEN)队列最大数据包的数量
sysctl -p /etc/sysctl.conf
0. 高并发 /proc/sys/net/core/somaxconn
修改somaxconn,该内核参数默认值一般是128,对于负载很大的服务程序来说大大的不够。一般会将它修改为2048或者更大。
```shell
echo 2048 > /proc/sys/net/core/somaxconn 但是这样系统重启后保存不了
在/etc/sysctl.conf中添加如下
net.core.somaxconn = 2048
然后在终端中执行
sysctl -p
-
shell中字符串命令 比如:
cmd="ls -lh" $cmd #错误
那么要执行这个cmd那么应该采用下面的方法:
cmd="ls -lh" eval $cmd
-
awk 两个文件关联处理:
比如输出a 文件第一列,与b文件种第二列相等的数据:
awk 'NR==FNR{a[$1]=$2;next} {if(a[$2]){print $2"\t"a[$2];}}' a b
解释一下这个命令:当NR==FNR时,即读取第一个文件的时候,先用循环把1.txt中的信息存到数组a中;当NR不等于FNR时,即读取第二个文件的时候,此时$2对应与b中user列,若数组a中有对应与当前行user的记录,则打印user(即$2)和passwd(即a[$2])。
其实在处理单个文件时,NR与FNR都一样,表示当前读取的行号,如执行awk '{print NR}' a 和执行 awk '{print FNR}' a,结果都一样,均为
1
2
3
但是当处理两个文件时,awk先读取第一个文件,此时NR与FNR相等,但是当读取第二个文件时,FNR从新开始计数,而NR继续增长,此时就不相等了 执行awk '{print NR"\t"FNR}' 1.txt 2,txt 结果如下:
1 1
2 2
3 3
4 1
5 2
6 3
- awk 使用shell变量
awk -vnvar="$var" '{print nvar}'
- mysql 查看未提交的事务
- mysql thread stack overrun
Last_Error: Error 'Thread stack overrun: 164768 bytes used of a 196608 byte stack, and 32000 bytes needed
原因是thread statck 太小了,木人的是192kb,可以通过调整mysql.cnf配置
-
nginx upstream
nginx upstream 到后端服务时,如果uri正确,但是却返回404。但是curl “http://test.reg/test/reg"
又是正常的,那么请确认一下,upstream的server端是否配置了多个配置使用同一个端口,同一个端口的请求,
nginx会根据server_name(http header) 将请求分发到对应的服务,否则服务区分请求是发给谁的。 - test1.conf
```nginx
server {
listen 80;
server_name test.reg;
...
location =/ {
...
}
}
0. test2.conf
```nginx
server {
listen 80;
server_name test2.reg;
...
location =/ {
...
}
}
如果是,那么需要在配置文件中配置一下host:
upstream test_svr
{
server test.reg fail_timeout=3;
}
location = /test {
proxy_connect_timeout 3s;
proxy_read_timeout 3s;
proxy_send_timeout 3s;
proxy_pass http://test_svr/$args;
proxy_set_header Host "test.reg";
}
-
排查网络问题
当出现连接不到服务时,首先登陆上服务器,然后telnet ip 端口
或者telnet localhost 端口
, 而telnet 域名 端口
如果此时能够连接,那么可以怀疑DNS出现问题,或者网络出现问题.如果以上都无法连接,而且ping ip/域名偶尔有问题(ping sendmsg operation not permitted),
0. 有可能是系统防火墙限制可以检查(iptable -L
或/etc/sysctl/iptables
). 0. 有可能是配置的打开文件数少了:ulimit -n
查看,或者查看系统级打开最大文件数的限制:/proc/sys/fs/file-max
0. 有可能是系统内核限制
可以通过/etc/sysctl.conf控制和配置Linux内核及网络设置。
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0
net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0
kernel.exec-shield = 1 kernel.randomize_va_space = 1
net.ipv6.conf.default.router_solicitations = 0 net.ipv6.conf.default.accept_ra_rtr_pref = 0 net.ipv6.conf.default.accept_ra_pinfo = 0 net.ipv6.conf.default.accept_ra_defrtr = 0 net.ipv6.conf.default.autoconf = 0 net.ipv6.conf.default.dad_transmits = 0 net.ipv6.conf.default.max_addresses = 1
fs.file-max = 65535
kernel.pid_max = 65536
net.ipv4.ip_local_port_range = 2000 65000
net.ipv4.tcp_rmem = 4096 87380 8388608 net.ipv4.tcp_wmem = 4096 87380 8388608
net.core.rmem_max = 8388608 net.core.wmem_max = 8388608 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_window_scaling = 1
0. mysql 连接
当mysql连接采用localhost连接是,那么将会采用mysql.sock 即用UNIX域协议进行连接,这种情况下通过命令行指定的
的端口号将不起作用,同时`netstat -lnt`命令也看不到对应的连接;但是连接上mysql 通过``show processlist命令可以
看到对应的localhost的连接。
0. file 链接库文件名
查看链接库的版本
```
[root@DELL-200 ms_ma]# file /lib64/libncurses.so.5.7
/lib64/libncurses.so.5.7: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
```
0. ldd 可执行文件
查看该进程中使用到得所有链接库的文件已经状态
```
[root@DELL-200 ms_ma]# ldd ms_ma
linux-gate.so.1 => (0x00976000)
libpthread.so.0 => /lib/libpthread.so.0 (0x007de000)
libnsl.so.1 => /lib/libnsl.so.1 (0x007b6000)
librt.so.1 => /lib/librt.so.1 (0x00b00000)
libncurses.so.5 => not found
libdl.so.2 => /lib/libdl.so.2 (0x00a8d000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00110000)
libm.so.6 => /lib/libm.so.6 (0x00bf0000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x001c9000)
libc.so.6 => /lib/libc.so.6 (0x00499000)
/lib/ld-linux.so.2 (0x00477000)
```
0. netstat -anp | grep portno 查看端口是否被占用
0. telnet 127.0.0.1 19119 查看端口是否正常
0.以root身份登录抓包: /usr/sbin/tcpdump -s 0 -w filename.cap port 223 tcp -c 100 -nn
`
-c 指定包个数
-nn显示真实端口、ip
tcp 只过滤tcp包
`
0. 查看文件的版本位数(32bit 或者 64bit)
`
$ file 文件名
`
0. 查看可执行文件使用了那些库文件(静态库和动态库):
`
$ ldd 文件名
`
0. 查看系统版本位数:
`
$ cat /proc/version
或者
$ uname -a
`
0. 查看系统中使用的端口号
`
$ netstat -anp
`
0. rsyslog 启动命令
`
$ /sbin/rsyslogd -i /var/run/syslogd.pid -c 4
其相应的配置文件/etc/rsyslog.conf
或者:
$ /etc/init.d/rsyslog start # 启用新的 rsyslog
`
0. 激活linux使其生成 core dump 文件:
`
ulimit -c unlimited
sysctl -p
`
0. 查看系统默认服务是否打开或者关闭:
`chkconfig --list`
0. 文件传输
0. `scp [email protected]:/vob/275.1/objs/monitor/mon/nms_monitor ./`
0. 采用nc进行传输:
在需要接收文件的server:10.10.10.2上执行
`nc -l 8888|tar -xvzf - `
在发送文件的server上执行:
`tar -cvzf - test.txt|nc 10.10.10.2 888`
0. awk
0. NF 分割后字段数目
0. 打印所有字段
`awk '{print $0}'`
0.打印每个字段并且每个字段一行:
`awk '{for(i=1;i<=NF;i++)print $i;print '\n'}' `
0. 以指定的分割符划分(默认的分隔符为空格)
`awk -F '/' '{print $0}' `
0. awk 统计某个字段 出现的频率
`awk '{aa[$1]++} END{for(i in a) print i,a[i]}'`
0. set -o vi
linux 命令行模式下,ESC 进入vi模式,可对当前命令行进行编辑(快捷键同vi)