http://www.cnblogs.com/wylhome/p/6057198.html http://tengine.taobao.org/book/chapter_02.html http://blog.csdn.net/justin_yaphet/article/details/47910439
Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由Igor Sysoev为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。 html
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler使用。其特色是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。 前端
Nginx能够在大多数 UnixLinux OS上编译运行,并有Windows移植版。 Nginx 的1.4.0稳定版已经于2013年4月24日发布,2016年10月18日,Nginx1.10.2 稳定版本发布。通常状况下,对于新建站点,建议使用最新稳定版做为生产版本,已有站点的升级急迫性不高。Nginx 的源代码使用2-clause BSD-like license。linux
通常是指局域网内部的机器经过代理服务器发送请求到互联网上的服务器,代理服务器通常做用在客户端。 nginx
一个完整的代理请求过程为:客户端首先与代理服务器建立链接,接着根据代理服务器所使用的代理协议,请求对目标服务器建立链接、或者得到目标服务器的指定资源。 Web代理(proxy)服务器是网络的中间实体。 代理位于Web客户端和Web服务器之间,扮演“中间人”的角色。HTTP的代理服务器便是Web服务器又是Web客户端。 web
代理服务器是介于客户端和Web服务器之间的另外一台服务器,有了它以后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,信号会先送到代理服务器,由代理服务器来取回浏览器所须要的信息并传送给你的浏览器。apache
是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),而后代理向原始服务器转交请求并将得到的内容返回给客户端。客户端必需要进行一些特别的设置才能使用正向代理。编程
在服务器端接受客户端的请求,而后把请求分发给具体的服务器进行处理,而后再将服务器的响应结果反馈给客户端。Nginx就是其中的一种反向代理服务器软件。 vim
说明:客户端必须设置正向代理服务器,固然前提是要知道正向代理服务器的IP地址,还有代理程序的端口。 后端
反向代理正好与正向代理相反,对于客户端而言代理服务器就像是原始服务器,而且客户端不须要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将得到的内容返回给客户端。
用户A始终认为它访问的是原始服务器B而不是代理服务器Z,但实用际上反向代理服务器接受用户A的应答,从原始资源服务器B中取得用户A的需求资源,而后发送给用户A。因为防火墙的做用,只容许代理服务器Z访问原始资源服务器B。尽管在这个虚拟的环境下,防火墙和反向代理的共同做用保护了原始资源服务器B,但用户A并不知情。centos
跨平台:Nginx 能够在大多数 Unix like OS编译运行,并且也有Windows的移植版本。
配置异常简单:很是容易上手。配置风格跟程序开发同样,神通常的配置
非阻塞、高并发链接:数据复制时,磁盘I/O的第一阶段是非阻塞的。官方测试可以支撑5万并发链接,在实际生产环境中跑到2~3万并发链接数.(这得益于Nginx使用了最新的epoll模型)
事件驱动:通讯机制采用epoll模型,支持更大的并发链接。
高并发:Nginx 是一个很强大的高性能Web和反向代理服务器,它具备不少很是优越的特性。在链接高并发的状况下,Nginx是Apache服务器不错的替代品,可以支持高达 50,000 个并发链接数的响应。
负载均衡器:Nginx做为负载均衡服务器:Nginx 既能够在内部直接支持 Rails 和 PHP 程序对外进行服务,也能够支持做为 HTTP代理服务器对外进行服务。
代理服务器:Nginx自己就是一个反向代理服务器,可支持邮件服务器代理以及http代理
1.轻量级,一样起web 服务,比apache 占用更少的内存及资源
2.抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能
3.高度模块化的设计,编写模块相对简单
4.配置简洁易懂,正则配置让不少事情变得简单
对于一个基本的web服务器来讲,事件一般有三种类型,网络事件、信号、定时器。
首先看一个请求的基本过程:创建链接—接收数据—发送数据 。
再次看系统底层的操做 :上述过程(创建链接—接收数据—发送数据)在系统底层就是读写事件。
(1)若是采用阻塞调用的方式,当读写事件没有准备好时,必然不可以进行读写事件,那么久只好等待,等事件准备好了,才能进行读写事件。那么请求就会被耽搁 。阻塞调用会进入内核等待,cpu就会让出去给别人用了,对单线程的worker来讲,显然不合适,当网络事件越多时,你们都在等待呢,cpu空闲下来没人用,cpu利用率天然上不去了,更别谈高并发了 。
(2)既然没有准备好阻塞调用不行,那么采用非阻塞方式。非阻塞就是,事件,立刻返回EAGAIN, 告诉你,事件还没准备好呢,你慌什么,过会再来吧。好吧,你过一会,再来检查一下事件,直到事件准备好了为止,在这期间,你就能够先去作其它事情,而后再 来看看事件好了没。虽然不阻塞了,但你得不时地过来检查一下事件的状态,你能够作更多的事情了,但带来的开销也是不小的
小结:非阻塞经过不断检查事件的状态来判断是否进行读写操做,这样带来的开销很大。
(3)所以才有了异步非阻塞的事件处理机制。具体到系统调用就是像select/poll/epoll/kqueue这样的系统调用。他们提供了一种机制,让你能够同时监控多个事件,调用他们是阻塞的,但能够设置超时时间,在超时时间以内,若是有事件准备好了,就返回。这种机制解决了咱们上面两个问题。
以epoll为例:当事件没有准备好时,就放入epoll(队列)里面。若是有事件准备好了,那么就去处理;若是事件返回的是EAGAIN,那么继续将其放入epoll里面。从而,只要有事件准备好了,咱们就去处理她,只有当全部时间都没有准备好时,才在epoll里 面等着。这样,咱们就能够并发处理大量的并发了,固然,这里的并发请求,是指未处理完的请求,线程只有一个,因此同时能处理的请求固然只有一个了,只是在 请求间进行不断地切换而已,切换也是由于异步事件未准备好,而主动让出的。这里的切换是没有任何代价,能够理解为循环处理多个准备好的事件
(4)与多线程的比较:
与多线程相比,这种事件处理方式是有很大的优点的,不须要建立线程,每一个请求占用的内存也不多,没有上下文切换,事件处理很是的轻量级。并发数再多也不会致使无谓的资源浪费(上下文切换)。
小结:经过异步非阻塞的事件处理机制,Nginx实现由进程循环处理多个准备好的事件,从而实现高并发和轻量级。
master/worker结构:一个master进程,生成一个或多个worker进程
内存消耗小:处理大并发的请求内存消耗很是小。在3万并发链接下,开启的10个Nginx 进程才消耗150M内存(15M*10=150M) 成本低廉:Nginx为开源软件,能够无偿使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则须要十多万至几十万人民币
内置的健康检查功能:若是 Nginx Proxy 后端的某台 Web 服务器宕机了,不会影响前端访问。
节省带宽:支持 GZIP 压缩,能够添加浏览器本地缓存的 Header 头。
稳定性高:用于反向代理,宕机的几率微乎其微。
Nginx在启动后,在Unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。咱们也能够手动地关掉后台模式,让Nginx在前台运行,而且经过配置让Nginx取消master进程,从而可使Nginx以单进程方式运行。很显然,生产环境下咱们确定不会这么作,因此关闭后台模式,通常是用来调试用的,Nginx是以多进程的方式来工做的,固然Nginx也是支持多线程的方式的,只是咱们主流的方式仍是多进程的方式,也是Nginx的默认方式。Nginx采用多进程的方式有诸多好处。
Nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常状况下),会自动从新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是能够设置的,通常咱们会设置与机器cpu核数一致,这里面的缘由与Nginx的进程模型以及事件处理模型是分不开的。Nginx的进程模型,能够由下图来表示:
master进程会接收来自外界发来的信号,再根据信号作不一样的事情。因此咱们要控制Nginx,只须要经过kill向master进程发送信号就好了。好比kill -HUP pid,则是告诉Nginx,从容地重启Nginx,咱们通常用这个信号来重启Nginx,或从新加载配置,由于是从容地重启,所以服务是不中断的。master进程在接收到HUP信号后是怎么作的呢?首先master进程在接到信号后,会先从新加载配置文件,而后再启动新的worker进程,并向全部老的worker进程发送信号,告诉他们能够光荣退休了。新的worker在启动后,就开始接收新的请求,而老的worker在收到来自master的信号后,就再也不接收新的请求,而且在当前进程中的全部未处理完的请求处理完成后,再退出。固然,直接给master进程发送信号,这是比较老的操做方式,Nginx在0.8版本以后,引入了一系列命令行参数,来方便咱们管理。好比,./nginx -s reload,就是来重启Nginx,./nginx -s stop,就是来中止Nginx的运行。如何作到的呢?咱们仍是拿reload来讲,咱们看到,执行命令时,咱们是启动一个新的Nginx进程,而新的Nginx进程在解析到reload参数后,就知道咱们的目的是控制Nginx来从新加载配置文件了,它会向master进程发送信号,而后接下来的动做,就和咱们直接向master进程发送信号同样了。
worker进程之间是平等的,每一个进程,处理请求的机会也是同样的。当咱们提供80端口的http服务时,一个链接请求过来,每一个进程都有可能处理这个链接。每一个worker进程都是从master进程fork过来,在master进程里面,先创建好须要listen的socket(listenfd)以后,而后再fork出多个worker进程。全部worker进程的listenfd会在新链接到来时变得可读,为保证只有一个进程处理该链接,全部worker进程在注册listenfd读事件前抢accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该链接。当一个worker进程在accept这个链接以后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开链接,这样一个完整的请求就是这样的了。一个请求,彻底由worker进程来处理,并且只在一个worker进程中处理。
对于每一个worker进程来讲,独立的进程,不须要加锁,因此省掉了锁带来的开销,同时在编程以及问题查找时,也会方便不少。其次,采用独立的进程,可让互相之间不会影响,一个进程退出后,其它进程还在工做,服务不会中断,master进程则很快启动新的worker进程。固然,worker进程的异常退出,确定是程序有bug了,异常退出,会致使当前worker上的全部请求失败,不过不会影响到全部请求,因此下降了风险。
nginx的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每一个模块的功能相对简单,便于开发,同时也便于对系统进行功能扩展。为了便于描述,下文中咱们将使用nginx core来称呼nginx的核心功能部分。
nginx提供了web服务器的基础功能,同时提供了web服务反向代理,email服务反向代理功能。nginx core实现了底层的通信协议,为其余模块和nginx进程构建了基本的运行时环境,而且构建了其余各模块的协做基础。除此以外,或者说大部分与协议相关的,或者应用相关的功能都是在这些模块中所实现的。
nginx将各功能模块组织成一条链,当有请求到达的时候,请求依次通过这条链上的部分或者所有模块,进行处理。每一个模块实现特定的功能。例如,实现对请求解压缩的模块,实现SSI的模块,实现与上游服务器进行通信的模块,实现与FastCGI服务进行通信的模块。
有两个模块比较特殊,他们居于nginx core和各功能模块的中间。这两个模块就是http模块和mail模块。这2个模块在nginx core之上实现了另一层抽象,处理与HTTP协议和email相关协议(SMTP/POP3/IMAP)有关的事件,而且确保这些事件能被以正确的顺序调用其余的一些功能模块。
目前HTTP协议是被实如今http模块中的,可是有可能未来被剥离到一个单独的模块中,以扩展nginx支持SPDY协议。
nginx使用一个多进程模型来对外提供服务,其中一个master进程,多个worker进程。master进程负责管理nginx自己和其余worker进程。
全部实际上的业务处理逻辑都在worker进程。worker进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个nginx服务被中止。
worker进程中,ngx_worker_process_cycle()函数就是这个无限循环的处理函数。在这个函数中,一个请求的简单处理流程以下:
1.操做系统提供的机制(例如epoll, kqueue等)产生相关的事件。
2.接收和处理这些事件,如是接受到数据,则产生更高层的request对象。
3.处理request的header和body。
4.产生响应,并发送回客户端。
5.完成request的处理。
6.从新初始化定时器及其余事件。
[root@localhost ~]# yum -y groupinstall "Development Tools" "Server Platform Development" 安装开发包组
[root@localhost ~]# yum -y install pcre-devel openssl-devel zlib-devel #安装依赖包
[root@localhost ~]# useradd -r nginx # 建立nginx系统用户
[root@localhost~]#./configure--prefix=/usr/local/nginx--conf-path=/etc/nginx/nginx.conf--error-log-path=/var/log/nginx/error.log--http-log-path=/var/log/nginx/access.log--pid-path=/var/run/nginx.pid--lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio # 配置nginx
[root@localhost ~]# make #编译
[root@localhost ~]# make install #安装或设置链接官网的yum源(官网地址http://nginx.org/packages/cen...)
[root@localhost ~]#vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx
baseurl=http://nginx.org/packages/cen...
gpgcheck=0
[root@localhost ~]#yum install nginx
[root@localhost ~]#systemctl start nginx.service
也可从本地epel直接安装
[root@localhost ~]#yum install nginx
[root@localhost ~]#systemctl start nginx.service
修改欢迎页面
[root@nginx1 /etc/nginx]#mkdir /data/nginx/vhost1 -pv
[root@nginx1 /etc/nginx]#vim /data/nginx/vhost1/index.html
<h1>Nginx Vhost 1</h1>
[root@nginx1 /etc/nginx]#vim conf.d/vhost1.conf
server {
listen 80;#监听80端口 server_name www.ilinux.io;#主机名为www.ilinux.io root /data/nginx/vhost1;#路径
}
[root@nginx1 /etc/nginx]#nginx -t
[root@nginx1 /etc/nginx]#nginx -s reload#重载配置文件
[root@nginx1 /etc/nginx]#vim /etc/hosts
172.16.254.127 www.ilinux.io
主配置文件:nginx.conf
include conf.d/*.conf
fastcgi, uwsgi,scgi等协议相关的配置文件
mime.types:支持的mime类型
主程序文件:/usr/sbin/nginx
Unit File:nginx.service
nginx配置文件组成:主配置文件nginx.conf,conf.d/*.conf;
fastcgi,uwsgi,scgi等协议相关的配置文件;
mime.types:支持的mime类型
分类:
正常运行必备的配置
优化性能相关的配置
用于调试及定位问题相关的配置
事件驱动相关的配置
一、user # 指定用于运行worker进程时的用户
Syntax: user user [group]; Default:user nobody nobody; Context: main
二、pid /PATH/TO/PID_FILE; # 指定存储nginx主进程进程号码的文件路径
Syntax: pid file; Default:pid nginx.pid; Context:main
三、include file | mask; # 指明包含进来的其它配置文件片段
Syntax: include file | mask; Default:— Context:any
四、load_module file; # 指明要装载的动态模块
Syntax: load_module file; Default:— Context:main
一、worker_processes number | auto; # worker进程的数量;一般应该为当前主机的cpu的物理核心数
Syntax: worker_processes number | auto; Default:worker_processes 1; Context:main
若是只有两个进程
[root@localhost /etc/nginx]#nginx -t
[root@localhost /etc/nginx]#nginx -s reload
![图片上传中...]
[root@localhost /etc/nginx]#nginx -t
[root@localhost /etc/nginx]#nginx -s reload
二、worker_cpu_affinity cpumask …; # 定义worker进程和cpu的绑定
worker_cpu_affinity auto [cpumask]; Default:— Context:main CPU MASK: 00000001:0号CPU 00000010:1号CPU 00000100: 2号CPU … …
绑定cpu,默认次序0、一、二、3
[root@localhost /etc/nginx]#nginx -t
[root@localhost /etc/nginx]#nginx -s reload
反向绑定cpu,三、二、一、0
[root@localhost /etc/nginx]#nginx -t
[root@localhost /etc/nginx]#nginx -s reload
三、worker_priority number; # 指定worker进程的nice值,设定worker进程优先级;[-20,20]
Syntax: worker_priority number; Default:worker_priority 0; Context:main
默认优先级
[root@localhost /etc/nginx]#ps axo comm,pid,psr,ni | grep nginx
nginx 4795 2 0
nginx 43059 3 0 优先级为0
nginx 43060 2 0 优先级为0设定优先级
[root@localhost /etc/nginx]#nginx -t
[root@localhost /etc/nginx]#nginx -s reload
[root@localhost /etc/nginx]#ps axo comm,pid,psr,ni | grep nginx
nginx 4795 2 0
nginx 43361 3 -5 优先级为-5
nginx 43362 2 -5 优先级为-5四、worker_rlimit_nofile number; # worker进程所可以打开的文件数量上限
Syntax: worker_rlimit_nofile number; Default:— Context:main
[root@localhost /etc/nginx]#vim nginx.conf
一、daemon on|off; # 是否以守护进程方式运行Nignx
Syntax: daemon on | off; Default:daemon on; Context:main
二、master_process on|off; # 是否以master/worker模型运行nginx;默认为on
Syntax: master_process on | off; Default:master_process on; Context:main
三、error_log file [level]; # 定义错误日志文件路径与级别
Syntax: error_log file [level]; Default:error_log logs/error.log error; Context:main, http, mail, stream, server, location
events { … }
一、worker_connections number; # 每一个worker进程所可以打开的最大并发链接数数量
Syntax: worker_connections number; Default:worker_connections 512; Context:events worker_processes * worker_connections得出最大并发链接数
二、use method; # 指明并发链接请求的处理方法
Syntax: use method; Default:— Context:events use epoll;
三、accept_mutex on | off; # 处理新的链接请求的方法;on意味着由各worker轮流处理新请求,Off意味着每一个新请求的到达都会通知全部的worker进程;建议使用on
Syntax: accept_mutex on | off; Default:accept_mutex off; Context:events
main block:主配置段,也即全局配置段;
event {
…
}:事件驱动相关的配置;
http {
…
}:http/https 协议相关的配置段;
mail {
…
}
stream {
…
}
http {
... ...:各server的公共配置 server { ... }:每一个server用于定义一个虚拟主机; server { ... listen server_name root alias location [OPERATOR] URL { ... if CONDITION { ... } } }
}