Freebsd内核的http请求过滤器

Freebsd在2000年的时候就有这个功能,他的作用是前端过滤未完整的http请求,将完整的http请求转发给后端app server(Apache)。

原文:

 accf_http -- buffer incoming connections until a certain complete HTTP
     requests arrive

目的有两个:
1、  也许后面根本没有HTTP请求过来;
2、  请求不完整,属于非法请求;

这样,Apache将派生很多的子进程(假设为prefork模式)去处理这些也许没有用的(可能是SYN FLOOD)连接,最后进程数满,Apache不堪重负。

FreeBSD实现的接收过滤器明确的延迟了accpet()的返回,只有当满足了一定的条件后,比如一个完整的HTTP/1.0或者HTTP /1.1 HEAD或者GET请求完全被FreeBSD内核缓存之后才返回。HEAD和GET之外的其他请求仍然直接有accpet()进程处理。这样后续的读写 socket操作就不需要等待客户端的请求数据。因此,每个Apache就能处理更多的有效连接。也可以使子进程在accpet()返回后立即处理请求, 因为这个HTTP请求已经建立而且可以read(),这样就减少了Apache进程在执行初始的请求解析(解析HTTP请求)前,执行过多的上下文切换 (Context Switch).  FreeBSD通过accf_http和accf_data(kldload accf_http)来实现接收过滤,Apache相关配置语法为AcceptFilter protocol accept_filter,如

AcceptFilter http httpready
AcceptFilter https dataready

httpready接收过滤器(Accept Filter)在内核级别缓冲整个HTTP请求。一旦一个请求体被完整接收,内核将把它发送给服务器。因为HTTPS请求已经被加密了,所以只使用了 accf_data(9)过滤器。 注:FreeBSD 6.1必须载入这个模块才能启动Apache2.2,FreeBSD6.2及后续版本不管是否加载这个模块都可以启动Apache,默认不加载,可以在 /etc/rc.conf中加入:apache22_http_accept_enable=”YES”进行启动时自动加载。

Linux上的默认值是:
AcceptFilter http data
AcceptFilter https data

Linux的TCP_DEFER_ACCEPT并不支持对http请求进行缓冲。除none之外的任何值都将在监听程序上启用 TCP_DEFER_ACCEPT 。参见tcp(7)手册页以获得更多详情。使用none将会为那个协议禁用接收过滤器(accept filter)。这对于像nntp这样需要服务器先发送数据的协议很有用处:
AcceptFilter nttp none

NetScaler似乎也使用了同样的思想,只将真正的HTTP请求数据发送给后端服务器,而之前的3次TCP握手都由NetScaler本身处理,大大提升了服务器的吞吐量。

在FreeBSD中启用此功能的方法:

The accf_http kernel option is also a module that can be enabled at run-
     time via kldload(8) if the	INET option has	been compiled into the kernel.
#kldload accf_http并将/boot/defaults/loader.conf中,以便下次启动自动装载模块

accf_data_load=”YES”
accf_http_load=”YES”   改了这一个就可以启动了。

 

评论关闭。