11.13. 调整内核限制

11.13.1. 文件/进程限制

11.13.1.1. kern.maxfiles

kern.maxfiles 可以根据系统的需求加大或者减小。 这个变量指出了在系统上文件描述符的最大数量。当文件描述符表曼的时候, 用 dmesg 命令可以看到 ``file: table is full'' 将会在系统信息缓存里反复的出现。

每个打开的文件、套接字、fifo 都使用一个描述符。 一个大规模的服务器很容易使用上千个文件描述符, 这取决于系统中同时运行着的服务的数量和类型。

kern.maxfile 的默认值以系统配置文件中的 MAXUSERS 选项来决定。kern.maxfilesMAXUSERS 的值成比例的增长。编译一个自定义内核的时候, 按照您系统中用户的数量来设置这个值是个好主意。 从这个数字可以确定内核很多先前定义的限制。即使一台机器不会真有 256 个用户同时连接,所需要的资源也可能跟一个高负荷的 web 服务器差不多。

Note: 像是 FreeBSD 4.5,在您的内核配置中设置 MAXUSERS 为会通过系统中内存的数量来选择一个合适的值。

11.13.1.2. kern.ipc.somaxconn

kern.ipc.somaxconn sysctl 变量 限制了接收新 TCP 连接侦听队列的大小。对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。 大多数环境这个值建议增加到 1024 或者更多。 服务进程会自己限制侦听队列的大小(例如 sendmail(8) 或者 Apache), 常常在它们的配置文件中有设置队列大小的选项。 大的侦听队列对防止拒绝服务 DoS 攻击也会有所帮助。

11.13.2. 网络限制

NMBCLUSTERS 内核配置选项指出了系统可用的网络Mbuf的数量。 一个高流量的服务器使用一个小数目的网络缓存会影响 FreeBSD 的性能。 每个 cluster 可能需要2K内存,所以一个1024的值需要在内核中给网络缓存保留2M内存。 可以用简单的方法计算出来需要多少网络缓存。 如果您有一个同时发生1000个以上连接的web服务器, 并且每个连接用掉16K接收和发送缓存, 就需要大概32M网络缓存来确保web服务器的工作。 一个好的简单计算方法是乘以2,所以2x32Mb/2Kb=64MB/2kb=32768。 我们建议在有大量内存的机器上把这个值设置在4096到32768之间。 没有必要把它设置成任意太高的值,它会在启动时引起崩溃。 netstat(1)-m 选项可以用来观察网络cluster使用情况。

kern.ipc.nmbclusters 可以用来在启动时刻调节这个。 仅仅在旧版本的 FreeBSD 需要使用 NMBCLUSTERS config(8) 选项。

经常使用 sendfile(2) 系统调用的繁忙的服务器, 有必要通过 NSFBUFS 内核选项或者在 /boot/loader.conf (查看 loader(8) 以获得更多细节) 中设置它的值来调节 sendfile(2) 缓存数量。 这个参数需要调节的普通原因是在进程中看到 sfbufa 状态。sysctl kern.ipc.nsfbufs 变量在内核配置变量中是只读的。 这个参数是由 kern.maxusers 决定的,然而它可能有必有因此而调整。

Important: 即使一个套接字被标记成非阻塞,在这个非阻塞的套接字上呼叫 sendfile(2) 可能导致 sendfile(2) 呼叫阻塞直到有足够的 struct sf_buf 可用。

11.13.2.1. net.inet.ip.portrange.*

net.inet.ip.portrange.* sysctl 变量自动的控制绑定在 TCP 和 UDP 套接字上的端口范围。 这里有三个范围:一个低端范围,一个默认范围和一个高端范围。 大多数网络程序分别使用由 net.inet.ip.portrange.firstnet.inet.ip.portrange.last 控制的从 1024 到 5000 的默认范围。端口范围用作对外连接,并且某些情况可能用完系统的端口, 这经常发生在运行一个高负荷 web 代理服务器的时候。 这个端口范围不是用来限制主要的例如 web 服务器进入连接或者有固定端口例如邮件传递对外连接的。 有时您可能用完了端口,那就建议适当的增加 net.inet.ip.portrange.last1000020000 或者 30000 可能是适当的值。 更改端口范围的时候也要考虑到防火墙。一些防火墙会阻止端口的大部分范围 (通常是低范围的端口)并且用高端口进行对外连接(--)。 基于这个问题建议把 net.inet.ip.portrange.first 设置的小一点。

11.13.2.2. TCP 带宽迟延(Bandwidth Delay Product)

限制 TCP 带宽延迟和 NetBSD 的 TCP/Vegas 类似。 它可以通过将 sysctl 变量 net.inet.tcp.inflight.enable 设置成 1 来启用。 系统将尝试计算每一个连接的带宽延迟积, 并将排队的数据量限制在恰好能保持最优吞吐量的水平上。

这一特性在您的服务器同时向使用普通调制解调器, 千兆以太网, 乃至更高速度的光与网络连接 (或其他带宽延迟积很大的连接) 的时候尤为重要, 特别是当您同时使用滑动窗缩放, 或使用了大的发送窗口的时候。 如果启用了这个选项, 您还应该把 net.inet.tcp.inflight.debug 设置为 0 (禁用调试), 对于生产环境而言, 将 net.inet.tcp.inflight.min 设置成至少 6144 会很有好处。 然而, 需要注意的是, 这个值设置过大事实上相当于禁用了连接带宽延迟积限制功能。 这个限制特性减少了在路由和交换包队列的堵塞数据数量, 也减少了在本地主机接口队列阻塞的数据的数量。在少数的等候队列中、 交互式连接,尤其是通过慢速的调制解调器,也能用低的 往返时间操作。但是,注意这只影响到数据发送 (上载/服务端)。对数据接收(下载)没有效果。

调整 net.inet.tcp.inflight.stab 推荐的。 这个参数的默认值是 20, 表示把 2 个最大包加入到带宽延迟积窗口的计算中。 额外的窗口似的算法更为稳定, 并改善对于多变网络环境的相应能力, 但也会导致慢速连接下的 ping 时间增长 (尽管还是会比没有使用 inflight 算法低许多)。 对于这些情形, 您可能会希望把这个参数减少到 15, 10, 或 5; 并可能因此而不得不减少 net.inet.tcp.inflight.min (比如说, 3500) 来得到希望的效果。 减少这些参数的值, 只应作为最后不得已时的手段来使用。

Note: 对于 4.X 和更早的 FreeBSD 版本, inflight sysctl 变量直接隶属于 net.inet.tcp。 它们的名字是 (按字母顺序): net.inet.tcp.inflight_debugnet.inet.tcp.inflight_enablenet.inet.tcp.inflight_maxnet.inet.tcp.inflight_minnet.inet.tcp.inflight_stab