最近评论

nginx源代码分析

Nginx可以开启多个进程,每个进程拥有最大上限128个子线程以及一定的可用连接数。如果你希望使用线程可以在配置文件中设置worker_threads这个参数,但这个参数在Nginx官方手册上没有。只有通过阅读源代码才看到。最大客户端连接数等于进程数与连接数的乘积,连接是在主进程中初始化的,一开始所有连接处于空闲状态。
每一个客户端请求进来以后会通过事件处理机制,在Linux是Epoll,在FreeBSD下是KQueue放到空闲的连接里。
如果设置了线程数,那么被填充的连接会在子线程中处理,否则会在主线程中依次处理。
如果解析出是动态脚本请求,会根据fast-cgi的设置访问php-cgi进程,php进程数量的多少依据php-fpm.conf中max_children的设置。
因此Nginx的动态请求能力不仅仅依靠Nginx本身的设置,还要调试php-fpm。
从源代码级别上看nginx由以下几个元素组成:
1. worker(进程)
2. thread(线程)
3. connection(连接)
4. event(事件)
5. module(模块)
6. pool(内存池)
7. cycle(全局设置)
8. log(日志)
大概就这些元素组成的。
整个程序从main()开始算
    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }
这几句比较关键,对加载的模块点一下数,看有多少个。ngx_modules并不是在原代码中被赋值的,你先执行一下./configure命令生成用于编译的make环境。在根目录会多出来一个文件夹objs,找到ngx_modules.c文件,默认情况下nginx会加载大约30个模块,的确不少,如果你不需要那个模块尽量还是去掉好一些。
接下来比较重要的函数是 ngx_init_cycle(),这个函数初始化系统的配置以及网络连接等,如果是多进程方式加载的会继续调用ngx_master_process_cycle(),这是main函数中调用的最关键的两个函数。
ngx_init_cycle()实际上是个复杂的初始化函数,首先是加载各子模块的配置信息、并初始化各组成模块。
任何模块都有两个重要接口组成,一个是create_conf,一个是init_conf。分别是创建配置和初始化配置信息。
模块按照先后顺序依次初始化,大概是这样的:
    &ngx_core_module,
    &ngx_errlog_module,
    &ngx_conf_module,
    &ngx_events_module,
    &ngx_event_core_module,
    &ngx_epoll_module,
    &ngx_http_module,
    &ngx_http_core_module,
    &ngx_http_log_module,
首先是内核模块、错误日志、配置模块、事件模块、时间内核模块、EPOLL模块、http模块、http内核模块、http日志模块,剩下的模块都算不上关键。
epoll是比较关键的核心模块之一,nginx兼容多种IO控制模型,memecached用的是libevent不如nginx彻头彻尾是自己实现的。
在ngx_init_cycle()中对模块初始化完毕后,调用ngx_open_listening_sockets()函数对socket进行了初始化。
在listen上80端口以后,调用模块的另外一个重要接口init_module对各模块进行初始化。
并不是每个模块都对init_module接口进行了定义,在比较重要的模块中仅有 ngx_http_log_module 对这个接口进行了定义。
ngx_init_cycle()返回后,主要的工作都是在ngx_master_process_cycle()函数中继续进行的。
ngx_master_process_cycle()函数中的重要过程有调用ngx_start_worker_processes()生成多个子进程,一般nginx是多进程的。
ngx_start_worker_processes()函数内部调用ngx_worker_process_cycle()函数建立每个进程的实际工 作内容,在这个函数中首先调用ngx_create_thread()初始化各线程。我们知道每个线程都有一个启动处理函数,nginx的线程处理函数为 ngx_worker_thread_cycle(),内部过程中最重要的是对ngx_event_thread_process_posted()函数 的调用,用于实际处理每一次请求。
在初始化线程结束后,首先调用ngx_process_events_and_timers()函数,该函数继续调用 ngx_process_events接口监听事件,一般情况下对应的函数是ngx_epoll_process_events(),如果使用的是其它种 类的IO模型,则应该实现相应的实际函数。这个接口负责把事件投递到ngx_posted_events事件队列里,并在 ngx_event_thread_process_posted()函数中进行处理。
nginx的connection和event是按照链表的方式进行存放的,区别在于connection是单向链表而event是双向链表。
nginx中的connection链表是提前分配的,定义在ngx_event_process_init()函数内,具体代码如下:
    …
   
    cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections,
                                   cycle->log);
    …
    i = cycle->connection_n;
    next = NULL;
    [...]

nginx源码目录结构、程序编译流程、如何构建学习nginx的环境

作者:张立冰
出处:http://www.libing.name/2009/02/27/understand-nginx-source-code-directory.html
本文主要简单介绍nginx源码目录结构、程序编译流程、如何构建学习nginx的环境等。
本文以及后续nginx源码分析文章是基于nginx当前(2009-02-27)的稳定版本0.6.35进行的分析,该版本的src目录下共有96615行代码,共记234个源码文件。
注:本系统的文章为本人学习做笔记用,为源码分析,而非模块的编写,可能会存在问题。
1.1 源码目录简述
nginx的源码目录结构层次明确,从自动编译脚本到各级的源码,层次都很清晰,是一个大型服务端软件构建的一个范例。以下是源码目录结构说明:

├─auto 自动编译安装相关目录
│ ├─cc 针对各种编译器进行相应的编译配置目录,包括Gcc、Ccc等
│ ├─lib 程序依赖的各种库,包括md5,openssl,pcre等
│ ├─os 针对不同操作系统所做的编译配置目录
│ └─types
├─conf 相关配置文件等目录,包括nginx的配置文件、fcgi相关的配置等
├─contrib
├─html [...]

NGINX 502 Bad Gateway 用upstream解决方法

NGINX 502 Bad Gateway错误以前遇到过,不过不是常发生,所以也没什么注意,不过今天在网上看到一个方法错误…

nginx的http session管理

http session,基本上可以认为就是我们平常所理解的完成GET或者POST请求的HTTP应用的TCP Session。

从自…

nginx php-fastcgi负载均衡

配置还是非常简单的,充分体现了nginx的强大与配置的简单^^下面是大致的服务器结构图:

应用的最前端是…

nginx php 在 daemontools 下运行, 永不当机配置

以下均为Linux 平台配置

1. 首先假设你已经可以使 nginx + php 在 fastcgi 模式下运行 (如果不会,请参考…

nginx启动关闭重启的shell脚本

#vi /etc/init.d/nginx
#! /bin/sh
### BEGIN INIT INFO
# Provides:           Nginx-php-fp…

nginx 502 bad故障原因及解决方法收集

如题,最近网站频繁出现502错误,简直无法正常运转,出现这种情况大多是php-cgi超时没有返回信息,或进程僵死等情况造成的,参考张宴的这篇关于502错误的解决办法(http://blog.s135.com/read.php?361),并咨询系统管理员高手,我们的nginx已经配置到极致这些都已经老早做过修改了,但现在又出然出现。
经过分析将nginx的error log打开,发现”pstream sent too big header while reading response header from upstream”这样的错误提示,查阅了一下资料,大意是nginx缓冲区有一个bug造成的,我们网站的页面消耗占用缓冲区可能过大。参考老外写的修改办法增加了缓冲区容量大小设置,502问题彻底解决,后来系统管理员又对参数做了调整只保留了2个设置参数:client head buffer,fastcgi buffer size。
参考:
http://www.sudone.com/nginx/nginx_400_bad_request.html
http://blog.rackcorp.com/?p=14
二、昨天装上nginx后在高负载的时候,论坛上传图片或者执行较长时间脚本的时候就不停的出现502 Bad Gateway ,网上搜了,大多数都是张大师的那篇解决方案,他的解决方案是
http
{
……
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
……
}
增加了fastcgi的相应请求时间。但是我在实际中碰到了这个问题,设置到500,还是会出现,只是比我设置120的时候要少一些。后来发现主要是在一些post或者数据库操作的时候出现这种情况,静态页面是不会出现的。
反复的查问题,调试,也加大了CGI的进程数。
128
256再加上去可能会变得很慢。占用内存大了。
在php-fpm.conf设置中还有一项,可能当时没注意到,无意中改了这个值。
request_terminate_timeout
这个值是max_execution_time,就是fast-cgi的执行脚本时间。
0s
0s为关闭,就是无限执行下去。(当时装的时候没仔细看就改了一个数字)
发现,问题解决了,执行很长时间也不会出错了。
优化fastcgi中,还可以改改这个值5s 。看看效果
终于发现502的错误其实不是nginx的问题,哈哈
php-cgi进程数不够用、php执行时间长、或者是php-cgi进程死掉,都会出现502错误
三、
一台服务器上运行着nginx php(fpm) xcache,访问量日均 300W pv左右
最近经常会出现这样的情况: php页面打开很慢,cpu使用率突然降至很低,系统负载突然升至很高,查看网卡的流量,也会发现突然降到了很低。这种情况只持续数秒钟就恢复了
检查php-fpm的日志文件发现了一些线索
Sep 30 08:32:23.289973 [NOTICE] fpm_unix_init_main(), line 271: getrlimit(nofile): max:51200, cur:51200
Sep 30 08:32:23.290212 [NOTICE] fpm_sockets_init_main(), line 371: using inherited socket fd=10, “127.0.0.1:9000″
Sep 30 08:32:23.290342 [NOTICE] [...]

强大的负载均衡+静态文件WEB服务器 nginx实战

  当前比较流行的负载均衡前端服务器主要有apache(with mod_proxy),nginx,lighttpd,squid,perlbal,pound,或者如果你的域名服务商提供DNS级别的负载均衡,也可以(就是一个域名随机指向多个IP,定制性不高)。
    以前自己常用pound作为前端,它专注于负载均衡,支持https协议,配置还算简单,不过渐渐发现功能不够强大,转而研究其他一些既可以做负载均衡,又能做web服务器的高性能工具吧。Perlbal是第一个看的,大牛Danga的杰作,它们开发的memcached(分布式内存cache系统)非常好用,Perlbal也不差,虽然是基于Perl的,速度上比纯C开发的可能稍逊,但不得不说Danga大牛实力非凡。不过公司的机器都是perl5.8.5,而Perlbal必须perl5.8.8以上,升级可能有兼容性问题,故只能作罢。
    转而研究nginx:Nginx (“engine X”) 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。Igor 将源代码以类BSD许可证的形式发布。尽管还是测试版,但是,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。 
    中文维基地址:http://wiki.codemongers.com/NginxChs
模块依赖:
1 gzip支持,需要zlib http://www.zlib.net/ 下载最新版即可
2 rewrite module requires pcre library http://www.pcre.org/ 下载最新版即可
3 ssl 功能需要 openssl 库 http://www.openssl.org/ => http://www.openssl.org/source/ LASTEST版本即可
 
安装过程:
#下载以上source到/usr/local/src/nginx/目录下,解压,则该目录下情况如下:
[root@s16 nginx]# ls
nginx-0.6.32  nginx-0.6.32.tar.gz  openssl-0.9.8i  openssl-0.9.8i.tar.gz  pcre-7.8  pcre-7.8.tar.gz  zlib-1.2.3  zlib-1.2.3.tar.gz
cd nginx-0.6.32
./configure –with-pcre=../pcre-7.8 –with-zlib=../zlib-1.2.3 –with-openssl=../openssl-0.9.8i
make
make [...]

apach htaccess 转换成 nginx rewrite rule

http://www.anilcetin.com/convert-apache-htaccess-to-nginx/