微信订阅号二维码
本栏目热门内容
  • Acrobat虚拟PDF打印机执行...
  • LINKSYS交换机登录WEB界面...
  • 又一次RAID 5阵列故障记录...
  • 解决VMware vSphere ESXi ...
  • 修改CentOS发行信息以绕过...
  • Windows Server 2008 重命...
  • 解决虚拟化运行的 Windows...
  • Intel Nehalem CPU Errata...
  • 某卢瑟装机搞得一踏糊涂,...
  • 解决MySQL Cluster 备份总...
  • MegaCli安装及使用杂记
  • 解决WSUS显示客户端不全的...
  • 解决 VMWare vSphere 6 客...
  • 解决Windows Server 2008 ...
  • 本站服务器RAID 5阵列双硬...
  • 网站数据库从MySQL 5.0升...
  • 解决MariaDB使用Percona X...
  • 修改arpwatch使通知邮件主...
  • Linux 下的分区调整工具GP...
  • DELL PowerEdge 820 报CPU...
  • 程序员漫画:如何用8种不...
  • 解决很好用的多合一即时通...
  • 使用 GParted 进行虚拟机...
  • 解决Samba WINS服务的错误...
  • 解决Squid代理HTTP时在浏...
  • 用Delphi编写使用到ADO的D...
  • 网站简单改版
  • 索尼系列手提电脑备份失败...
  • Dell R900服务器 BMC firm...
  • 更多...

    Linux 软路由网络吞吐优化设置
    作者:Sender  来源:WaveCN.com  发布日期:2022-02-25  最后修改日期:2022-02-26

      如果使用CentOS 等 Linux操作系统、X86服务器作为软路由,网络吞吐设置是需要进行一些必需的优化设置,因为系统的默认设置并不是为了这种用途而设计。

      本文基于CentOS 7,最终实现的效果是终端数量高峰在350台左右,并发连接数14000条,路由能力仅受限于出口带宽,内网路由无丢包。暂未有条件试验更多的终端数量。

     

      相关设置编写为系统启动后的初始化脚本,通过/etc/rc.d/rc.local来调用。需要说一下的是CentOS 7中,rc.local是通过systemd,作为一个一次性运行对的服务来调用的。因此,需要通过:

    # systemctl enable rc-local
    # chmod +x /etc/rc.d/rc.local
    

      去启用。

     

      下面介绍优化设置。

     

      1. 常量定义

      定义所有的网络界面,比如em1 em2是主板上的端口,而p1p1~p1p4是附加的4端口网卡

    INTERFACES="lo em1 em2 p1p1 p1p2 p1p3 p1p4"
    

     

      定义并发连接数设置。

      CONNTRACK 跟踪并且记录连接状态。Linux 核心对网络栈的每一个数据包均通过记录连接项去确定数据包所归属的数据流。

    CONNTRACK_MAX="262144"
    HASHSIZE="65536"
    

     

      2. TCP/IP基本设置

      这些设置也可能已经是系统的默认设置。重复设置并无问题,反而是确保会被设置。

     

      启用IP转发

    echo 1 > /proc/sys/net/ipv4/ip_forward
    

     

      明确地禁止ECN

    if [ -e /proc/sys/net/ipv4/tcp_ecn ]
    then
      echo 0 > /proc/sys/net/ipv4/tcp_ecn
    fi
    

     

      防范SYN Flood攻击

    echo "1" > /proc/sys/net/ipv4/tcp_syncookies
    

     

      某些路由器违反了RFC1122定义,会对ICMP广播帧发送虚假的响应。此类违反情况正常情况下会被作为内核警告而记录下来。通过设置为1(一般是默认值),内核就不会进行记录,从而避免日志文件泛滥。

    echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 
    

     

      调整ARP超时时间

    echo 300 > /proc/sys/net/ipv4/neigh/default/base_reachable_time
    echo 600 > /proc/sys/net/ipv4/neigh/default/gc_stale_time
    

     

      扩大ARP表。存在于ARP高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行。缺省值是128。

    echo 1024 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
    

     

      保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒。缺省值是 512。 

    echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
    

     

      保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是1024。

    echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
    

     

      设置TCP连接超时。 默认值600秒,太长了。

    echo 180 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
    echo 180 > /proc/sys/net/netfilter/nf_conntrack_generic_timeout
    

     

      扩充接收队列

    echo 4096 > /proc/sys/net/core/netdev_max_backlog
    echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
    echo 2048 > /proc/sys/net/core/somaxconn
    

     

      扩充缓冲区

    echo 16777216 > /proc/sys/net/core/rmem_max
    echo 16777216 > /proc/sys/net/core/wmem_max
    echo "4096 87380 16777216" > /proc/sys/net/ipv4/tcp_rmem
    echo "4096 65536 16777216" > /proc/sys/net/ipv4/tcp_wmem
    

     

      3. 增加并发连接处理能力

      修改ip_conntrack_max和hashsize的值。

    echo $HASHSIZE > /sys/module/nf_conntrack/parameters/hashsize
    echo $CONNTRACK_MAX > /proc/sys/net/nf_conntrack_max
    

      以上2句其实可以被/etc/modprobe.d/nf_conntrack.conf的配置取代

     

      要计算Conntrack模块需要占用的内存数量,可以按如下的方法:

    size_of_mem_used_by_conntrack = CONNTRACK_MAX * sizeof(struct ip_conntrack) + HASHSIZE * sizeof(struct list_head)
    

     

      但是,sizeof(struct ip_conntrack) 会因为内核版本、系统架构、编译设置等等因素而不同。如果要准确获得这个值,需要观察内核日志信息中,ip_conntrack初始化时的信息。比如,对于CentOS 5.2 64位版本,sizeof(struct ip_conntrack) 是304字节。然后,sizeof(struct list_head) = 2 * 指针字节数,如果是64位系统,指针占8个字节。因此,conntrack所使用的内存 = CONNTRACK_MAX * 304 + HASHSIZE * 8 (字节),代入本文例子:262144和65536,计算得到即 80216064 字节,76.5M内存。

     

      如果定义的数量太大,比如CONNTRACK_MAX=1048576,会导致操作系统使用vmalloc来分配内存。而vmalloc分配的内存不是核心内存,可能会产生内存交换、物理地址不连续、强制对齐到内存页等问题。从而影响性能。

     

      本文不讨论Linux核心对内存的分配使用机制,有兴趣可以参考:

    https://www.kernel.org/doc/html/latest/vm/index.html

    https://hammertux.github.io/slab-allocator

     

      4. 对网络界面设置

      禁止所有网络界面的spoofing,优化网卡发送接收队列长度。

    for x in ${INTERFACES}
    do
      echo 1 > /proc/sys/net/ipv4/conf/${x}/rp_filter
      ethtool -G ${x} rx 2047 tx 511
      ip link set dev ${x} txqueuelen 2047
    done
    

      或者可以进一步考虑,把这个脚本调整为通过 ethtool -g em1 这样的命令获取可以设置的最大值(即命令参数中的2047、511等值)去设置。不过一般情况下,手工获取一次然后修改设置到这个脚本,也就足够了。

     

      最后汇总一下无注释脚本如下:

    #!/bin/sh
    
    INTERFACES="lo em1 em2 p1p1 p1p2 p1p3 p1p4"
    CONNTRACK_MAX="262144"
    HASHSIZE="65536"
    
    echo 1 > /proc/sys/net/ipv4/ip_forward
    if [ -e /proc/sys/net/ipv4/tcp_ecn ]
    then
      echo 0 > /proc/sys/net/ipv4/tcp_ecn
    fi
    echo "1" > /proc/sys/net/ipv4/tcp_syncookies
    echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 
    echo 300 > /proc/sys/net/ipv4/neigh/default/base_reachable_time
    echo 600 > /proc/sys/net/ipv4/neigh/default/gc_stale_time
    echo 1024 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
    echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
    echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3   
    echo 180 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
    echo 180 > /proc/sys/net/netfilter/nf_conntrack_generic_timeout
    echo 4096 > /proc/sys/net/core/netdev_max_backlog
    echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
    echo 2048 > /proc/sys/net/core/somaxconn
    echo 16777216 > /proc/sys/net/core/rmem_max
    echo 16777216 > /proc/sys/net/core/wmem_max
    echo "4096 87380 16777216" > /proc/sys/net/ipv4/tcp_rmem
    echo "4096 65536 16777216" > /proc/sys/net/ipv4/tcp_wmem
    echo $HASHSIZE > /sys/module/nf_conntrack/parameters/hashsize
    echo $CONNTRACK_MAX > /proc/sys/net/nf_conntrack_max
    for x in ${INTERFACES}
    do
      echo 1 > /proc/sys/net/ipv4/conf/${x}/rp_filter
      ethtool -G ${x} rx 2047 tx 511
      ip link set dev ${x} txqueuelen 2047
    done
    

     

      带注释脚本如下:

    #!/bin/sh
    
    # 1. 常量定义
    # 定义所有的网络界面,比如em1 em2是主板上的端口,而p1p1~p1p4是附加的4端口网卡
    INTERFACES="lo em1 em2 p1p1 p1p2 p1p3 p1p4"
    
    # 定义并发连接数设置。
    # CONNTRACK 跟踪并且记录连接状态。Linux 核心对网络栈的每一个数据包均通过记录连接项去确定数据包所归属的数据流。
    CONNTRACK_MAX="262144"
    HASHSIZE="65536"
    
    # 2. TCP/IP基本设置
    # 这些设置也可能已经是系统的默认设置。重复设置并无问题,反而是确保会被设置。
    
    # 启用IP转发
    echo 1 > /proc/sys/net/ipv4/ip_forward
    
    # 显式禁止ECN
    if [ -e /proc/sys/net/ipv4/tcp_ecn ]
    then
      echo 0 > /proc/sys/net/ipv4/tcp_ecn
    fi
    
    # 防范SYN Flood攻击
    echo "1" > /proc/sys/net/ipv4/tcp_syncookies
    
    # 某些路由器违反了RFC1122定义,会对ICMP广播帧发送虚假的响应。
    # 此类违反情况正常情况下会被作为内核警告而记录下来。
    # 通过设置为1(一般是默认值),内核就不会进行记录,从而避免日志文件泛滥。
    echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 
    
    # 调整ARP超时时间
    echo 300 > /proc/sys/net/ipv4/neigh/default/base_reachable_time
    echo 600 > /proc/sys/net/ipv4/neigh/default/gc_stale_time
    # 扩大ARP表。这个是第二层的事情。
    # 存在于ARP高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行。缺省值是128。
    echo 1024 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
    # 保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒。缺省值是 512。 
    echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
    # 保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是1024。
    echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3   
    
    # 设置TCP连接超时。
    echo 180 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
    # 默认值600秒,太长
    echo 180 > /proc/sys/net/netfilter/nf_conntrack_generic_timeout
    
    # 扩充接收队列
    echo 4096 > /proc/sys/net/core/netdev_max_backlog
    echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
    echo 2048 > /proc/sys/net/core/somaxconn
    
    # 扩充缓冲区
    echo 16777216 > /proc/sys/net/core/rmem_max
    echo 16777216 > /proc/sys/net/core/wmem_max
    echo "4096 87380 16777216" > /proc/sys/net/ipv4/tcp_rmem
    echo "4096 65536 16777216" > /proc/sys/net/ipv4/tcp_wmem
    
    # 3. 增加并发连接处理能力
    # 修改ip_conntrack_max和hashsize的值。
    echo $HASHSIZE > /sys/module/nf_conntrack/parameters/hashsize
    echo $CONNTRACK_MAX > /proc/sys/net/nf_conntrack_max
    # 以上2句其实可以被/etc/modprobe.d/nf_conntrack.conf的配置取代
    
    # 注意:conntrack所使用的内存(字节数)size_of_mem_used_by_conntrack = CONNTRACK_MAX * sizeof(struct ip_conntrack) + HASHSIZE * sizeof(struct list_head)
    # 但是,sizeof(struct ip_conntrack) 会因为内核版本、系统架构、编译设置等等因素而不同。
    # 如果要准确获得这个值,需要观察内核日志信息中,ip_conntrack初始化时的信息。
    # 比如,对于CentOS 5.2 64位版本,sizeof(struct ip_conntrack) 是304字节。
    # 然后,sizeof(struct list_head) = 2 * 指针字节数,如果是64位系统,指针占8个字节
    # 因此,conntrack所使用的内存 = CONNTRACK_MAX * 304 + HASHSIZE * 8 (字节).
    # 按本例子的262144和65536,即 80216064 字节,76.5M内存。
    
    # 如果定义的数量太大,比如1048576,会导致操作系统使用vmalloc来分配内存。而vmalloc分配的内存不是核心内存,可能会产生内存交换、物理地址不连续、强制对齐到内存页等问题。从而影响性能。
    # 本文不讨论Linux核心对内存的分配使用机制,有兴趣可以参考:
    # https://www.kernel.org/doc/html/latest/vm/index.html
    # https://hammertux.github.io/slab-allocator
    
    # 4. 对网络界面设置
    
    for x in ${INTERFACES}
    do
      # 禁止所有网络界面的spoofing
      echo 1 > /proc/sys/net/ipv4/conf/${x}/rp_filter
        # 优化网卡发送接收队列长度
        # 可以进一步考虑,把这个脚本调整为通过 ethtool -g em1 这样的命令获取可以设置的最大值(即命令参数中的2047、511等值)去设置。不过一般情况下,手工获取一次然后修改设置到这个脚本,也就足够了。
      ethtool -G ${x} rx 2047 tx 511
      ip link set dev ${x} txqueuelen 2047
    done
    

    欢迎关注微信公众号后私信讨论文章内容!
    本栏目相关
  •  2013-09-04 Windows Server 2008 重命名域和域控制器
  •  2015-05-11 解决Windows Server 2008 R2域控制器显示无法连接到Internet
  •  2010-01-25 Linux 下的分区调整工具GParted实战
  •  2009-04-17 如何在Seamonkey上安装VMWare Server 2.0的客户机Console
  •  2020-02-27 服务器热加硬盘、热转RAID模式,配合LINUX卷操作实现不重启服务器完成扩容
  •  2008-04-17 万恶的UAC功能增加了许多麻烦
  •  2022-02-24 如何安装使用 Broadcom RAID卡命令行管理工具 StorCLI(或称PercCLI)?
  •  2022-02-25 Linux 软路由网络吞吐优化设置
  •  2022-03-02 关于 SystemRescueCD/GParted 的使用技巧连载(硬盘分区知识篇)