nginx应用总结(1)--基础认识和应用配置

转自:http://www.cnblogs.com/kevingrace/p/6095027.html

在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结。

一、nginx服务简介
Nginx是一个高性能的HTTP和反向代理服务器,也是一个 IMAP/POP3/SMTP代理服务器。Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。

使用 Nginx 前必须了解的事项:
1)目前官方 Nginx 并不支持 Windows,您只能在包括 Linux、UNIX、BSD 系统下安装和使用;
2)Nginx 本身只是一个 HTTP 和反向代理服务器,它无法像 Apache 一样通过安装各种模块来支持不同的页面脚本,例如 PHP、CGI 等;
3)Nginx 支持简单的负载均衡和容错;
4)支持作为基本 HTTP 服务器的功能,例如日志、压缩、Byte ranges、Chunked responses、SSL、虚拟主机等等,应有尽有。

Nginx工作原理:
Nginx由内核和一系列模块组成,内核提供web服务的基本功能,如启用网络协议,创建运行环境,接收和分配客户端请求,处理模块之间的交互。Nginx的各种功能和操作都由模块来实现。Nginx的模块从结构上分为核心模块、基础模块和第三方模块。
1)核心模块: HTTP模块、EVENT模块和MAIL模块
2)基础模块: HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块
3)第三方模块: HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块及用户自己开发的模块
这样的设计使Nginx方便开发和扩展,也正因此才使得Nginx功能如此强大。Nginx的模块默认编译进nginx中,如果需要增加或删除模块,需要重新编译Nginx,这一点不如Apache的动态加载模块方便。如果有需要动态加载模块,可以使用由淘宝网发起的web服务器Tengine,在nginx的基础上增加了很多高级特性,完全兼容Nginx,已被国内很多网站采用。

Nginx处理连接过程:
nginx不会为每个连接派生进程或线程,而是由 worker 进程通过监听共享套接字接受新请求,并且使用高效的循环来处理数千个连接。Nginx 不使用仲裁器或分发器来分发连接,这个工作由操作系统内核机制完成。监听套接字在启动时就完成初始化,worker 进程通过这些套接字接受、读取请求和输出响应。

Nginx的工作模式很简单,就是采用一个master进程和多个worker工作进程:
其中master进程的作用也是很明确的就是负责管理worker进程,同时监听连接请求,当连接请求到来之后将连接放入worker进程中去处理具体的业务请求,比如说http请求。 Nginx能够处理高并发的原因在于对socket的管理方式是异步非阻塞的,使用select/poll/epoll/kqueue 来实现对大量socket描述符的管理,每个worker进程有一个主线程,而没有其他的线程这样的好处就在于不需要进行线程间的切换,这样就节省了资源。所以总的来说:Nginx能够实现支持高并发的同时运行效率还很低的关键在于整个系统内部只有有限的几个工作进程和一个监听进程,而每个进程内部只有一个主线程,这样就不会引起很多的线程切换,从而降低了系统开销,同时每个线程内部使用异步非阻塞的方式来管理描述符这样就可以管理大量的描述符,当描述符多的时候也只是会占用较多的内存而已,而不会造成占用大量cpu时间。以上说的就是Nginx的进程模型和事件模型,事件模型中处理的情况主要有三种,分别是网络事件,如HTTP请求等,网络事件使用异步非阻塞模式就可以很好的解决;还有信号,定时器,信号和定时器还不是很明白。Nginx处理进程间争夺系统资源的方式:也就是进程间存在的惊群现象。

master:
当 nginx 在启动后,会有一个 master 进程和多个 worker 进程。master进程主要用来管理worker进程,master 要做的就是:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动重新启动新的 worker 进程。
主要完成如下工作:
1)读取并验证配置信息;
2)创建、绑定及关闭套接字;
3)启动、终止 worker 进程及维护 worker 进程的个数;
4)无须中止服务而重新配置工作;
5)控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本;
6)重新打开日志文件;
7)编译嵌入式perl脚本

worker:
对于基本的网络事件,则是放在 worker 进程中来处理了。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其它进程的请求(一对一)。然而 nginx 没有专门地仲裁或连接分布的 worker,这项工作是由操作系统内核机制完成的。在启动时,创建一组初始的监听套接字,HTTP 请求和响应之时,worker 连续接收、读取和写入套接字。
worker 进程主要完成的任务包括:
1)接收、传入并处理来自客户端的连接;
2)提供反向代理及过滤功能;
3)nginx任何能完成的其它任务

举例说明一个完整请求如何通过互相协作来实现的:
既然worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供80端口的http服务时,一个连接请求过来,每个进程都有可能处理这个连接。那么问题来了,到底最后怎样处理,是由什么决定的呢?首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listen 的 socket(listenfd)之后,然后再 fork 出多个 worker 进程。所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程会在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的那个进程注册 listenfd 读事件,然后在读事件里调用 accept 接受该连接。当一个 worker 进程在 accept 这个连接之后,就开始读取请求、解析请求、处理请求。产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。我们可以看到:一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。

也许有个疑问,那就是nginx采用多worker 的方式来处理请求,每个 worker 里面只有一个主线程,那能够处理的并发数很有限啊,多少个 worker 就能处理多少个并发,何来高并发呢?
然而,这就是 nginx 的高明之处,nginx 采用了异步非阻塞的方式来处理请求,也就是说,nginx 是可以同时处理成千上万个请求的。

异步非阻塞
异步的概念是和同步相对的,也就是不同事件之间不是同时发生的。非阻塞的概念是和阻塞对应的,阻塞是事件按顺序执行,每一事件都要等待上一事件的完成,而非阻塞是如果事件没有准备好,这个事件可以直接返回,过一段时间再进行处理询问,这期间可以做其他事情。

二、nginx相对于传统的apache服务的优缺点
nginx相对比apache,实在有太多的优势。可以说,现在Nginx才是Web服务器的首选!!
1)nginx相对于apache的优点:
轻量级,同样起web 服务,比apache 占用更少的内存及资源;
抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能;
高度模块化的设计,编写模块相对简单;
社区活跃,各种高性能模块出品迅速;
当然apache相对于nginx也有它自身的优点:rewrite比nginx 的rewrite强大;模块超多,基本想到的都可以找到;少bug,nginx的bug相对较多;超稳定;apache有自带php解析功能(apache环境部署好后,不需要再启动php服务,apache自动解析php文件,机器上只要有php命令即可;但是nginx不行,nginx必须结合php服务才能解析php文件,两则服务都要启动)

存在就是理由,一般来说,需要性能的web 服务,用nginx 。
如果不需要性能只求稳定,那就用apache。
后者的各种功能模块实现得比前者,例如ssl 的模块就比前者好,可配置项多。
这里要注意一点,epoll(freebsd 上是 kqueue )网络IO 模型是nginx 处理性能高的根本理由,但并不是所有的情况下都是epoll 大获全胜的,如果本身提供静态服务的就只有寥寥几个文件,apache 的select 模型或许比epoll 更高性能。当然,这只是根据网络IO 模型的原理作的一个假设,真正的应用还是需要实测了再说的。

2)作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。在高连接并发的情况下,Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 感谢Nginx为我们选择了 epoll and kqueue 作为开发模型.
Nginx作为负载均衡服务器: Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理 服务器对外进行服务. Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多.
作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器), Last.fm 描述了成功并且美妙的使用经验.
Nginx 是一个安装非常的简单 , 配置文件非常简洁(还能够支持perl语法), Bugs 非常少的服务器: Nginx 启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动. 你还能够不间断服务的情况下进行软件版本的升级 .
3)Nginx 配置简洁,Apach复杂;Nginx静态处理性能比Apache高3倍以上;Apache对PHP支持比较简单,Nginx需要配合其他后端用;Apache的组件比Nginx多;
4)最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程
5)nginx处理静态文件好,耗费内存少.但apache目前也有它的优势,有很多丰富的特性.所以还需要搭配着来.当然如果能确定nginx就适合需求,那么使用nginx会是更经济的方式.
6)从个人过往的使用情况来看,nginx的负载能力比apache高很多。最新的服务器也改用nginx了。而且nginx改完配置能-t测试一下配置有没有问题,apache重启的时候发现配置出错了,会很崩溃,改的时候都会非常小心翼翼现在看有好多集群站,前端nginx抗并发,后端apache集群,配合的也不错。
7)nginx处理动态请求是鸡肋,一般动态请求要apache去做,nginx只适合静态和反向。
8)从个人经验来看,nginx是很不错的前端服务器,负载性能很好,linux服务器上运营nginx,用webbench模拟10000個个静态文件请求毫不吃力。apache对php等语言的支持很好,此外apache有強大的支持网路,反正时间相对nginx更久,bug少,但是apache有先天不支持多核心处理负载鸡肋的缺点,所以建议使用nginx做前端,后端用apache。大型网站建议用nginx自代的集群功能!
9)Nginx优于apache的主要两点还体现在:Nginx本身就是一个反向代理服务器;Nginx支持7层负载均衡;其他的当然,Nginx可能会比apache支持更高的并发;Aapche因为其成熟的技术和开发社区,总体来说也有非常不错的性能,很多大公司而言还比较青睐apache。
10)你对web server的需求决定你的选择。大部分情况下nginx都优于apache,比如说静态文件处理、PHP-CGI的支持、反向代理功能、前端Cache、维持连接等等。在Apache+PHP(prefork)模式下,如果PHP处理慢或者前端压力很大的情况下,很容易出现Apache进程数飙升,从而拒绝服务的现象。
11)对于nginx,我喜欢它配置文件写的很简洁,正则配置让很多事情变得简单运行效率高,占用资源少,代理功能强大,很适合做前端响应服务器
12)Apache在处理动态有优势,Nginx并发性比较好,CPU内存占用低,如果rewrite频繁,那还是Apache更好。

三、在 Linux 下安装 Nginx
为了确保能在Nginx中使用正则表达式进行更灵活的配置,安装之前需要确定系统是否安装有PCRE(Perl Compatible Regular Expressions)包。
您可以到ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/下载最新的PCR 源码包,使用下面命令下载编译和安装 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 参数和控制
程序运行参数
Nginx 安装后只有一个程序文件,本身并不提供各种管理程序,它是使用参数和系统信号机制对 Nginx 进程本身进行控制的。 Nginx 的参数包括有如下几个:
-c <path_to_config>:使用指定的配置文件而不是 conf 目录下的 nginx.conf 。
-t:测试配置文件是否正确,在运行时需要重新加载配置的时候,此命令非常重要,用来检测所修改的配置文件是否有语法错误。
-v:显示 nginx 版本号。
-V:显示 nginx 的版本号以及编译环境信息以及编译时的参数。
例如我们要测试某个配置文件是否书写正确,我们可以使用以下命令
sbin/nginx – t – c conf/nginx2.conf

---------------------------------------------------------------------------------------------
当一台服务器中启用多个实例的nginx时(即开启不同端口的nginx),那么启动nginx的时候就要根据各自的nginx配置文件进行启动了,比如:
/data/nginx/sbin/nginx  -c /data/nginx/conf/nginx.conf
/data/nginx1.9/sbin/nginx -c /data/nginx1.9/conf/nginx.conf
/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf

通过信号对 Nginx 进行控制
Nginx 支持下表中的信号:

有两种方式来通过这些信号去控制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 都会非常及时的处理状态的变化,以保证不会影响到用户的访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值