使用Nginx提升网站访问速度

本文主要介绍Linux系统安装HTTP服务器——Nginx、并在不改变原有网站结构的条件下用Nginx来提升网站的访问速度。

Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。Igor 将源代码以类BSD许可证的形式发布。尽管还是测试版,但是,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。

根据最新一期(08年6月份)的NetCraft调查报告显示,已经有超过两百万的主机使用了Nginx,这个数字超过了另外一个轻量级的HTTP服务器lighttpd, 排名第四,并且发展迅速。下面是这份报告的前几名的报表:

产品 网站数
Apache 84,309,103
IIS 60,987,087
Google GFE 10,465,178
Unknown 4,903,174
nginx 2,125,160
Oversee 1,953,848
lighttpd 1,532,952

关于这期调查报告的更详细信息请看下面链接:

http://survey.netcraft.com/Reports/200806/

下图是最近几个月使用Nginx和lighttpd的网站数比较

使用Nginx前必须了解的事项

1. 目前官方Nginx并不支持Windows,你只能在包括Linux、UNIX、BSD系统下安装和使用;

2. Nginx本身只是一个HTTP和反向代理服务器,它无法像Apache一样通过安装各种模块来支持不同的页面脚本,例如PHP、CGI等;

3. Nginx支持简单的负载均衡和容错

4. 支持作为基本HTTP服务器的功能,例如日志、压缩、Byte ranges、Chunked responses、SSL、虚拟主机等等,应有尽有。

在Linux下安装Nginx

为了确保能在Nginx中使用正则表达式进行更灵活的配置,安装之前需要确定系统是否安装有PCRE(Perl Compatible Regular Expressions)包。你可以到 ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ 下载最新的PCRE源码包,使用下面命令下载编译和安装PCRE包:

# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.7.tar.gz
# tar zxvf pcre-7.7.tar.gz
# cd pcre-7.7
# ./configure
# make
# make install

接下来安装Nginx,Nginx一般有两个版本,分别是稳定版和开发版,你可以根据你的目的来选择这两个版本的其中一个,下面把Nginx安装到/opt/nginx目录下的详细步骤:

# wget http://sysoev.ru/nginx/nginx-0.6.31.tar.gz
# tar zxvf nginx-0.6.31.tar.gz
# cd nginx-0.6.31
# ./configure --with-http_stub_status_module –prefix=/opt/nginx
# make
# make install

其中参数--with-http_stub_status_module 是为了启用nginx的NginxStatus功能,用来监控Nginx的当前状态。

安装成功后/opt/nginx目录下有四个子目录分别是:conf、html、logs、sbin。其中Nginx的配置文件存放于conf/nginx.conf,Nginx只有一个程序文件位于sbin目录下的nginx文件。确保系统的80端口没被其他程序占用,运行 sbin/nginx 命令来启动Nginx,打开浏览器访问此机器的IP,如果浏览器出现Welcome to nginx! 则表示Nginx已经安装并运行成功。

常用的Nginx参数和控制

1.程序运行参数

Nginx安装后只有一个程序文件,本身并不提供各种管理程序,它是使用参数和系统信号机制对Nginx进程本身进行控制的。Nginx的参数包括有如下几个:

-c <path_to_config> 使用指定的配置文件而不是conf目录下的nginx.conf。

-t 测试配置文件是否正确,在运行时需要重新加载配置的时候,此命令非常重要,用来所修改的配置文件没有语法错误。

-v 显示nginx版本号。

-V 显示nginx的版本号以及编译环境信息以及编译时的参数。

例如我们要测试某个配置文件是否书写正确,我们可以使用以下命令

sbin/nginx –t –c conf/nginx2.conf

2.通过信号对Nginx进行控制

Nginx支持下表中的信号:

信号名 作用描述
TERM, INT 快速关闭程序,中止当前正在处理的请求
QUIT 处理完当前请求后,关闭程序
HUP 重新加载配置,并开启新的工作进程,关闭就的进程,此操作不会中断请求
USR1 重新打开日志文件,用于切换日志,例如每天生成一个新的日志文件
USR2 平滑升级可执行程序
WINCH 从容关闭工作进程

有两种方式来通过这些信号去控制Nginx,第一是通过logs目录下的nginx.pid查看当前运行的Nginx的进程ID,通过 kill –XXX <pid> 来控制Nginx,其中XXX就是上表中列出的信号名。如果你的系统中只有一个Nginx进程,那你也可以通过killall命令来完成,例如运行killall –s HUP nginx 来让Nginx重新加载配置。

配置Nginx

先来看一个实际的配置文件:

user  nobody;#工作进程的属主 
worker_processes  4;#工作进程数,一般与CPU核数等同 
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    use epoll;#Linux下性能最好的event模式 
    worker_connections  2048;#每个工作进程允许最大的同时连接数 
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] $request '
    #                  '"$status" $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  off;
    access_log  logs/access.log;#日志文件名 

    sendfile        on;
    #tcp_nopush     on;
    tcp_nodelay     on;

    keepalive_timeout  65;

    include gzip.conf;
            
    #集群中的所有后台服务器的配置信息 
    upstream tomcats {
        server 192.168.0.11:8080 weight=10; 
        server 192.168.0.11:8081 weight=10;
        server 192.168.0.12:8080 weight=10;
        server 192.168.0.12:8081 weight=10;
        server 192.168.0.13:8080 weight=10; 
        server 192.168.0.13:8081 weight=10;
    }

    server {
        listen       80;#HTTP的端口 
        server_name  localhost;

        charset utf-8;

        #access_log  logs/host.access.log  main;

        location ~ ^/NginxStatus/ {
            stub_status on; #Nginx状态监控配置 
            access_log off;
        }

        location ~ ^/(WEB-INF)/ {
            deny all;
        }

        location ~* \.(htm|html|asp|php|gif|jpg|jpeg|png|bmp|ico|rar|css|js|zip|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ {
            root /opt/webapp;
            expires 24h;
        }

        location / {
            proxy_pass http://tomcats;#反向代理 
            include proxy.conf;
        }

        error_page 404 /html/404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page 502 503 /html/502.html;
        error_page 500 504 /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

Nginx监控

上面是一个实际网站的配置实例,其中灰色文字为配置说明。上述配置中,首先我们定义了一个location ~ ^/NginxStatus/,这样通过http://localhost/NginxStatus/就可以监控到Nginx的运行信息,显示的内容如下:

Active connections: 70 
server accepts handled requests
14553819 14553819 19239266 
Reading: 0 Writing: 3 Waiting: 67 
NginxStatus显示的内容意思如下:
active connections – 当前Nginx正处理的活动连接数
server accepts handled requests --总共处理了 14553819 个连接, 成功创建 14553819 次握手 (证明中间没有失败的), 总共处理了 19239266 个请求 (平均每次握手处理了 1.3个数据请求)
reading -- nginx 读取到客户端的Header信息数
writing -- nginx 返回给客户端的Header信息数
waiting -- 开启 keep-alive 的情况下,这个值等于 active - (reading + writing),意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接

静态文件处理

通过正则表达式,我们可让Nginx识别出各种静态文件,例如images路径下的所有请求可以写为:

    location ~ ^/images/ {
        root /opt/webapp/images;
    }

而下面的配置则定义了以几种文件类型的请求处理方式。

location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|ico|css|js|txt)$ {
    root /opt/webapp;
    expires 24h;
}

对于例如图片、静态HTML文件、js脚本文件和css样式文件等,我们希望Nginx直接处理并返回给浏览器,这样可以大大的加快网页浏览时的速度。因此对于这类文件我们需要通过root指令来指定文件的存放路径,同时因为这类文件并不常修改,通过expires指令来控制其在浏览器的缓存,以减少不必要的请求。expires指令可以控制HTTP应答中的“Expires”和“Cache-Control”的头标(起到控制页面缓存的作用)。你可以使用例如以下的格式来书写Expires

expires 1 January, 1970, 00:00:01 GMT;
expires 60s;
expires 30m;
expires 24h;
expires 1d;
expires max;
expires off;

动态页面请求处理

Nginx本身并不支持现在流行的JSP、ASP、PHP、PERL等动态页面,但是它可以通过反向代理将请求发送到后端的服务器,例如Tomcat、Apache、IIS等来完成动态页面的请求处理。前面的配置示例中,我们首先定义了由Nginx直接处理的一些静态文件请求后,其他所有的请求通过proxy_pass指令传送给后端的服务器(在上述例子中是Tomcat)。最简单的proxy_pass用法如下:

location / {
    proxy_pass        http://localhost:8080;
    proxy_set_header  X-Real-IP  $remote_addr;
}

这里我们没有使用到集群,而是将请求直接送到运行在8080端口的Tomcat服务上来完成类似JSP和Servlet的请求处理。

当页面的访问量非常大的时候,往往需要多个应用服务器来共同承担动态页面的执行操作,这时我们就需要使用集群的架构。Nginx通过upstream指令来定义一个服务器的集群,最前面那个完整的例子中我们定义了一个名为tomcats的集群,这个集群中包括了三台服务器共6个Tomcat服务。而proxy_pass指令的写法变成了:

location / {
    proxy_pass        http://tomcats;
    proxy_set_header  X-Real-IP  $remote_addr;
}

在Nginx的集群配置中,Nginx使用最简单的平均分配规则给集群中的每个节点分配请求。一旦某个节点失效时,或者重新起效时,Nginx都会非常及时的处理状态的变化,以保证不会影响到用户的访问。

总结

尽管整个程序包只有五百多K,但麻雀虽小、五脏俱全。Nginx官方提供的各种功能模块应有尽有,结合这些模块可以完整各种各样的配置要求,例如:压缩、防盗链、集群、FastCGI、流媒体服务器、Memcached支持、URL重写等等,更关键的是Nginx拥有Apache和其他HTTP服务器无法比拟的高性能。你甚至可以在不改变原有网站的架构上,通过在前端引入Nginx来提升网站的访问速度。

本文只是简单介绍了Nginx的安装以及常见的基本的配置和使用,更多关于Nginx的信息请阅读文章后面的参考资源。在这里要非常感谢我的朋友——陈磊(chanix@msn.com),他一直在做着 Nginx的中文WIKI(http://wiki.codemongers.com/NginxChs),同时也是他介绍给我这么好的一款软件。

如果你的网站是运行在Linux下,如果你并没有使用一些非常复杂的而且确定Nginx无法完成的功能,那你应该试试Nginx。

参考资源

· Nginx英文站点:http://www.nginx.net

· Nginx中文WIKI:http://wiki.codemongers.com/NginxChs

· Nginx英文WIKI:http://wiki.codemongers.com/Main

· 另外一个轻量级HTTP服务器lighttpd: http://www.lighttpd.net/

· 最新版本Nginx下载地址:http://sysoev.ru/nginx/nginx-0.6.31.tar.gz

· PCRE下载地址:ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/

发表评论