6.13. 调整内核限制

6.13.1. 文件/进程限制

6.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 为会通过系统中内存的数量来选择一个合适的值。

6.13.1.2. kern.ipc.somaxconn

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

6.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 可用。

6.13.2.1. net.inet.ip.portrange.*

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

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

The TCP Bandwidth Delay Product Limiting 类似于 NetBSD 的TCP/Vegas。它可以通过设置 net.inet.tcp.inflight_enable sysctl 变量为 1 来启动。系统将会为每个连接尝试带宽迟延并且限制发送到网络中的队列中的数据数量以维持适当的吞吐量。 similar to TCP/Vegas in NetBSD. It can be enabled by setting net.inet.tcp.inflight_enable sysctl variable to 1. The system will attempt to calculate the bandwidth delay product for each connection and limit the amount of data queued to the network to just the amount required to maintain optimum throughput.

如果你在使用调制解调器,千兆以太网或者高速的广域网连接(或者其他有高的带宽迟延的产品)提供数据服务,这个特性就会很有用。特别是你在使用窗口缩放或者配置一个大的发送窗口。如果启用了这个选项,童谣要确信设置 net.inet.tcp.inflight_debug0(关闭调试),对于生产用来说,设置 net.inet.tcp.inflight_min 至少为 6144 可能会受益。然而,注意设置一个高的最小值能有效的关闭依赖连接的带宽限制。这个限制特性减少了在路由和交换包队列的堵塞数据数量,也减少了在本地主机接口队列阻塞的数据的数量。在少数的等候队列中、交互式连接,尤其是通过慢速的调制解调器,也能用低的 往返时间操作。但是,注意这只影响到数据发送(上载/服务端)。对数据接收(下载)没有效果。

调整 net.inet.tcp.inflight_stab被建议的。这个参数的默认值是20,它代表两个最大的包被添加到带宽迟延窗口考虑。另外的窗口是稳定算法和改善改变条件时的应答所需要的,但是它也能导致通过慢速连接产生高的ping时间(虽然比你不用这个算法还慢)。这些情况下,你可能想试着把这个参数减小到15,10或者5;并且也可能需要减小 net.inet.tcp.inflight_min(例如3500)来达到效果。减少这些参数应该是最后的唯一手段。