为什么要做性能优化
Linux默认的系统参数是为通用场景设计的,不一定适合你的具体业务。我见过很多服务器,硬件配置不低但性能上不去,原因就是系统参数没优化。
今天分享一些我在生产环境中实际用过的优化方法,效果立竿见影。
性能诊断:先找瓶颈
优化之前,先弄清楚瓶颈在哪。
快速诊断命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # CPU负载
$ uptime
10:00:00 up 30 days, load average: 2.50, 1.80, 1.20
# load average三个数字分别是1分钟、5分钟、15分钟平均负载
# 一般不超过CPU核心数就正常
# 查看CPU核心数
$ nproc
4
# CPU使用详情
$ mpstat -P ALL 1
Linux 5.15.0-91-generic 02/18/2026
10:00:01 CPU %usr %nice %sys %iowait %irq %soft %steal %idle
10:00:02 all 25.12 0.00 5.23 2.15 0.00 0.50 0.00 67.00
10:00:02 0 30.00 0.00 6.00 3.00 0.00 1.00 0.00 60.00
10:00:02 1 22.00 0.00 5.00 1.00 0.00 0.00 0.00 72.00
|
性能诊断清单
| 指标 | 查看命令 | 正常范围 |
|---|
| CPU负载 | uptime | < CPU核心数 |
| CPU使用率 | mpstat 1 | < 80% |
| 内存使用 | free -h | 可用 > 20% |
| 磁盘IO | iostat -x 1 | %util < 80% |
| 磁盘空间 | df -h | 使用率 < 85% |
| 网络 | sar -n DEV 1 | 无丢包 |
| 打开文件数 | cat /proc/sys/fs/file-nr | 远低于限制 |
内核参数优化
网络参数优化
这是Web服务器最重要的优化:
1
| $ sudo vim /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
| # ===== 网络优化 =====
# 增大连接队列(高并发必须调)
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
# TCP优化
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
# TIME_WAIT优化(高并发服务器)
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
# 端口范围扩大
net.ipv4.ip_local_port_range = 1024 65535
# TCP缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# ===== 内存优化 =====
# 减少swap使用倾向(值越小越少用swap)
vm.swappiness = 10
# 脏页参数
vm.dirty_ratio = 30
vm.dirty_background_ratio = 5
# ===== 文件系统 =====
# 增大文件监控数量
fs.inotify.max_user_watches = 524288
# 增大文件描述符限制
fs.file-max = 2097152
|
1
2
3
4
5
6
7
8
9
10
| # 使配置生效
$ sudo sysctl -p
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
...
# 验证
$ sysctl net.core.somaxconn
net.core.somaxconn = 65535
|
参数说明
| 参数 | 默认值 | 优化值 | 说明 |
|---|
somaxconn | 4096 | 65535 | 监听队列上限 |
tcp_fin_timeout | 60 | 30 | FIN超时时间 |
tcp_tw_reuse | 0 | 1 | 重用TIME_WAIT |
swappiness | 60 | 10 | swap使用倾向 |
file-max | 65535 | 2097152 | 系统文件描述符上限 |
文件描述符限制
很多应用(Nginx、MySQL、Node.js)都需要打开大量文件和连接。
1
2
3
4
5
6
7
8
9
| # 查看当前限制
$ ulimit -n
1024 # 默认只有1024,太小了
# 临时修改
$ ulimit -n 65535
# 永久修改
$ sudo vim /etc/security/limits.conf
|
1
2
3
4
5
6
7
| # /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
root soft nofile 65535
root hard nofile 65535
|
1
2
3
4
5
6
7
| # 对于systemd管理的服务,还需要修改service文件
$ sudo vim /etc/systemd/system/nginx.service.d/limits.conf
[Service]
LimitNOFILE=65535
$ sudo systemctl daemon-reload
$ sudo systemctl restart nginx
|
Swap优化
合理设置Swap大小
| 内存大小 | 建议Swap | 说明 |
|---|
| ≤ 2GB | 2倍内存 | 小内存服务器需要更多swap |
| 2-8GB | 等于内存 | 平衡选择 |
| 8-64GB | 4-8GB | 大内存不需要太多swap |
| > 64GB | 4GB | 或者不设swap |
创建/调整Swap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 查看当前swap
$ swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 2G 64M -2
# 创建新的swap文件
$ sudo fallocate -l 4G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 4 GiB
$ sudo swapon /swapfile
# 写入fstab永久生效
$ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 调整swappiness
$ sudo sysctl vm.swappiness=10
$ echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
|
Nginx性能优化
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
| # /etc/nginx/nginx.conf
worker_processes auto; # 自动匹配CPU核心数
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
multi_accept on;
use epoll;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# 缓冲区
client_body_buffer_size 16k;
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
# 文件缓存
open_file_cache max=65535 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
}
|
MySQL性能优化
1
| $ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| [mysqld]
# 缓冲池(最重要的参数,设为可用内存的50-70%)
innodb_buffer_pool_size = 1G
# 日志文件
innodb_log_file_size = 256M
innodb_log_buffer_size = 16M
# 连接数
max_connections = 500
# 查询缓存
query_cache_type = 0
query_cache_size = 0
# 临时表
tmp_table_size = 64M
max_heap_table_size = 64M
# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
|
磁盘IO优化
1
2
3
4
5
6
7
8
9
10
11
| # 查看当前IO调度器
$ cat /sys/block/vda/queue/scheduler
[mq-deadline] none
# 对于SSD,使用noop/none调度器
$ echo "none" | sudo tee /sys/block/vda/queue/scheduler
# 查看磁盘IO情况
$ iostat -x 1 3
Device r/s w/s rkB/s wkB/s %util
vda 1.23 15.67 12.34 156.78 5.23%
|
| IO调度器 | 适用场景 |
|---|
mq-deadline | HDD通用(默认) |
none/noop | SSD |
bfq | 桌面/交互式 |
kyber | 高速存储 |
优化效果验证
用ab做压力测试
1
2
3
4
5
6
7
8
9
10
11
| $ sudo apt install -y apache2-utils
# 压测:1000个请求,100并发
$ ab -n 1000 -c 100 http://localhost/
Concurrency Level: 100
Time taken for tests: 2.345 seconds
Complete requests: 1000
Failed requests: 0
Requests per second: 426.44 [#/sec] (mean)
Time per request: 234.50 [ms] (mean)
Transfer rate: 1234.56 [Kbytes/sec] received
|
优化前后对比
| 指标 | 优化前 | 优化后 | 提升 |
|---|
| QPS | 200 | 850 | 4.25x |
| 平均响应时间 | 500ms | 120ms | 4.17x |
| CPU使用率 | 90% | 45% | 减半 |
| 内存使用 | 85% | 60% | 下降25% |
优化清单总结
1
2
3
4
5
6
7
8
| # 快速优化清单(按优先级排序)
1. 调整内核网络参数(sysctl.conf)
2. 增大文件描述符限制(limits.conf)
3. 调整swappiness
4. 优化Nginx配置
5. 优化MySQL缓冲池
6. 调整IO调度器(SSD)
7. 开启Gzip压缩
|
总结
性能优化的核心原则:先诊断,再优化,最后验证。不要盲目调参数,先用工具找到瓶颈,针对性优化,然后用压测验证效果。
服务器监控是持续优化的基础,推荐阅读监控工具推荐。磁盘管理方面可以参考Linux磁盘管理。