Python with Nginx

CGI (Common Gateway Interface) 的设计初衷:

用来作为 Web Server 同 Python, PHP 等的通信手段。而在静态网页的时代, 只需要 Web Server 即可。

CGI 的定义:

CGI is the protocal that describs the  way information is exchanged between the web server (如 Nginx) and the gateway application (PHP, Python, and so on.)

CGI 的缺点:

1. 每个请求都会产生一个对应的 gateway application 进程。从一个请求到另一个请求, 内存和上下文信息会丢失。无法 cache 来提高效率。

2. 大负载能力不足。对系统而言,启动一个进程非常耗资源。大量的并发请求(每个请求启动一个进程)会瞬间搞跨服务器。

3. 将 web server, gateway application 部署到不同服务器上的愿望难以实现。

FastCGI (Fast Common Gateway Interface):

也就是说 FastCGI 同 CGI 一样都是一个协议, 而不是一个具体实现。

flup 才是具体实现?

Microsoft IIS 也有一个 FastCGI 的实现。

http://www.iis.net/download/fastcgi

FastCGI 相对于 CGI 的改进:

1. 反复重用一个进程来处理多个请求, 而不是每个请求产生一个进程。

例如, 在 IIS FastCGI 中有这样两个特性:

a. Configurable maximum number of FastCGI processers per application pool.

b. Configurable maximum number of requests that FastCGI process can handle before being recycled by FastCGI.

2. Web Server 与 Gateway Application 通过 TCP 或者 POSIX local IPC sockets 通信。所以这些进程能够位于不同的主机上。

3. The web server forwards the client request to the gateway and receives the response within a single connection.

4. Since FastCGI is a socket-based protocol, it can be implemented on any platform with any programming language.

The FastCGI module is included in the default Nginx build, you do not need to enable it manually at compile time.

2010-11-16

fastcgi_read_timeout

设置 Nginx 从 FastCGI application 或者回复的超时时间。如果超时, 返回 504 Gateway Timeout HTTP error.

fastcgi_connect_timeout

与 read timeout 的区别是:

read timeout 是已经连上 fastcgi server 才开始计时。 connect timeout 是未连接状态的计时。

fastcgi_store

以文件的形式缓存 FastCGI app 的返回结果。 on/off.  默认是 off.

fastcgi_temp_path

指定 fastcgi_store 的缓存文件的存放目录, 存放在内存盘 /tmp 是一个好的选择, 快。。。

FastCGI caching

fastcgi_cache

定义一个 cache zone, 以便复用。

fastcgi_cache_key

不同 cache 得以区分的标识, 通常以请求地址标志。


fastcgi_cache 与 fastcgi-store 的区别是什么呢?

官网:

To be clear fastcgi_store is not a cache, it's rather mirror on demand.

官网对于 fastcgi_cache 的定义:

The directive specifies the area which actually is the share memory's name for caching. The same can be used in several places.

一个显著的区别是:

fastcgi_cache 是在使用内存, 而 fastcgi store 是在使用文件。 而这个cache 是所有进程都共用么?

<Nginx HTTP Server> 对于 directive 的解释明显不如官网详细。

Upstream Blocks

常见的问题是: FastCGI app 非常耗费系统资源, 尤其在 CPU 的使用方面。这时就需要增加 Backend Server 以做负载均衡。

upstream module 就是用来做此配置的:

例如:

upstream phpfpm{

    server 192.168.0.50:9000;

    server 192.168.0.51:9000;

    server 192.168.0.52:9000;

}

之后在配置 FastCGI 时, 连接 upstream block.

server{

    server_name website.com;

    location ~* \.php${

       fastcgi_pass phpfpm;

       [....]

   }

}

upstream module is round robin. 循环法

当一个用户发送两次请求, 就会被分发到不同的 backend 上, 就会造成资源无法复用。

可以改成:

upstream phpfpm{

    ip_hash;

    server 192.168.0.50:9000;

    ....;

}

如果想对不同的 Backend 设置不同的权重:

upstream php{

    server 192.168.0.1:9000 weight=2;

    server 192.168.0.2:9000;

}

在 ip_hash mode 下权重参数无效。

flup library, which provides the actual FastCGI protocol implementation.

对于 CentOS, EPEL 必须添加上。

RHEL:

yum install python-flup

这样默认安装的是 2.4.。。

还是使用 python2.6 的 easy_install flup 才搞定。

(下的 flup 2.6 egg 居然不能执行。)

Debian:

apt-get install python-flup

python manage.py runfcgi method=prefork host=127.0.0.1 port=9000 pidfile=/var/run/django.pid

runfcgi 的几个参数介绍:

protocol:

可选值为 fcgi, scgi, ajp, .... 默认为 fcgi, 即 FastCGI

host:

hostname to listen on.

port:

prot to listen on.

method:

prefork or threaded (default prefork)

网上说:

prefork 内存占用量大, threaded 内存需要量小。

prefork 在超大负载是仍然可以很好的工作, threaded 在大负载时常常无法响应。

在一个 Apache 的博客中找到一个可能的解释:

prefork 相当于使用 进程处理每个请求, 而 threaded 是每个子进程再产生一定量的 线程来处理请求。

pidfile:

write the spawned process-id to this file.

一个成功的配置:

location / {
            root   html;
            index  index.html index.htm;
            fastcgi_pass 127.0.0.1:9000;
#            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
#            include fastcgi_params;
        }
 

修改完之后需要 reload nginx:

/usr/local/nginx/sbin/nginx -s reload

猜你喜欢

转载自zhongwei-leg.iteye.com/blog/812210