Nginx

一、http相关知识

1.http的请求流程

①:建立tcp连接

②:web浏览器向web服务器发送请求

③:web浏览器发送请求头信息

    建立连接后,客户机发送一个请求给服务器,请求方式的格式:URL、version、MIME

④:web服务器响应

    响应格式:version status_code、MIME信息、body信息。

⑤:Web服务器向浏览器应答头部信息

⑥:Web服务器向浏览器发送数据

⑦:Web服务器关闭TCP连接

web页面:可能一次页面多个URL和资源请求、可能请求静态资源或动态资源

2.MPM 多路处理模型

①:prefork模型

    主进程开启子进程进行响应,每个子进程处理一个请求,子进程根据访问量大小进行调整

②:worker模型

    实现设置好开多少进程、每个进程开多少线程

③:event模型

worker模型的变种,把服务进程从连接中分离出来,开启keepalive场合下对worker模式承受更高的并发负载。

2d8f08c2cb294d75b8a4e14262c09b34.png

流程:客户端到服务端发送浏览器请求,本质上是获取对方的web数据。客户端要发起两次I/O,分别为网络请求I/O、服务器数据I/O(内核到用户据I/O)。首先网络请求I/O,发送TCP请求连接,其次把请求的数据发送到内核空间,内核空间进行预热识别,内核空间的内存就会有所消耗(每次请求就要调用I/O的进程数,无论是MPM哪个模块都会占据内核空间内存数),将内核空间磁盘中的web数据复制到用户空间;第四步:用户空间将数据进行处理,产生新的数据;如果对方请求是put数据,就要把数据copy到内核,然后存储到对应的磁盘中。最后在web服务进程,将处理数据封装成html响应报文,基于tcp套接字连接,返回给客户端。

二、I/O模型详解

1.I/O网络模型

c894f822900f4c78a48878c95cf922d7.png

6a8d0615e66e45ed843cda2b87fe52dd.png

2.Linux的I/O


        磁盘 1/O
        网络 1/O:一切皆文件,本质为对 socket 文件的读写

        磁盘I/O
        磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源比如是html 文件或者图片,然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间
        网络 I/O
        网络通信就是网络协议栈到用户空间进程的I/O就是网络I/O


        获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3)

        构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4)

        返回数据,服务器将已构建好的响应报文再通过内核空间的网络I/O发还给客户端(5-7)

        每次 I/O,都要经由两个阶段:

         第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长

         第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短

3.五种I/O模型:

        ①同步和异步

          关注的是消息通知机制

          同步:调用资源发出请求不会立即返回,但如果返回肯定是最终结果

          异步:调用资源发出,被调用方立即返回消息,但可能不是最终结果

        ②阻塞和非阻塞

        关注的是调用者等待被调用者提供结果时的状态

        阻塞:调用结果返回之前,调用者处于挂起状态、只有获取结果后才继续

        非阻塞:调用者在结果返回之前,不会被挂起,调用不会阻塞调用者。

        ③五种I/O模型

        阻塞

        非阻塞

        多路I/O(select 和 poll)   1024以内

        事件驱动

        异步(AIO)

【注】:Apache是select同步阻塞模型,支持文件描述符太小,默认1024

               nginx是epoll(linux)异步非阻塞模型,支持文件描述符最大65535

                nginx支持三种I/O,多路I/O、事件驱动、异步非阻塞;默认是事件驱动模型

357ae6b8268549029c8ea58024c710d0.png

13aff267223f456293abe0044743c9f9.png

c437cb0ac86b4aa6837de9dbc35ed31a.png

apache,Tomcat等都用I/O复用

select调用:同步客户到进程之间的映射关系;既同步又阻塞,但有select调用,所有并发高

c8b03b71d6f34add9cdca580652e583f.png

事件驱动I/O模型:Nginx(异步非阻塞)

前半段(应用进程-内核)是完全非阻塞的,内核空间还是阻塞的

f7b5bd4a288b48f986e6e67e7580e1a2.png

72ebda0a0fe940928c514127565144cd.png

epoll异步模型(事件驱动模型)

①:支持一个进程打开大数目的socket描述符

②:I/O效率不随fd数目增加而线性下降

③:使用mmap加速内核与用户空间的消息传递

④:边缘触发和水平触发

通知机制:水平触发   多次通知;边缘触发   一次通知

poll()

Select()

 

三、Nginx基本架构

1.Nginx简介

①:是一款开源的轻量级的高性能的静态资源web服务器、同时也是非常优秀反向代理服务器(负载均衡)、缓存服务器、邮件代理服务器。常见CDN:nginx、squid、varnish

②:最早由俄罗斯程序员伊戈尔·赛索耶夫开发,官方主页http://nginx.org

③:理念和apache不一样,占用内存少、并发能力强、在中国大陆绝大部分的网站服务器都在使用。

④:属于web服务器解决方案领域的新贵,市场份额一路飙升。

2.Nginx作为web服务器的优点

在高连接,高并发情况下,Nginx是apache的很不错的替代品理论支持超50000并发。

使用异步非阻塞的epoll模型(已经可以支持AIO),内存消耗很少。

配置文件非常简单

Rewrite重写规则非常强大 

内置健康检查功能---> (后端web服务器宕机,不影响前端访问)

节省带宽---> 支持gzip压缩(可定义压缩级别),可以添加浏览器本地缓存

稳定性高 ---> 用于反向代理,宕机几率低

模块化设计:模块可以动态编译,nginx不支持DSO(动态装卸载模块)

热部署:不停机重载配置文件,性能好。

成本低廉(尤其是作为负载均衡)

Nginx二次开发版

     淘宝 Tengine

     Registry

libevent: 高性能的网络库 epoll()

3.Nginx基本功能:

    静态资源的web服务器,缓存打开的文件描述符:

    http、smtp、pop3协议的反向代理服务器

    缓存加速、负载均衡

    支持fastcgi(fpm  LNMP),uWSGI(python)等;Python开发框架是django、java:ssm

    模块化(非DSO机制)、过滤器zip、SSI及图像的大小调整

    支持SSL(TLS)

    扩展功能:

    基于名称和IP以及端口的虚拟主机:

    支持长连接:keepalive

    支持平滑升级

    定制访问日志、支持使用日志缓冲区,提高日志存储性能

    支持URL rewrite

    支持路径别名

    支持基于IP和用户的访问控制

    支持速率限制,支持并发数限制

4.Nginx的基本架构 

一个主进程生成多个worker(工作)进程(由CPU核心数来决定)

事件驱动:epoll(边缘触发)

I/O复用器:select,poll, rt signal(实时信号)

支持Sendfile和sendfile64

支持AIO(异步I/O)和nmap(内存映射)

nginx工作模式

复用I/O、事件驱动、AIO  由1个主进程生成多个worker线程,每个worker响应多个请求。

模块类型

核心模块

Standard HTTP modules(标准http模块)

Optional HTTP modules(可选模块)      --with

Mail modules (邮件模块)

第三方模块 (第三方模块需要额外编译指定)  --add

5.nginx源码编译

安装方法:

         源码:编译安装

         官方的rpm包(基于epel源)

(1)源码编译安装nginx步骤:

        ①:安装基于perl的正则表达式,支持URL重写  

                yum -y install pcre-devel zlib-devel openssl-devel

                pcre-devel:正则表达式包、zlib-devel:压缩包、openssl-devel:加密认证

        ②:建立nginx用户

                useradd -r nginx //由于编译安装,需要创建一个程序用户nginx

        ③:预配置(根据实际情况添加或修改功能)

                如需支持https  许支持ssl    yum -y install openssl-devel

./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/lock/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 && make && make install

--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:支持httpd访问日志路径

--pid-path=/var/run/nginx.pid:支持pid路径

--user=nginx --group=nginx:属主、属主

--with-http_ssl_module:支持https

--with-http_v2_module:支持http2.0

--with-http_stub_status_module:支持状态显示页

--with-http_realip_module:支持记录原始ip的功能模块

--with-pcre:支持正则表达式

--with-stream:支持上游代理功能

cd /usr/local/nginx/

cd sbin (把/etc/nginx/nginx.conf里面的user ***改成user nginx)

ea0f571cadce4c7ea979d47315118304.png

00b11f052b0a4698a31d4646f6383b7f.png

编译完毕后为nginx的主程序设置软链接  ln -sv /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx

nginx (启动服务)、 nginx -s reload (重启nginx)、nginx -s stop (停服)

四、Nginx的web配置

1.nginx配置文件讲解

vim /etc/nginx/nginx.conf

main配置段:全局配置段

event:定义event模型工作模型工作特性

http {

}:定义http协议相关的配置

 

配置指令:不区分大小写,但要以分号结尾。支持使用变量(内置变量和自定义变量)

 

主配置段(全局)的指令:

             用于调试、定位问题

             正常运行必备的配置

             优化性能的配置

             事件相关的配置

正常运行的必备配置:

  ①:user USERNAME [group user]

    指定运行worker进程的用户和组

    user nginx nginx;

  ②:pid /path/to/pid_file;

    指定nginx守护进程的PID文件,注释到配置文件中的,就代表编译在哪就在哪;否则需要停服,更改并创建响应目录

98f881ccd36847d8bc77c8afe416e9c2.png

20e038d1d59c47dbbb8224e070d76120.png

  ③:worker_rlimit_nofile(相当于ulimit -n)

    指定一个worker进程所能够打开的最大文件句柄数

b8895dca8b734689b4574ba7ac85336a.png

把nginx设置为高并发

①vim /etc/sysctl.conf  //内核打开最大数量

d9991993c8f9432da28d2fd0c4b3b436.png

②vim /etc/security/limits.conf //安全相关的从不同层面,针对硬件和软件打开文件数量

767e481cc5614a3f814b2812bbd29201.png

③vim /etc/nginx/nginx.conf

198f360eb13c4079ae7833d914440847.png

测试是否实现高并发:

c21918e88a94441e970bf6ce87da0e0a.png

性能优化相关的配置:

 ①:worker_processes #;

     worker进程的个数;通常应略少于CPU物理核心数(可设置为auto)

     进程切换  context switch会产生CPU不必要的消耗,进程数要少于CPU。

但能提升缓存命中率

419e84f683bf41b69ce2e32c86fe7c63.png

 

 ②:worker_cpu_affinity [cpu mask]  目的在于将worker进程绑定在某些CPU上

    cpumask由八位数的二进制表示

    例如:00000001 00000010 00000100;

ccbb00d813c64b3189b9ab313ba5e9e4.png

0a7bbd9a5534462cb6d3f1c4d4e0225d.png

 ③:time_resolution

    计时器解析度:降低此值,可减少gettimeofday()系统调用的次数。(提升nginx性能)

 ④:worker_priority NUMBER:

    指明worker进程的优先(nice)值

    -20-->100,19-->139

f314ef536b2742baada67ddf8651874a.png

检查语法并重启;

nginx -t   nginx -s reload        ep_pol(事件驱动模型)

647c0977ea364806aa1074af0216df24.png

事件相关的配置:

①:accept_mutex {off|on};

     master调度用户请求至各worker进程时使用的负载均衡锁,on表示能使多个worker进程轮流、序列化的响应新请求。(使CPU核心数非常均匀的调度)

f17e280535f44cb6872c1f6c39e81bf4.png

②:lock_file file

      accept_mutex用到的锁文件路径

  ③:use [epoll|select|poll|rtsig]

      指明使用的事件模型,建议让nginx自动选择

     6a1964dfe0154a118b2cda49ae057a57.png

  ④:worker_connections #

      设定单个worker进程能处理的最大并发连接数量;

      例如   worker_connections 10240;

    940efc7494b649c8b19d0f226474a8c1.png

用于用户调试、定位问题:(若使用调试功能,需在编译的时候--with-debug)

①:daemon {on|off};

    是否以守护进程方式运行nginx,调试时应该设置为on。

②:master_process {on|off};

    是否以master/worker模型来运行nginx,调试时可以设为off。

③:error_log file

    错误日志,包括日志位置和级别。(使用debug级别,需要编译时使用--with-debug选项)

 baf0d448e5614ce19b3b17352b0ff477.png

经常需要调整的参数:worker_processes,worker_connections,worker_cpu_affinity,worker_priority

五、Nginx网页重写

1.基于nginx实现上传服务器

client _max_body_size 1m;#设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出 413 错误
client body_buffer_size size;#用于接收每个客户端请求报文的 body 部分的缓冲区大小;默认 16k;超出此大小时,其将被暂存到磁盘上的由 client body temp_path 指令所定义的位置 client body temp path path [level1 [level2 [level3]]];
#设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为 16 进制的数字,使用 hash 之后的值从后往前截取1位、2 位、2 位作为目录名

client max body size 100m;
client body buffer size 1024k;
client body_temp_path /usr/share/nginx/client body_temp/ 1 2 2;

7866911bbf834def931fc69f2227aa4e.png

2.stub_status {onloff} 状态统计页面,仅能用于 location 上下文

例如:

0c408562621d4733ae3856da75f7d871.png

测试:

a9ca075d55084cddb4648614a548e82d.png

状态内容详解:
Active connections: 1   ---->当前所有处于活动的连接

server accepts handled requests
276 276 221   ---->  接受的连接、处理过的连接、处理的请求

Reading:0 Writing:1 Waiting: 0  正在接受的请求;请求完成,处于发送响应报文
状态;处于活动状态的连接数

URL重写(用户请求重定向)

编写格式:rewrite regex replacement flag;

xxx.wma   xxx.mp3   /aaa/.jpg   /bbb/xxx.gif

www.xxhf123.com/hubei

3.URL重写(用户请求重定向)

编写格式:rewrite regex replacement flag;

xxx.wma   xxx.mp3   /aaa/.jpg   /bbb/xxx.gif

www.xxhf123.com/hubei  hebei

URL重写在企业中应用广泛,当域名发生更改和迁移,以及可以方便SEO优化

(1)return:模式比较简单,客户端可以感知

vim /etc/nginx/nginx.conf

92cde9cdbb2c49de886cd7c696e0fff9.png

测试:(也可以用301)

29da3a6646dd4df2bdf7948ec89206ca.png

②实现直接重定向域名中

8ba6ac6518224a4793422cc43d9d1ed6.png

必须在/etc/hosts/里面做本地名字解析

测试:http://web.xxhf123.top

64954a7b82224d2a8f7ce0f71d108273.png

(2)rewrite

例如

    rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;

    rewrite ^/aaa/(.*).jpg$ /bbb/$1.gif break;

    rewrite /(.*)$ https://www.xxhf123.com/$1 break;

例:

①rewrite ^/aaa/  /bbb  //从aaa目录往bbb里面跳

b4bd11af2b754958a837f4efeb157d8a.png

然后在/usr/local/nginx/html 目录下建立bbb目录,在bbb下面建立index.html

测试:

4e9d19316cbc4c93aa704a4816bcfb80.png

②做精准匹配,访问gif格式的图片,跳转到jpg里,客户端正在访问的是动态的gif

385037a29ea34badb285753f85b540d2.png

bc5c8ff40ebd410aaf8a04eb2020d2cd.png

测试:发现访问的是gif格式

db30cc49409142cbb3336696a950ad2b.png

③或者可以针对aaa目录大范围做匹配规则

6fa2983eefea4df2a50350a30fbdbc72.png

测试:发现访问aaa的时候,也可以看到动图

ce006e223f904214ba7f576bfa44da83.png

④实现跳转https访问

c3d8b306129c46a496bf048f2d219f1a.png

在https里面进行设置(跨协议客户端一定会感知)

0d04cae50376487aaa8166323b1ef6f5.png

把/usr/local/nginx的资源,copy 到https目录下的index

ac7d3c65fe9940b28de727287f7102d1.png

测试:http://web.xxhf123.top/gou.jpg

99ef765cc7f640fbb41b46bdc8c551b8.png

 (3)rewrite四大标记为位 flag分类:

①:last    rewrite规则重写完成,不再被其他规则处理,由浏览器对新规则发起请求,重头开始执行。(例如定义Alias别名)

②:break:rewrite规则完成,跳出循环。

③:redirect:以302状态响应码返回新URL,属于临时重定向。

④:permanent:以301状态响应码返回新URL,属于永久重定向。

【注】:测试时要把缓存清干净

    例如:rewrite ^/discuz/(.*)$ /skyuc/$1 break;   此种方式已经实质上属于访问新位置资源,但URL没有跳转。

例如:rewrite ^/discuz/(.*)$ https://web.xxhf.com/$1 redirect;  此方式属于URL跳转,URL位置已经发生改变

 

Last和break:让客户端不感知;操作时有个bug,无论break、last都会跳

①break

874459bf573247b9ae11976e14cb3c8d.png

break,直接打断,不跳转alias;而last会跳转

测试:http://web.xxhf123.top/aaa/

a7a79e888442462db7734a47cd98437b.png

②进行实验last:

2454be043ad54e6db54050fc508b836a.png

在alias里面创建index.html

6e23d69f6ee2496190aa0c74b186d06c.png

测试:

489f847246d44c2ba7cf2cc4eb0996e6.png

③精准匹配aaa/index.html,然后跳转到bbb下

ff684a28c8ee4dc3b712e15e16d6c1dd.png

测试:

0bda114364c64d6d93c622bea3668d67.png

redirect和permanent:让客户端感知

redirect:

a78c68717e0a44b6b79e001c28c6514a.png

测试:输入192.168.10.100/bbb

90d6b79a85624fbe9a8546db013dd0ee.png

把/usr/local/nginx/html/bbb/gou.gif 移到 /alias

b167fc3933a54c2f965c1d22aa855210.png

771bdbb03a574bc2ae5e5ceed0a00512.png

测试:

f7d87f9ed0d44100bfa1d5f3a65a6bbc.png

permanent:301重定向

86dd2f48e1b34ce2bfb13ec6b365dba8.png

测试:浏览器输入192.168.10.100/aaa/

7ccc0bcfbb734fbcae6630f2212b1345.png

4.if上下文以及防盗链

(1)if上下文(通常定义在location或server上下文中)

                语法:if (condition) {......} 

                应用环境:server,location

                condition:

                ①变量名 (变量值为空时,或者以“0”开始,即为false,其他的均为true)

                ②以变量为基础的比较表达式

                ③可以基于正则表达式模式匹配操作

                ~:区分大小写模式匹配

                ~*:不区分大小写的模式匹配检查

                !~和!~*:对上面两种测试取反

                ④测试文件是否存在  -f  !-f

                ⑤测试指定目录是否存在  -d  !-d

                ⑥测试文件是否存在:-e  !-e

                ⑦检查文件是否有执行权:-x  !-x

                例如:if ($http_user_agent ~* MSIE) {

                                       rewrite ^(.*)$ /msie/$1 break;

                                   }

                             if ($request_method = POST) {

                                         return 405;

                                      }

                              5720a10064f747c3af9784ad5ba2f17a.png

                                进行创建msie目录:

                                6dc40664ed2c42a4ac971855188ef0a1.png

                                测试结果:

                               52dfaef9419d4d48a5cfd2f47297ea34.png             ​​​​​​​ 

                                485700f8072f412cbbe30e1177463062.png

                                定义一个localtion,不用写mise

                                9708be72ae7448509a7fecc655f6d79b.png

                                测试实验结果:

                                11e8a2a631cb455fb32499640df8e8f5.png

 

                                 模拟IE浏览器:

                             96a3ec0b50bc491a86192f3a458ce11c.png

                        

 常见变量:

8c3d10e2801845e6bb1d21d4af2dd5b0.png

例:

a2baa0136482462e8efcff6246665b44.png

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值