
网站建设手机:增加Squid进程的FD限额
这里可见ngx_http_parse_header_line函数中的内部变量p保存了请求体的部分内容。
如果使用$$locals$,可以看到每次输出(实际就是ngx_http_parse—header.line读取请求体
的过程)p的内存地址自增一次,然后在某一时刻突然中断。我们计算自增数,就知道是
在请求体的第几个字节处发生问题了。
最后在这个出问题的请求的对应字节处发现了一个\0,引发了旧版本Nginx的
NGX_HTTP_PARSE_INVALID_HEADER判断。
1.3.8.3.5 增加Squid进程的FD限额
Squid在启动的时候,会根据当前shell的ulimit限制来设置自己的rlimit,默认情况
就是只能打开1024个FD。这在大流量的情况下显然是不够的。而Squid又不像Nginx那
样提供了配置参数,只能在启动前修改好当前登录shell的ulimit-这种操作显然是很容
易被遗忘的。因此我们应该通过自动化手段避免它。
但是无法避免的是已经启动的进程,这时候我们也可以想办法来修改。这里涉及较多
的源码流程,就不详细阐述了,只直接给出结果。
(1)在squid启动时,会将当前限额记录在Squid_MaxFD变量中;
第1章 服务器监测
(2)当FD不足时,会调用内核的socket来创建,这里socket需要检查当前的限额;
(3)不限额的话成功创建socket返回给squid;
(4) squid更新自己的另一个变量Biggest_FD,但在更新时会判断这个最新的fd是否
小于Squid_MaxFD;
(5)如果大于Squid_MaxFD了,依然报错。
所以我们需要从两方面入手,一方面修改已经运行的squid在调用socket时检测的系
统rlimit;另一方面修改Squid_MaxFD变量。
关于系统的部分,跟踪socket流程最后找到expand_files()函数,其中关于FD限额的
判断流程如下。
( 1) if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
( 2) if (nr < fdt->max_fds)
( 3 ) if (nr >= sysctl_nr_open)
以上都通过了才进入真正的expand_fdtable()。所以我们在这个函数里修改rlim cur
和rlim max,stp脚本如下。
%{
#include <linux/sched.h>
#include <linux/resource.h>
%}
probe kernel.function("expand_files@fs/file.c") .call {. '
if ( execname () -= "squid" ) {
if ( rlim_cur() < 65535 ) {
printf("Change statusi %d\n", set rlim(65535》 ;
function rlim _cur:long ()
%{
struct signal_struct *ss = kread( &<current->signal》; ;
TH工S-> retvalue = kread (& (ss->rlim[RLIMIT NOFILE] .rlim cur》 ;