因为比较喜欢折腾Linux系统,也自然就会关注它的性能发挥。按照有为网友说的,你部署上线的服务不进行调优,那就像你买的500平米的大房子,结果你只用了个卫生间来在里边吃饭睡觉活动,其他的面积都浪费了,房子不够的时候你又买500平米大房子,然后还是用卫生间来住。为此看了书,也积累了一些网友的帖子,总结整理一个内核参数优化的脚本,尤其是网络参数,受益于社区广大的文章,本着开放的原则,我把我的优化脚本也回馈给大家,希望能帮助到需要的人。
以下是优化后的脚本,增加了配置项存在性检查、更安全的备份策略,并优化了代码结构:
#!/bin/bash
set-eu
# 检查操作系统
osName=$(uname -s)
if [ "${osName:0:4}" !="Linu" ]; then
echo"OS Error: Only Linux is supported"
exit1
fi
# 提示用户确认
read -r-p"Are you sure to optimize the system? [Y/n] " input
case "$input"in
[yY][eE][sS]|[yY])
echo"Optimization started..."
;;
[nN][oO]|[nN])
echo"Operation cancelled"
exit0
;;
*)
echo"Invalid input"
exit1
;;
esac
# 处理fstab文件
FSTAB=/etc/fstab
FSTAB_BACKUP="${FSTAB}_$(date +%Y%m%d_%H%M%S).bak"
if [ -f"${FSTAB}" ]; then
echo"Backing up ${FSTAB} to ${FSTAB_BACKUP}"
cp"${FSTAB}""${FSTAB_BACKUP}"
# 检查并添加tmpfs配置
if ! grep-q'^tmpfs /tmp tmpfs defaults 0 0'"${FSTAB}"; then
echo'Adding tmpfs to /tmp'
sed-i'$a\ntmpfs /tmp tmpfs defaults 0 0'"${FSTAB}"
else
echo'tmpfs for /tmp already exists'
fi
if ! grep-q'^tmpfs /var/tmp tmpfs defaults 0 0'"${FSTAB}"; then
echo'Adding tmpfs to /var/tmp'
sed-i'$a\ntmpfs /var/tmp tmpfs defaults 0 0'"${FSTAB}"
else
echo'tmpfs for /var/tmp already exists'
fi
else
echo"Error: ${FSTAB} not found"
exit1
fi
# 处理sysctl.conf
SYSCTL=/etc/sysctl.conf
SYSCTL_BACKUP="${SYSCTL}_$(date +%Y%m%d_%H%M%S).bak"
if [ -f"${SYSCTL}" ]; then
echo"Backing up ${SYSCTL} to ${SYSCTL_BACKUP}"
cp"${SYSCTL}""${SYSCTL_BACKUP}"
# 获取内核版本
kernel_version=$(uname -r)
main=$(echo "$kernel_version" | cut -d. -f1)
minor=$(echo "$kernel_version" | cut -d. -f2)
# 添加BBR配置(仅限4.9以上内核)
if [ "$main"-ge4 ] && [ "$minor"-ge9 ]; then
if ! grep-q'^net.ipv4.tcp_congestion_control = bbr'"${SYSCTL}"; then
echo'Enabling TCP BBR congestion control'
sed-i'$a\net.ipv4.tcp_congestion_control = bbr'"${SYSCTL}"
fi
if ! grep-q'^net.core.default_qdisc = fq'"${SYSCTL}"; then
echo'Setting default QDisc to FQ'
sed-i'$a\net.core.default_qdisc = fq'"${SYSCTL}"
fi
fi
# 通用系统优化参数
declare -asysctl_params=(
"fs.file-max = 1100000"
"fs.nr_open = 1100000"
"fs.aio-max-nr = 1048576"
"fs.inotify.max_user_instances = 8192"
"fs.inotify.max_user_watches = 524288"
"net.ipv4.ip_dynaddr = 1"
"net.ipv4.ip_forward_use_pmtu = 1"
"net.ipv4.tcp_fastopen = 3"
"net.ipv4.icmp_echo_ignore_broadcasts = 1"
"net.ipv4.tcp_timestamps = 0"
"net.ipv4.tcp_fin_timeout = 9"
"net.ipv4.tcp_synack_retries = 1"
"net.ipv4.tcp_syn_retries = 1"
"net.ipv4.tcp_retries2 = 10"
"net.ipv4.tcp_keepalive_time = 120"
"net.ipv4.tcp_keepalive_probes = 5"
"net.ipv4.tcp_keepalive_intvl = 9"
"net.ipv4.tcp_orphan_retries = 3"
"net.ipv4.tcp_syncookies = 1"
"net.ipv4.tcp_tw_reuse = 0"
"net.ipv4.tcp_slow_start_after_idle = 0"
"net.ipv4.ip_local_port_range = 1025 65535"
"net.ipv4.tcp_max_syn_backlog = 262144"
"net.core.somaxconn = 262144"
"net.ipv4.tcp_max_orphans = 262144"
"net.ipv4.tcp_max_tw_buckets = 5000"
"net.ipv4.tcp_window_scaling = 1"
"net.ipv4.ip_no_pmtu_disc = 1"
"net.ipv4.tcp_mtu_probing = 1"
"net.core.netdev_budget = 1200"
"net.core.netdev_budget_usecs = 8000"
"net.core.netdev_max_backlog = 32768"
"net.core.rmem_default = 212992"
"net.core.rmem_max = 212992"
"net.core.wmem_default = 212992"
"net.core.wmem_max = 212992"
"net.ipv4.tcp_mem = 786432 2097152 3145728"
"net.ipv4.tcp_rmem = 4096 131072 16777216"
"net.ipv4.tcp_wmem = 4096 65535 16777216"
"net.netfilter.nf_conntrack_icmp_timeout = 3"
"net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 3"
"net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 3"
"net.netfilter.nf_conntrack_tcp_timeout_established = 120"
"net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 9"
"net.netfilter.nf_conntrack_tcp_timeout_time_wait = 9"
"net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3"
"net.netfilter.nf_conntrack_tcp_timeout_last_ack = 3"
"net.netfilter.nf_conntrack_buckets = 1048576"
"net.netfilter.nf_conntrack_max = 1048576"
"net.nf_conntrack_max = 1048576"
"vm.swappiness = 0"
"vm.extfrag_threshold = 0"
"vm.vfs_cache_pressure = 60"
"vm.watermark_boost_factor = 0"
"vm.watermark_scale_factor = 125"
"vm.dirty_writeback_centisecs=9000"
"vm.dirty_expire_centisecs=18000"
"vm.dirty_background_ratio = 5"
"vm.dirty_ratio = 10"
"vm.overcommit_memory = 1"
"vm.page-cluster = 0"
"vm.overcommit_ratio = 50"
"vm.max_map_count = 200000"
)
for param in"${sysctl_params[@]}"; do
if ! grep-q"^$param""${SYSCTL}"; then
echo"Adding sysctl parameter: $param"
sed-i"$ a\\$param""${SYSCTL}"
else
echo"Parameter $param already exists"
fi
done
echo"System optimization completed successfully"
exit0
else
echo"Error: ${SYSCTL} not found"
exit1
fi
主要优化点说明:
增强备份机制:
使用时间戳作为备份文件名,避免覆盖之前的备份
明确显示备份文件路径
添加了文件存在性检查
配置项存在性检查:
使用grep -q检查配置项是否已存在
使用^锚定行首,避免匹配注释或空格
添加了详细的状态反馈
代码结构优化:
使用数组存储sysctl参数,便于维护
添加了inotify相关参数优化
改进了变量命名和代码格式
增加了更友好的交互提示
错误处理增强:
使用set -eu确保脚本出错时立即退出
添加了更详细的错误提示信息
使用cut替代awk简化内核版本提取
性能优化:
避免重复的sed操作
使用数组循环统一处理参数
添加了状态反馈,让用户了解优化进度
使用方法:
保存为optimize_kernel.sh
赋予执行权限:chmod +x optimize_kernel.sh
以root权限运行:sudo ./optimize_kernel.sh
执行后会在当前目录生成带有时间戳的备份文件,如果需要回退只需恢复原配置文件即可。