快速入门

------------------------

关于Nginx,我们可以到其官网 http://nginx.org/  以及WIKI http://wiki.nginx.org 进行下载和了解。

我们可以看一下下面的英文介绍:

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%。

【我们可以通过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非常轻量级,编译安装的过程非常快。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
tar -xf nginx-1.6.2.tar.gz
cd nginx-1.6.2
groupadd -r nginx
useradd -r -g nginx nginx
./configure \
--prefix=/usr/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/tmp/nginx/client/ \
--http-proxy-temp-path=/var/tmp/nginx/proxy/ \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi/ \
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi/ \                      
--http-scgi-temp-path=/var/tmp/nginx/scgi/ \
--with-pcre
make
make install

可以发现,在编译中,我们指定了nginx的owner,group为我们新建的系统用户和组。

需要指定一些临时目录路径,并确保在启动NGINX时,这些临时目录是存在,否则可能启动出错。

由于Nginx是基于模块化的方式设计的,所以我们需要清楚哪些模块是默认编译安装的?

./configure --help的方式,可以获得这些信息,如果是with-somemodule,说明这个module默认是不编译的,要想使用,必须显式的使用with;如果是without-somemodule,说明这个module默认是编译的,不想编译的话,必须显式的使用without。

在安装过程中,很可能遇到缺少一些软件包,直接利用YUM的方式安装即可。

启动Nginx

根据编译时指定的可执行命令路径,

1
2
cd /usr/sbin
./nginx

即可启动Nginx

查看监听端口:

1
2
3
[root@localhost sbin]# netstat -tnlp | grep 80
tcp  0   0 0.0.0.0:80       0.0.0.0:*                LISTEN     28238/nginx         
[root@localhost sbin]#

我们也可以通过浏览器或者直接curl的方式访问Nginx为我们提供的首页。

我们的主战场:nginx.conf

配置文件分析

------------------------

worker_processes表示启动WORKER进程的个数,而worker_connections表示每个WORKER进程最多可以处理的连接。那么,我们最多支持的连接数 为  worker_processes * worker_connections。上面的,都是全局的配置。

下面,我们重点分析的是http段的server配置。

1
2
3
4
5
6
7
8
9
10
11
12
server{
listen port;
server_name YOUR_SERVER_NAME;
location [=|^~|~|~*] uri {
    root YOUR_FILE_PATH;
    index index.html index.jsp index.htm;
    autoindex on|off;
    deny SOMEIP/SOMEUSER;
    allow SOMEIP/SOMEUSER;
}
error_page 404 uri;
}

指令以分号结束。

每一个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页面了。

看下面的一个实例配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
              listen 81;
              server_name localhost;
              location /bbs {
                root /web/;
                index index.html;
       
              }
              location /sports {
                root /web/;
                index index.html;
       
              }
          }

在/web目录下有bbs,sports目录

1
2
3
4
[root@www ~]# curl http://192.168.204.88:81/bbs/index.html
<h1>hello,bbs</h1>
[root@www ~]# curl http://192.168.204.88:81/sports/index.html
<h1>hello,sports</h1>

也就是说,root/uri的方式共同定位到文件资源的路径。

访问控制法则

基于IP地址的(deny/allow形式,注意默认情况下是allow all的)

基于用户/密码的(auth_basic 采用htpasswd生成用户密码文件即可)

在location中可以 autoindex on 来列出文件

在SERVER段中,可以通过定义如下location来在网页上显示NGINX的状态信息

1
2
3
4
5
6
7
8
9
location /nginx-status {
            stub_status on;
            access_log off;   #不记录日志
}
[root@www ~]# curl http://192.168.204.88/nginx-status
Active connections: 1 
server accepts handled requests
 9 9 14 
Reading: 0 Writing: 1 Waiting: 0

说明:

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:

1
2
3
4
location /bbs {
             proxy_pass   http://www.zfz1.com:8080;
             index  index.html index.htm;
}

apache虚拟主机配置:

1
2
3
4
5
6
<VirtualHost 192.168.204.88:8080>
    DocumentRoot /web/
    ServerName   www.zfz1.com 
    ErrorLog logs/www.zfz1.com-error_log
    CustomLog logs/www.zfz1.com-access_log common
</VirtualHost>

/etc/hosts配置:

1
192.168.204.88 www.zfz1.com

/web/bbs/index.html:

1
<h1>hello,apache's bbs</h1>

验证:

1
2
3
[root@www nginx]# curl http://www.zfz1.com/bbs/index.html
<h1>hello,apache's bbs</h1>
[root@www nginx]#

从配置上,其实反向代理就是在location中用proxy_pass取代了root而已。

关于access_log的说明:

由于,我们使用了反向代理,Apache接收到的请求都是来自nginx的,那么access_log中记录的IP等信息其实都是nginx的信息,这样显然不是我们想要的,我们希望日志中记录的是真实的客户端信息,这样以后有利于我们进行日志分析。

其实,请求会在nginx这一端进行封装,我们可以自定义一些http header,比如:

1
2
3
4
5
location  /bbs {
     
    proxy_pass http://ip:port;
    proxy_set_header YOUR_HEADER_NAME $XXX;
}

$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。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upstream backend {
    ip_hash;
    server backend1.example.com;
    server ba.ck.en.d2:port weight=x;
    server backend3.example.com max_fails=3 fail_timeout=30s;
    #server 127.0.0.1 backup;
}
server {
    ...
    location / {
       proxy_pass http://backend;
    }
    ...
}

在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方面的东西,学习了下,写出来和大家分享,如果理解上有错误,欢迎大家留言指正~

本文出自 “学海无涯 心境无限” 博客,请务必保留此出处http://zhangfengzhe.blog.51cto.com/8855103/1597009

Nginx介绍及原理简单分析相关推荐

  1. 岭回归原理简单分析与理解

    岭回归原理简单分析与理解 首先说明一下,岭回归用于回归.学习岭回归,给我的感受是,它的数学公式推导比较简单,然而理解其含义相对难一些,所以本文着重引导你去理解它,而不仅仅是会推导公式.至于背景介绍,网 ...

  2. Nginx介绍和原理

    文章目录 nginx介绍 nginx的特性 nginx的优点 nginx的基本功能 nginx的应用类别 nginx模块分类 nginx的工作原理 nginx介绍 nginx是一款轻量级的Web服务器 ...

  3. DWM1000 测距原理简单分析 之 SS-TWR

    蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: DWM1000 超宽带测距,使用的TOF(time of fly) 的方式,也就是计算无线电磁波传输时 ...

  4. DWM1000 测距原理简单分析 之 SS-TWR代码分析2 -- [蓝点无限]

    蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 首先将SS 原理介绍中的图片拿过来,将图片印在脑海里. 对于DeviceA 和 DeviceB来说,初 ...

  5. 慢慢学Linux驱动开发,第四篇,USB工作原理简单分析

    1.简单概念 学习U盘驱动,不仅仅是去关注drivers/usb/storage目录下那相关的3000行代码. 毕竟,作为U盘,她需要与usb core打交道,需要与scsi core打交道,需要与内 ...

  6. Dubbo原理简单分析

    1.Dubbo原理分析 alibaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo.hsf),jms消息服务(napoli.notify),KV数据库(tair ...

  7. java lock park_java并发编程-LockSupport中park与unpark基本使用与原理简单分析

    文章目录 java并发编程原理之---park与unpark 基本使用 情况一,先park再unpark,代码举例与分析 情况二,先unpark再park,代码举例与分析 特点 原理之park &am ...

  8. Flink教程(05)- Flink原理简单分析

    文章目录 01 引言 02 Flink角色 03 Flink执行流程 3.1 Standalone版本 3.2 on yarn 04 Flink Streaming Dataflow 4.1 Flin ...

  9. 送给那些经常问我如何设置360测速结果为电信的朋友,360测速模块原理简单分析...

    自从上次告诉大家把api.ip.360.cn指向电信线路,或者重定向,就会改变360的测速结果. 可能是后面360更新了,自然对新的360不一定生效,具体由于我没有双线路,没有测试哦~~~~最主要的是 ...

最新文章

  1. mysql 查询用户最后登陆时间_弄懂mysql:mysql的通信协议
  2. Alpha版验收通过
  3. 【读书笔记-数据挖掘概念与技术】分类:高级方法
  4. 最优化算法python实现篇(2)—无约束一维极值(二分法)
  5. 台湾大学林轩田机器学习基石课程学习笔记15 -- Validation
  6. 几种简单的排序算法(JAVA)
  7. fastdfs上传文件时报错No route to host
  8. 自学python到什么程度就可以工作-自学Python爬虫学到什么程度?就可以去找工作了?...
  9. win10跳过计算机密码,win10开机密码忘了怎么办
  10. 关于js的match用法
  11. latex 编译缺少STXingkai字体
  12. 零跑汽车冲刺港股:年营收31亿 去年曾募资88亿
  13. 公司禁用QQ,破解方法(洋葱tor 安装配置)
  14. 黑苹果教程(二)自己制作cdr、dmg镜像
  15. python错误:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb5 in position 0: invalid start byte
  16. 【自动化办公】python批量替换word中的内容
  17. 入行数据科学,这些书一定要看
  18. JAVAEE 实训日志 一
  19. 数字人民币解决中小企收付难点
  20. 基站网口损坏检查方法

热门文章

  1. 深入JVM-垃圾回收
  2. cmd怎么实现隐藏DOS窗口运行程序
  3. 绕圈圈面试题(Python经典编程案例)
  4. docker加载镜像报错 dockerError processing tar file(exit status 1): no space left on device
  5. 微信备份到云服务器失败怎么回事,iCloud云备份失败是为什么呢?iCloud云备份启用失败如何解决...
  6. redis的多路复用原理
  7. 共享文件夹无法打开——服务器存储空间不足,无法处理此命令
  8. (转载)SAP第三方销售实现方法
  9. 个人计算机有ip地址吗,如何查看ip? 查看个人电脑IP地址五大方法
  10. 鸿蒙归蝶的反弹,诛仙鸿蒙副本怎么过