记得12年的时候调优个一个tcp server, 系统运行在linux上, 大概会模拟100k个客户端通过tcp连接, 相互之间收发message, 消息大小有1kb, 模拟的是相互的聊天应用。程序是构建在java + NIO, 针对这个应用作系统调优
- 修改资源限制
linux 修改资源限制的方式有很多, 常用的方法就是修改ulimit的配置文件
$ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63667
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
//进程最大打开文件数
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
//用户线程最大数
max user processes (-u) 1024
永久修改这些,可以修改配置文件 /etc/security/limits.conf 添加或者修改两行(确保root身份)
user soft nproc 500000
user hard nproc 1000000
user soft nofile 500000
user hard nofile 1000000
NOTE: soft 和hard的含义,很好理解,hard 表示一定不能超过是硬性限制, soft设定的值是可以超过, 但是超过了会有警告信息。
要单机支持这么多的连接, 还要修改端口限制, 否则无法建立如此多的tcp连接(双网卡100k),修改的命令是 sysctrl,要查看当前的端口限制,如下命令
cat /proc/sys/net/ipv4/ip_local_port_range
10000 20000
结果表示可用的是可用端口范围
修改的方法, 新建一个文件 tuning.conf
net.core.wmem_max=12582912//最大socket写buffer
net.core.rmem_max=12582912//最大socket读buffer
net.ipv4.tcp_rmem= 10240 87380 12582912//tcp读 buffer,
net.ipv4.tcp_wmem= 10240 87380 12582912//tcp写 buffer
net.ipv4.tcp_timestamps = 1//大数据包下有用, 可以让内核识别重复的包序号
net.ipv4.tcp_sack = 1// seleck ack, 针对丢包的,网络不稳定, 包量较大,有用
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_mem = 10240 87380 12582912//tcp 内存大小 单位是页
net.ipv4.ip_local_port_range=10000 65535
直接使用命令 sysctrl -p tuning.conf就可以修改, 这里有很多参数, 不去详细介绍
- 常用工具介绍
- mpstat
命令的详细说明可以用man手册, 先看下常用到的方式
$mpstat -P ALL 3
12:20:39 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
12:20:42 PM all 0.00 0.00 0.04 0.08 0.00 0.00 0.00 0.00 99.87
12:20:42 PM 0 0.00 0.00 0.00 0.33 0.00 0.00 0.00 0.00 99.67
12:20:42 PM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
该命令的作用是 打印全部, 3s一次
对关键输出结果说明:
CPU对应的列, all 对的是整机的cpu使用情况, 剩下的是cpu 0 ~ cpu 7的使用情况
user% 用户态cpu使用, sys% 内核态cpu使用的情况, soft% 软中断, irq%中断
这个命令用处就是他统计了不同cpu的使用情况, 尤其是当我们调试多线程,网络程序时, 最好用这个命令看下, 是否有,没有利用多核, 或网络中断处理不均衡的情况(现象就是某一个或几个cpu用光,其余很闲)。
$mpstat -P ALL 3
12:20:39 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
12:20:42 PM all 0.00 0.00 0.04 0.08 0.00 0.00 0.00 0.00 99.87
12:20:42 PM 0 0.00 0.00 0.00 0.33 0.00 0.00 0.00 0.00 99.67
12:20:42 PM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
12:20:42 PM 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
对关键输出结果说明:
2. sar
sar这个命令要将的话能讲很多,详细的我们不讨论, 网上很多博客都详细论述,但是他很有用 磁盘,网络,内存全能监控,下面看下我们的几个用法
$ sar -n DEV 1
12:44:00 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
12:44:01 PM eth0 5.00 0.00 0.48 0.00 0.00 0.00 0.00
12:44:01 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:44:01 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
12:44:02 PM eth0 4.00 2.00 0.33 0.44 0.00 0.00 0.00
12:44:02 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:44:02 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
12:44:03 PM eth0 1.00 1.00 0.06 0.37 0.00 0.00 0.00
12:44:03 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
这个是用来统计网卡流量, 每隔1s刷新. 含义很好理解。
统计磁盘的使用可以用iostat, 当然 sar也可以代劳
sar -d 1
12:46:46 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:46:47 PM dev8-0 2.00 0.00 16.00 8.00 0.00 0.00 0.00 0.00
12:46:47 PM dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:46:47 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:46:48 PM dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:46:48 PM dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:46:48 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:46:49 PM dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:46:49 PM dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
总结
本文只能算是个引子, 简单的介绍了一些用法, 这些只能是表面上的东西。 深层次的东西,我们以后会再来展开, 比如说
- 如何统计真正的cpu使用情况(vmstat这些工具是有问题的, 不能相信, 尤其是HT 打开的情况)
- 如何来排查多线程的问题,线程死锁, 线程锁比较重,导致的性能差
- 底层的一些比方 cache miss, numa locality, 还有例如虽然软件设计上没有锁, 但底层硬件有锁等问题
- 内存碎片如何避免, 如何监控
上面这些问题我都会在后续博客中讨论下。