第一部分:
html
Nginx介绍及原理简单分析nginx
快速入门web ------------------------正则表达式
关于Nginx,咱们能够到其官网 http://nginx.org/ 以及WIKI http://wiki.nginx.org 进行下载和了解。算法
咱们能够看一下下面的英文介绍:apache
Nginx (pronounced engine-x) is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Igor Sysoev started development of Nginx in 2002, with the first public release in 2004. Nginx now hosts nearly12.18% (22.2M) of active sites across all domains. Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.后端
从上面的,咱们大概能够知道以下信息:浏览器
第一,Nginx是一个开源,免费的高性能HTTP服务器和HTTP/MAIL反向代理服务器。缓存
第二,自2004以来,Nginx的使用占比逐渐上升,目前大概占有WEB SERVER市场的12%。bash 【咱们能够经过http://www.netcraft.com/来看一下目前主流的WEB SERVER的使用趋势。】
第三,Nginx具备高性能,稳定性,丰富的特性,简单的配置,低资源占用等特色。
什么是正向代理/代理服务器 and 反向代理/反向代理服务器?
正向代理示意图:
反向代理示意图:
通俗点说,正向代理中的代理服务器比如“管家”,由这个“管家”帮你作事情,而反向代理中的反向代理服务器比如“秘书”,要想见领导必须经过“秘书”。 在正向代理中,客户机须要明确的知道“管家”的一些信息,如IP,PORT等;可是在反向代理中,客户请求的是“领导”,他并不知道在这过程当中“秘书”发挥了做用。
Nginx的工做模式及原理简单分析
同Apache http server的Perfork工做模型相似,Nginx也有master,worker进程的概念。
第一,很显然,启动Nginx,就必须在端口启动监听服务,也就是套接字(ip+port),一般Nginx做为WEB SERVER和反向代理服务器都会在80端口监听。在LINUX上,要开启<1024端口的监听服务,必须用特权身份运行,也就是说master进程应该以root身份启动。
第二,那么master进程主要的职责是什么?
读取并验证配置信息 建立,绑定,关闭套接字 启动,终止,维护worker进程的个数
master负责管理worker进程,这一点好理解,须要注意的是master在处理配置信息这一块。
假设nginx已经启动,咱们更改配置文件后reload,若是这个配置文件语法有误,nginx会怎么作? 若是这个配置文件OK,nginx又会怎么作?
若是配置文件有误,reload后,master会提示配置错误,并不会影响请求的处理。 若是配置文件OK,reload后,何时生效呢?
Nginx支持热部署!!!
若是主配置文件发生改变,那么并不会马上影响到WORKER进程,而是MASTER等到WORKER进程的链接请求处理完毕后KILL掉这个WORKER进程,而后从新生成一个WORKER进程,这样这个WORKER进程就将以新的配置启动了。也就是说,老的链接用老的配置,新的链接用新的配置。从新加载配置文件不会中断正在处理的请求。
第三,worker进程是干吗的?咱们应该有多少个Worker进程?每个Worker进程中有多少个线程?
在Nginx中,链接请求由为数很少的几个仅包含一个线程的进程worker以高效的回环机制进行处理,而每一个worker能够并行处理数千个的并发链接和请求。
Worker进程的个数,这个是能够配置的,可是通常而言,个数应该和CPU个数一致性,主要是为了CPU的进程切换。
what can worker process do ? 接受,传入并处理来自客户端的链接; 提供反向代理等功能;
第四,worker进程如何处理请求的?
当一个请求来了,那么多个worker进程,谁去处理,仍是几个一块儿处理?如何处理?
首先,要清楚的是,一个请求能够由一个worker进程处理并只能由这个worker进程彻底处理。 Nginx在内部实际上是维护了一个accept_mutex,其实就是一个锁,确保在某一时刻,一个请求只能被 一个worker进程捕获。当一个worker进程在accept这个链接以后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开链接,这样一个完整的请求就是这样的了。
Nginx采用了异步非阻塞事件驱动的方式来处理请求的,只要咱们设置好WORKER进程个数与CPU的亲缘性绑定,那么就能减小CPU在进程间切换所花费的时间以及切换带来的进程的保存/恢复现场,同时,因为Nginx中一个worker里面只有一个线程,也避免了线程的上下文切换。
第五,异步/非阻塞/事件驱动???
咱们知道,不少请求来了,他们大多须要读写数据,发生IO请求,此时程序就会发生中断,若是此时咱们一直等待IO调用结束,才继续工做,那么这种就是阻塞的,那么很显然不少请求来了,都处于等待状态,CPU就将处于空闲状态,为了提供高并发的能力,Nginx采用的是非阻塞的方式。若是发生IO中断,那么你去作你的事情,可是过一段时间来看看IO调用是否结束,这就是非阻塞:你能够作更多的事情,可是你得时不时的检查中断状态,带来的开销也不小。
为了更高效,Nginx利用了LINUX的EPOLL模型(其余系统相似): EPOLL模型,提供一种事件驱动机制,它能够监控多个事件是否准备好了,若是准备好了,那么就放入EPOLL队列中。这种机制是异步的。经过这样,WORKER进程只须要循环处理EPOLL队列中的请求,咱们只须要在请求间不断切换,而这种切换是不须要付出什么代价的,经过这种循环处理已经准备好的请求,从而Nginx能够高效的处理高并发的问题。
好了,到这里,咱们应该对Nginx的原理有些认识了,下面经过Nginx提供的一些具体功能来加深认识。
|
第二部分:
Nginx做为Web Server详解
安装与初步使用 ------------------------
咱们能够直接到NGINX的官网下载最新的稳定版,好比1.6.2。 Nginx很是轻量级,编译安装的过程很是快。
能够发现,在编译中,咱们指定了nginx的owner,group为咱们新建的系统用户和组。
须要指定一些临时目录路径,并确保在启动NGINX时,这些临时目录是存在,不然可能启动出错。
因为Nginx是基于模块化的方式设计的,因此咱们须要清楚哪些模块是默认编译安装的?
./configure --help的方式,能够得到这些信息,若是是with-somemodule,说明这个module默认是不编译的,要想使用,必须显式的使用with;若是是without-somemodule,说明这个module默认是编译的,不想编译的话,必须显式的使用without。
在安装过程当中,极可能遇到缺乏一些软件包,直接利用YUM的方式安装便可。
启动Nginx
根据编译时指定的可执行命令路径,
便可启动Nginx
查看监听端口:
咱们也能够经过浏览器或者直接curl的方式访问Nginx为咱们提供的首页。
咱们的主战场:nginx.conf
配置文件分析 ------------------------
worker_processes表示启动WORKER进程的个数,而worker_connections表示每一个WORKER进程最多能够处理的链接。那么,咱们最多支持的链接数 为 worker_processes * worker_connections。上面的,都是全局的配置。
下面,咱们重点分析的是http段的server配置。
指令以分号结束。 每个server用来定义一个虚拟主机,Nginx必须采用这样的方式来进行配置。 可见Nginx支持基于ServerName和Port的虚拟主机。 咱们须要重点理解和注意的是location中的uri配置:
location [ = | ~ | ~* | ^~ ] uri { ... }
说明location在支持uri方面,有以下形式:
location uri {} 对这个uri下面的全部路径(包括子路径)都有效 匹配范围很大
location = uri {} 只对当前路径生效,注意若是此uri是一个目录,那么并不会对这个目录下的有效,仅仅当这个uri是文件的时候才有效。 精确匹配到具体的文件路径,对目录无效
location ~ uri {} 模式匹配,就是正则 区分大小写 uri此时就是一个正则表达式
location ~* uri {} 同上,也是模式匹配,不区分大小写
location ^~ uri {} 不使用正则表达式
那么一个请求URL来了,匹配优先级是?
优先级从高到低 = ^~ ~和~* 不使用其余任何符号的
举个例子: http://servername:port/bbs/....
那么会首先寻找location = /bbs 的进行匹配,而后看不使用模式匹配的location ^~ uri可否匹配,如不匹配,继续看使用模式匹配的可否匹配location ~ uri / location ~* uri,若是模式匹配也不成功,那么看location uri是否包含这个路径,若是最后不包含这个路径,那么就是404页面了。
看下面的一个实例配置:
在/web目录下有bbs,sports目录
也就是说,root/uri的方式共同定位到文件资源的路径。
访问控制法则 基于IP地址的(deny/allow形式,注意默认状况下是allow all的) 基于用户/密码的(auth_basic 采用htpasswd生成用户密码文件便可)
在location中能够 autoindex on 来列出文件
在SERVER段中,能够经过定义以下location来在网页上显示NGINX的状态信息
说明: Active connections表示活动的链接数。 accepts/handled表示已经接受/处理的链接数 requests表示已经处理的请求。 【注意,在一个链接中,能够处理多个请求】 reading表示nginx reads request header writing表示nginx reads request body ,process request or writes response to a client waiting表示keep-alive connections,actually it is active (reading + writing)
/usr/sbin/nginx #启动Nginx /usr/sbin/nginx -t #检查nginx.conf配置文件是否有误 /usr/sbin/nginx -s reload #从新载入配置文件 /usr/sbin/nginx -s stop #中止nginx
到这里,Nginx的基本使用以及做为web server配置方面,就差很少了。
|
第三部分:
关于反向代理
作一个实验来讲明反向代理:
request -> nginx -> apache http://www.zfz1.com:80/bbs请求到达nginx,被反向代理到Apache上,经过虚拟主机的方式进行响应http://www.zfz1.com:8080/bbs
直接上配置:
nginx.conf:
apache虚拟主机配置:
/etc/hosts配置:
/web/bbs/index.html:
验证:
从配置上,其实反向代理就是在location中用proxy_pass取代了root而已。
关于access_log的说明:
因为,咱们使用了反向代理,Apache接收到的请求都是来自nginx的,那么access_log中记录的IP等信息其实都是nginx的信息,这样显然不是咱们想要的,咱们但愿日志中记录的是真实的客户端信息,这样之后有利于咱们进行日志分析。
其实,请求会在nginx这一端进行封装,咱们能够自定义一些http header,好比:
$XXX为Nginx内置的HTTP变量,好比:$remote_addr
这些内置的变量,咱们能够通官方文档来查阅:http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
利用proxy_set_header进行HTTP HEADER设置,那么咱们就能够在APACHE的LOGFORMAT中进行引用YOUR_HEADER_NAME了。这样日志中记录的就是咱们想要的信息。
|
第四部分:
关于负载均衡
咱们能够把后端的多个apache归并成一个组,还能够定义负载均衡法则。对于nginx而言,这些后端的APP SERVER,称为上游服务器,即upstream。
在upstream中,咱们能够定义多个server,每个server的定义不要加上协议,要么是IP+PORT,要么是SERVERNAME+PORT,利用weight的方式定义加权轮调。Nginx能够对上游服务器进行健康状态检查,若是上游服务器DOWN了,那么Nginx不在将请求链接给他,若是上游服务器又活了,那么让他处理链接请求。max_fails和fail_timeout能够定义健康状态检查。若是全部的上游服务器都挂了怎么办呢?server 127.0.0.1 backup就会起做用了。
有些时候,咱们必须未来自同一个客户端的请求定向到同一台后端服务器【保持SESSION会话】,ip_hash指令就是用来干这个的,根据客户端请求的源地址作HASH运算,只要HASH运算结果相同,那么就会一直分发到相同的上游服务器。
事实上,nginx支持三种负载均衡算法: 第一,加权轮调 round_robin 第二,IPHASH 第三,最少链接【挑一个链接数最少的上游服务器进行处理】least_conn
|
第五部分:
关于缓存
Nginx之全部有效的减轻了上游服务器的压力,是由于nginx的缓存机制。 nginx的缓存大概能够分为: 共享内存:存储键和缓存对象元数据。也就是说查找缓存,是在内存中完成的。 磁盘空间:存储数据。缓存数据最终也是在磁盘上的。
在http段中进行配置: proxy_cache_path /nginx/cache levles=1:2:1 keys_zone=first:20m max_size=1g
表示缓存目录位于/nginx/cache下,1:2:1表示会创建三级目录,第一级目录名称为1个字符,第二季目录名称为2个字符,第三级目录名称为1个字符。keys_zone=a:b用来讲明缓存在共享内存中的配置,a即表明名称,若是谁要使用缓存,就必须引用这个名称,b即表明内存大小。max_size用来定义磁盘缓存空间的最大大小。
在location段中明确开启缓存功能: proxy_cache first;
|
第六部分:
关于URL重写
Nginx中支持rewrite模块,并支持正则表达式,来进行URL的rewrite。
这里就不在介绍了,具体的使用方法,能够参考nginx的官方文档便可。
|
第七部分:
结束语
因为在项目中用到了一点nginx方面的东西,学习了下,写出来和你们分享,若是理解上有错误,欢迎你们留言指正~ |