linux 开发常用的命令
性能排查指令
1
2
3
4
5
6
7
8
9uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1perf
- 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、只能检测自身网络故障linux 内存
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[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,94tcpdump 抓包只输出 data部分(hex)
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
50tcpdump -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协议信息)。
0. 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”的错误是由于第一种情况引起的。
0. vmstat 查看系统虚拟内存等使用情况
vmstat 2 3 #没两秒采集一次采集3次
0. linux /proc/pid/syscall
/proc/pid/syscall可以协助定位系统调用的问题
```shell
ubuntu:~ # cat /proc/8443/syscall
0 0x7 0x70f000 0x1000 0x0 0x7f33e1532e80 0x7f33e1532ed8 0x7fff3a6b8718 0x7f33e128cf00
```
第一个数字是系统调用号,后面是参数。不同的系统调用所需的参数个数不同。这里的字段数是按最大参数数量来的,所以不一定每个参数字段都有价值。那么怎么知道系统调用号对应哪个系统调用呢?在头文件 /usr/include/asm/unistd_64.h 中都有定义。也可以用个小脚本来快速查找:
```shell
!/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和传送率1
输入命令:sar –n DEV 1 4 // 每秒钟采集一次,共4次
git 删除远程分支
- 首先在本地分支:
git branch -D branchname
- 然后
git push origin :branchname
注意:origin 与: 之间的空格是必须的
- 首先在本地分支:
mysqldump innodb
1
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 同步表结构:
1
2
3schemasync [options] <source> <target>
# source/target 格式: mysql://user:pass@host:port/database
- 导出结构不导出数据
mysql 快速dump数据
1
2
3
4
5
6
7
8
9
10
11
12sample: 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数据:
```shell
/myloader -u root -p 'xxxxx' -B test -d /home/mysql/高并发tcp配置
/etc/sysctl.conf :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
53net.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
sock 优化
more /proc/sys/net/core/somaxconn
echo 50000 > /proc/sys/net/core/somaxconn
加快TCP回收
cat /proc/sys/net/ipv4/tcp_tw_recycle # 默认值0:不自动回收,谨慎使用,会再某些特殊场景下(NAT)如果时间戳不对会导致连接连不上
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
空的TCP回收利用
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
编辑 vim /etc/sysctl.conf 文件永久优化
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高并发 /proc/sys/net/core/somaxconn
修改somaxconn,该内核参数默认值一般是128,对于负载很大的服务程序来说大大的不够。一般会将它修改为2048或者更大。1
echo 2048 > /proc/sys/net/core/somaxconn 但是这样系统重启后保存不了
在/etc/sysctl.conf中添加如下
1
net.core.somaxconn = 2048
然后在终端中执行
1
sysctl -p
shell中字符串命令
比如:1
2cmd="ls -lh"
cmd #错误那么要执行这个cmd那么应该采用下面的方法:
1
2cmd="ls -lh"
eval $cmdawk 两个文件关联处理:
比如输出a 文件第一列,与b文件种第二列相等的数据:1
2
3
4
5
6
7
8awk '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,结果都一样,均为
```c
1
2
3但是当处理两个文件时,awk先读取第一个文件,此时NR与FNR相等,但是当读取第二个文件时,FNR从新开始计数,而NR继续增长,此时就不相等了
执行awk ‘{print NR”\t”FNR}’ 1.txt 2,txt 结果如下:1
2
3
4
5
61 1
2 2
3 3
4 1
5 2
6 3awk 使用shell变量
1
awk -vnvar="$var" '{print nvar}'
mysql 查看未提交的事务
- mysql thread stack overrun
1
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
1
2
3
4
5
6
7
8server {
listen 80;
server_name test.reg;
...
location =/ {
...
}
}test2.conf
1
2
3
4
5
6
7
8server {
listen 80;
server_name test2.reg;
...
location =/ {
...
}
}
如果是,那么需要在配置文件中配置一下host:
1
2
3
4
5
6
7
8
9
10
11upstream 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),
- 有可能是系统防火墙限制可以检查(
iptable -L
或/etc/sysctl/iptables
). - 有可能是配置的打开文件数少了:
ulimit -n
查看,或者查看系统级打开最大文件数的限制:/proc/sys/fs/file-max
有可能是系统内核限制
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可以通过/etc/sysctl.conf控制和配置Linux内核及网络设置。
# 避免放大攻击
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 开启恶意icmp错误消息保护
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 开启SYN洪水攻击保护
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
# 开启execshild
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# IPv6设置
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
# 优化LB使用的端口
# 增加系统文件描述符限制
fs.file-max = 65535
# 允许更多的PIDs (减少滚动翻转问题); may break some programs 32768
kernel.pid_max = 65536
# 增加系统IP端口限制
net.ipv4.ip_local_port_range = 2000 65000
# 增加TCP最大缓冲区大小
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 87380 8388608
# 增加Linux自动调整TCP缓冲区限制
# 最小,默认和最大可使用的字节数
# 最大值不低于4MB,如果你使用非常高的BDP路径可以设置得更高
# Tcp窗口等
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_window_scaling = 1
- 有可能是系统防火墙限制可以检查(
mysql 连接
当mysql连接采用localhost连接是,那么将会采用mysql.sock 即用UNIX域协议进行连接,这种情况下通过命令行指定的
的端口号将不起作用,同时netstat -lnt
命令也看不到对应的连接;但是连接上mysql 通过show processlist命令可以
看到对应的localhost的连接。file 链接库文件名
查看链接库的版本1
2[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, strippedldd 可执行文件
查看该进程中使用到得所有链接库的文件已经状态1
2
3
4
5
6
7
8
9
10
11
12[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)netstat -anp | grep portno 查看端口是否被占用
- 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包
- 查看文件的版本位数(32bit 或者 64bit)
$ file 文件名
- 查看可执行文件使用了那些库文件(静态库和动态库):
$ ldd 文件名
- 查看系统版本位数:
$ cat /proc/version 或者 $ uname -a
- 查看系统中使用的端口号
$ netstat -anp
- rsyslog 启动命令
$ /sbin/rsyslogd -i /var/run/syslogd.pid -c 4 其相应的配置文件/etc/rsyslog.conf 或者: $ /etc/init.d/rsyslog start # 启用新的 rsyslog
- 激活linux使其生成 core dump 文件:
`
`ulimit -c unlimited sysctl -p
- 查看系统默认服务是否打开或者关闭:
chkconfig --list
文件传输
scp root@10.48.32.52:/vob/275.1/objs/monitor/mon/nms_monitor ./
- 采用nc进行传输:
在需要接收文件的server:10.10.10.2上执行
nc -l 8888|tar -xvzf -
在发送文件的server上执行:
tar -cvzf - test.txt|nc 10.10.10.2 888
awk
- NF 分割后字段数目
- 打印所有字段
awk '{print $0}'
0.打印每个字段并且每个字段一行:awk '{for(i=1;i<=NF;i++)print $i;print '\n'}'
- 以指定的分割符划分(默认的分隔符为空格)
awk -F '/' '{print $0}'
- awk 统计某个字段 出现的频率
awk '{aa[$1]++} END{for(i in a) print i,a[i]}'
- set -o vi
linux 命令行模式下,ESC 进入vi模式,可对当前命令行进行编辑(快捷键同vi)