linux

Linux高并发系统参数优化

终于毕业证书到手,学生生涯也算是划上完美的句号了。不过工作强度还真的有点大,还经常加班。感觉自己懒散了许多,人果然是生于忧患,死于安乐。。。最近的项目里对业务处理的高并发要求比较高,因此也学习了相关的如何调整 Linux 内核参数让服务器可以处理非常高并发的业务。所以在博客上记录下相关的经验,以供参考。 修改的参数主要是 Linux 系统参数和网络协议栈参数。注意,以下命令都需要在 root 环境下运行。

# Linux 操作系统参数

系统全局允许分配的最大文件句柄数:

# sysctl -w fs.file-max=2097152
# sysctl -w fs.nr_open=2097152
1
2

允许当前会话/进程打开文件句柄数:

# ulimit -n 1048576
1

但是以上命令只是临时修改,重启系统便会失效,所以我们需要持久化这些参数。

持久化fs.file-max设置到/etc/sysctl.conf 文件:

fs.file-max = 1048576
1

/etc/security/limits.conf 持久化设置允许用户/进程打开文件句柄数:

*      soft   nofile      1048576
*      hard   nofile      1048576
1
2

# TCP 协议栈网络参数

并发连接 backlog(定义了网络连接的队列的最大长度)设置:

# sysctl -w net.core.somaxconn=32768
# sysctl -w net.ipv4.tcp_max_syn_backlog=16384
# sysctl -w net.core.netdev_max_backlog=16384
1
2
3

可用知名端口范围:

# sysctl -w net.ipv4.ip_local_port_range='1000 65535'
1

TCP Socket 读写 Buffer 设置:

# sysctl -w net.core.rmem_default=262144
# sysctl -w net.core.wmem_default=262144
# sysctl -w net.core.rmem_max=16777216
# sysctl -w net.core.wmem_max=16777216
# sysctl -w net.core.optmem_max=16777216

# sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216'
# sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216'
1
2
3
4
5
6
7
8

TCP 连接追踪设置:

# sysctl -w net.nf_conntrack_max=1000000
# sysctl -w net.netfilter.nf_conntrack_max=1000000
# sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
1
2
3

TIME-WAIT Socket 最大数量、回收与重用设置:

# net.ipv4.tcp_max_tw_buckets=1048576
1

FIN-WAIT-2 Socket 超时设置:

# net.ipv4.tcp_fin_timeout = 15
1

# 参考

测试调优 (opens new window)

解决Dota2在Archlinux下的各种疑难杂症

V 社的 steam 平台在 Linux 下出了这么多年还是没解决输入法的问题.本身官方也就只支持 Ubuntu,所以在其它发行版也就难免会有各种各样的问题.容我慢慢道来

# Alt 键无法发信号

Dota2 只能通过 Alt 和鼠标左键的配合发信号.无法像 Dota 一样可以单纯使用鼠标发信号.但是有些用户可能发现自己无法发信号. 原因在于你使用的窗口管理器已经为 Alt 和鼠标左键绑定了事件,所以你得取消窗口管理器的事件绑定,例如 openbox 需要修改配置文件 rc.xml 找到鼠标事件并注释掉事件绑定的内容.

# 双显卡启动游戏

对于很多双显卡的机器,平时运行使用集显但是在玩游戏的时候肯定要使用独显才能充分享受游戏的乐趣.所以启动游戏的时候就必须设置启动参数才行. 启动参数设置为vblank_mode=0 primusrun %command% 前提是你要装上 primusrun.

# Dota2 没声音

如果你只使用的 ALSA 没使用 PulseAudio 可能会遇到这个问题,原因是因为 Steam 自己的库文件和系统的冲突.只要把 Steam 的相关 ALSA 库删掉即可. 删掉下面的文件夹 和 libasound.so.*即可搞定.

~/.steam/steam/ubuntu12_32/steam-runtime/i386/usr/lib/i386-linux-gnu/
~/.steam/steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/
1
2

# 参考:

Steam (opens new window)

Dota 2 (opens new window)

Archlinux和Win 10 在 UEFI下 双启动

实验室给配备了一台高性能的台式机,但是 UEFI 本身关不掉.而且有些操作还是离不开 Windows,于是便折腾 Win10 和 Archlinux 的双启动. 安装双系统基本上都是先装 Windows 再装 Linux 的.切忌这一点,安装顺序反了会很麻烦.

# Win10 配置

要安装 Archlinux,首先得对 Windows 进行相应的配置才行.Windows 的安装就不用我介绍了,大家基本都会的.

# UEFI Secure Boot

首先要进入 BIOS 把这个参数关掉,如果 BIOS 里面有快速启动之类的也关掉.

# Fast Start-Up

把 Win10 的这个加速系统开机的配置禁用掉,应该在电源管理界面可以禁用的.因为切换系统的话这个功能会导致你丢失数据.

# 制作 Arch 的 U 盘安装盘

如果你简单的使用dd (opens new window)命令就可以成功安装那是最好不过的了,但是有时候事与愿违...

假设你用 dd 刻录好之后,然后用电脑 U 盘启动,出现启动菜单 选择 Arch Linux archiso x86_64 UEFI CD 之后遇到黑屏的问题.

你可以先试试禁用 KMS (opens new window)

如果这个不行的话,那说明你得采用第二个办法了,使用 GRUB 进行引导启动盘.

# 手动制作启动盘

因为要使用 GRUB 进行引导,所以不能使用 dd 刻录,dd 刻录的 U 盘有写保护,我们无法修改.我们得手动制作安装盘 (opens new window)

# mkdir -p /mnt/{iso,usb}
# mount -o loop archlinux-2015.10.01-dual.iso /mnt/iso
# mount /dev/sdXn /mnt/usb
# cp -a /mnt/iso/* /mnt/usb
# sync
# umount /mnt/iso
1
2
3
4
5
6

光是拷贝还不行,我们还得有引导信息. 使用 syslinux 进行引导 (opens new window)

# cp -r /usr/lib/syslinux/bios/*.c32 /mnt/usb/arch/boot/syslinux/  ## copy ALL the *.c32 files from /usr/lib/syslinux/bios/, DO NOT SYMLINK
# extlinux --install /mnt/usb/arch/boot/syslinux/
1
2

如果你的 U 盘是 MBR 格式的,记得使用 fdisk 把当前分区设置为活动分区. fdisk /dev/sdX 然后输入 a 命令,选择要设置的活动分区.

还有 U 盘寻找启动分区是根据 U 盘的 label 标签来寻找的,确保你的卷标是 ARCH_2015XX 格式. 如果你不想用卷标的话,还可以用 UUID. 查找你 U 盘的 UUID 的命令是 sudo blkid.

# 制作 GRUB standalone

这才只是手动制作好了启动 U 盘.你还要切换成 GRUB 引导.通过下面的命令制作出一个带有所有模块的 GRUB 引导文件.

grub-mkstandalone -d /usr/lib/grub/x86_64-efi/ -O x86_64-efi --modules="part_gpt part_msdos" --fonts="unicode" --locales="en@quot" --themes="" -o "/tmp/grubx64_standalone.efi"
1

生成的 grubx64_standalone.efi 就是我们需要的文件.

然后回到我们的那个启动 U 盘.备份 EFI/boot/loader.efi 成 EFI/boot/gummiboot.efi.

拷贝两份 grubx64_standalone.efi. 分别命名为 EFI/boot/loader.efi 和 EFI/boot/bootx64.efi.

然后新建一个 EFI/boot/grub.cfg 把 wiki (opens new window)上的内容拷贝过去.记得替换掉 ARCH_YYYYMM 的值.

然后这样就应该用 grub 启动了. 如果你这样还是启动失败了, 得到了类似 invalid magic number的错误.那只能说你跟我一样倒霉.

# 用 GRUB 挂载 ISO 进行引导

既然我们的 GRUB 是好的,那我们就用 GRUB 直接引导一个完整的 ISO 文件. 参考我之前发布的文章使用 GRUB2 引导 ISO 镜像 (opens new window).

在原有的 grub.cfg 上添加一个 menuentry.并把完整的 ISO 镜像拷贝到 U 盘里面.记得替换 UUID 和文件名.

menuentry "Archlinux-x86_64.iso" --class iso {
  set isofile="/archlinux-2013.04.01-dual.iso"
  search -s -f -n /archlinux-2013.04.01-dual.iso
  probe --set=DB7B-2C3D -u $root
  loopback loop /archlinux-2013.04.01-dual.iso
  linux (loop)/arch/boot/x86_64/vmlinuz archisolabel=ARCH_201304 img_dev=/dev/disk/by-uuid/DB7B-2C3D  img_loop=$isofile earlymodules=loop
  initrd (loop)/arch/boot/x86_64/archiso.img
}
1
2
3
4
5
6
7
8

这次总算可以引导出 arch 的安装环境了.接下来就是按照正常的步骤进行安装了. 在 Win 下直接使用Rufus (opens new window)刻录就没那么折腾了.

# 安装 Archlinux 之后配置双系统的 GRUB

到最后我们要安装 GRUB 到 UEFI (opens new window)上.如果你提前安装过 Windows,那么你肯定有 EFI 分区的.

# pacman -S dosfstools grub efibootmgr
# mkdir /boot/efi
# mount /dev/sda1 /boot/efi
1
2
3

把 EFI 分区挂载到系统上,然后安装 GRUB.

# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=grub --recheck
# grub-mkconfig -o /boot/grub/grub.cfg
1
2

生成的 grub.cfg 里面并没有 Windows 的启动菜单,我们需要手动写.

menuentry "Microsoft Windows 10" {
    insmod part_gpt
    insmod fat
    insmod search_fs_uuid
    insmod chain
    search --fs-uuid --set=root $hints_string $fs_uuid
    chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
1
2
3
4
5
6
7
8

$hints_string 的值是命令# grub-probe --target=hints_string /boot/efi/EFI/Microsoft/Boot/bootmgfw.efi的输出.

$fs_uuid 的值是命令# grub-probe --target=fs_uuid /boot/efi/EFI/Microsoft/Boot/bootmgfw.efi的输出.

替换这俩值,保存并退出即可.到此双系统配置完毕.最后别忘了进 BIOS 把第一启动项目设置为 GRUB.

# 参考

Preinstalled Windows 8.1 and Arch Linux dual boot (opens new window)

Unified Extensible Firmware Interface (opens new window)

USB flash installation media (opens new window)

Syslinux (opens new window)

GRUB (opens new window)