Nginx各种IO

五种IO机制,Nginx web重点基础详解

2017-09-20  本文已影响63人  _千树一木_

Nginx

1.高并发链接:官方测试能够支持5W并发连接,在实际生产环境中跑到2~3万并发连接数。

2.内存消耗少:在3W并发链接下,开启的10个Nginx进程才消耗150M内存

3.配置文件非常简单:风格跟程序一样通俗易懂。

4.陈本低廉:Nginx为开源软件,可以免费使用。而购买F5 BIG-IP NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币。

5.支持Rewrite重写规则:能够根据域名,URL的不同,将HTTP请求分到不同的后端服务器群组。

6.内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问。

7.节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头,可以设置压缩级别。

8.稳定性高:用于反向代理,宕机的概率微乎其微,master,worker。

9.模块化设计:模块可以动态编译,不耦合,灵活组建性非常好!

10.外围支持好:文档全,二次开发和模块较多

11.支持热部署:可以不停机重载配置文件

12.支持事件驱动,AIO,mmap等性能优化

理解要点:异步IO,mmap

HEADER

            通用首部

            请求首部:

                       If-Modified-Since   ,   If-None-Match

          响应首部

          实体首部

          扩展首部

Pv:page view      页面整个一次的浏览量

Uv:user view      独立IP

Web页面

          1.加速

           缓存加速

           基于任何浏览器对单个域名访问的多线程是有限的,在站点上做加速时,比如在同一主页面上的资源,按照资源类型划分,分别对应多个域名,那么就能起到很高的页面加速效果。

           2.认证

            基于IP认证:

            基于用户认证:

               basic

               digest

          3.资源认证:

                    Alias

                    DocumentRoot

I/O类型

      同步和异步:synchronous,asynchronous

                  关注的是消息通知机制

                   同步:调用发出之后不会立即返回,但一旦返回,则返回即使最终结果。

                   异步:调用发出之后,被调用方立即返回消息,但返回的并非最终结;被调用者通过状态,通知机制等,来通知调用者,或通过回调函数来处理结果。

       阻塞和非阻塞:block,nonblack

                  关注的是调用者等待被调用者返回调用结果时的状态

                   阻塞:调用结果返回之前,调用者会被挂起;调用者只有在得到返回结果之后才能继续;

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

I/O模型

                 blocking IO(阻塞式IO)

                 nonblocking IO(非阻塞式IO)

                 IO  multiplexing(复用型IO)

                              select()    poll()

                 signal   driven   IO(事件驱动型IO)

                              通知:

                                           水平触发:多次通知

                                           边缘触发:只通知一次,但可以回调

                 asynchronous IO(异步IO)

例如:一次read操作:

              主要的两步:(1)内核进程将磁盘中的内容读到内核内存

                                    (2)用户进程将内核内存中的内容copy一份到用户内存

              而IO操作即主要为(2)

1.阻塞性IO

     在内核进行(1)(2)步骤时,进程被‘不可中断式挂起’,什么事都做不了,一直在等待。

     一个进程通常情况下,只能处理单路IO,例如这个用户请求,起码经过网络IO和磁盘IO两种IO方式。

2.非阻塞式IO

    第(1)步是忙等待状态,第(2)步还是阻塞模式,所有非阻塞模式并不比阻塞式高多少

         阻塞式IO和非阻塞式IO都是古老的单进程模型,一个进程响应一个任务,都是串行模式。

3.复用型IO(多路IO)

     在用户请求与内核处理之间有一个内核中的select(),poll(),

     select()最多承载1024

      这种多路模式就相当于在内核中加了一个助理,能把请求分发给内核中不同的功能去处理,但是实际也是阻塞的,阻塞在select上,并没阻塞在用户进程上,所以还可以进行别的IO请求。

4.事件驱动型IO

      第(1)步,不用进行忙等,完成了内核会通知。第(2)部还是阻塞式的

      不用阻塞,不用忙等,这样的话一个进程可以处理多个响应请求(这是真正的实现一个响应多个请求),虽然这点有了进步,但是第(2)步仍然是阻塞的,所以性能的提高不会非常大。这种处理方式即为callback处理方式。

       引入了两种通知机制:水平触发(多次通知,直到你拿到)

       边缘触发(只通知一次,但我会把资源发在某处,你来了问我取就行(回调方法))

5.异步IO

        第(1)(2)阶段都不用阻塞,用户请求之后,进程将资源扔给内核,内核处理完毕,直接将数据返回给进程,进程直接打包发走,实现了真正的1对n,所以非常优秀

        Nginx支持异步IO,还更支持mmap机制,所以它的性能优秀

五种IO的比较图


有通知机制的notification叫做异步IO

Nginx

                 Nginx: engine X,Tengine ,Registry

                libevent:高性能的网络库epoll():nginx就继承了其的epoll()这种事件驱动方法。

Nginx特性:

                   模块化设计,较好的扩展性,淘宝改进的tengine支持动态模块可装载

                   高可靠

                                               master–> worker

                  低内存消耗

                                              10000个keep-alive模式下的connection,仅需要2.5MB的内存

                  支持热部署

                                              不停机而更新配置文件,日志文件滚动,升级程序版本;

                 支持事件驱动机制,异步IO,mmap内存映射;

  基本功能:

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

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

               缓存,负载均衡机制:

               支持FastCGI(fpm,LNMP),uWSGI(python)等;

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

扩展功能:

               基于名称和IP的虚拟主机;

               支持keepalive

               支持平滑升级

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

               支持url rewrite

               支持路径别名

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

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

Nginx的基本运行图

Nginx的基本架构:

                1.    一个master进程,生成一个或多个worker进程(线程)

                 它支持sendfile机制:

              磁盘通过内核的指令进行操作,然后内核将操作的结果直接打包成数据报文,通过网卡发送,其中省略了多次返回到用户进程的状态,这样提高 了效率。

                2.  基于事件驱动:linux系统epoll(边缘出发),BSD系统kqueue(),/dev/poll

                    nginx都支持以上不同系统的事件驱动机制

                              IO复用:复用器:select,poll,rt signal

                   支持sendfile(该方式下发送内容大小有限,一般为几k),sendfile64(相比sendfile,每次发送的内容更大一点)

                   支持AIO

                   支持mmap

Nginx的工作模式:非阻塞,事件驱动,由一个master进程生成多个worker线程,每个worker响应n个请求:

                 作为web服务器而言,总体支持的最大请求书为worker* n,但是套接字最多为65535个,最多5w左右,但是在反向代理模式下会更少一些

模块类型:

                核心模块

                Standard HTTP modules     标准HTTP模块

                Optional HTTP modules      可选的HTTP模块

                Mail  modules     邮件模块

               3rd   party modules        第三方模块(在源码编译时,需要手动添加编译)

安装方法:

               1. 源码安装

               2. 制作好的程序包:rpm包,

               1. 源码安装Niginx

                        a) 步骤

                                    groupadd –r nginx

                                    useradd –g nginx –r nginx

                        b)  常用第三方模块

                                i.    --with-http_ssl_module开启https方式

                       c)  安装命令

             ./configure --prefix=/home/hxl/Test_nginx --user=nginx --group=nginx--error-log-path=/home/hxl/Test_nginx/logs/error.log--http-log-path=/home/hxl/logs/access.log--pid-path=/home/hxl/log/nginx/nginx.pid --lock-path=/home/hxl/Test_nginx/lock/nginx.lock--with-http_ssl_module --with-http_stub_status_module--with-http_gzip_static_module --with-http_flv_module--http-client-body-temp-path=/home/hxl/Test_nginx/clinet--http-proxy-temp-path=/home/hxl/Test_nginx/proxy--http-fastcgi-temp-path=/home/hxl/Test_nginx/fastcgi--http-uwsgi-temp-path=/home/hxl/Test_nginx/uwsgi

                            make && make install

                            修改nginx.conf第一行为user  root;

                            找到nginx启动命令启动nginx

                            测试访问

                    d)  配置文件

                            main配置段:  全局配置段

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

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

                            配置指令:要以分号结尾,语法格式:

                                     directivevalue1 {value2…}

                           支持使用变量

                                  内置变量:

                                          模块会提供几建变量定义

                                  自定义变量:

                                           setvar_namevalue

                           主配置段的指令:

                                           用于调试,定位问题

                                           正常运行必备的配置

                                           优化性能的配置

                                           事件相关的配

上述内容回顾

                     I/O模型,nginx基本安装

                    e)  主配置段的指令:

                                 正常运行的必备配置:

                                               1.  user   USERNAME  [GROUPNAME];

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

                                                           组名字省略的话,默认使用与用户名相同的组

                                                           user    nginx  nginx;

                                               2.  pid     /path/to/pid_file;

                                                           指定nginx守护进程的pid文件;

                                                           pid     /home/hxl/log/nginx/nginx.pid

                                              3.  worker_rlimit_nofile   <number>;

                                                          更改rlimit_nofile所有worker进程一共打开的最大文件数()的限制。用于增加限制而不重新启动主进程

                                              4.  worker_rlimit_core一般不调整

                                                          更改rlimit_core所有worker进程的核心文件()的最大大小的限制

                              优化性能相关的配置:

                                             1.  worker_processes #;

                                                         worker进程的个数:通常应该略少于CPU物理核心数;

                                                         不过较新版本的都支持auto这种自动判断数量的方式了,可以直接设置为auto

                                             2.  worker_cpu_affinitv cpumask …;保证了缓存的有效性,可能会提升缓存的命中率。

                                                        设定将worker进程绑定在那些cpu上

                                                        context switch会产生CPU的不必要的消耗

                                                cpumask:

                                                       0000 0000

                                                       0000 0001           一号  cpu

                                                       0000 0010           二号  cpu

                                                   …

                                                 不过较新版本的都支持auto这种自动判断数量的方式了,可以直接设置为auto(很方便,不用再记什么参数了)

                                              3.  timer_resolution;

                                                          计时器解析度:降低此值,可减少gettimeofday()系统调用次数。默认情况下,gettimeofday()每次接收到内核事件时都会调用它(在生产环境中,并没有设置这个)。

                                               例:

                                                           timer_resolution100ms;

                                             4.  worker_prioritynumber;

                                                      定义worker进程的调度优先级,如通过nice命令完成的;

                                                      赋值number表示较高的优先级。允许范围通常在-20到19。

                                                   例:

                                                          worker_priority     -10

                     f)事件相关的配置

                                              1.  accept_mutex{on | off};

                                                       如果accept_mutex启用,woker进程将轮流接受新链接。

                                                       还有一个_delay,设置等待时间的

                                              2.  lock_file file;

                                                       accept_mutex  用到的锁文件路径

                                              3.  use  <method> [epoll|rtsig|select|poll];

                                                      指定要使用的连接处理method,通常不需要明确指定它,因为nginx默认使用最有效的方法。

                                              4.  woker_connections

                                                      设置单个woker进程可以打开的同时连接的最大数量。

                     g)用户调试,定位问题:

                                              1.  daemon   { on | off };

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

                                              2.  master_process  { on | off };

                                                       是否以master/worker模型来运行nginx;

                                              3.  error_log file [level]

                                                       第一个参数定义一个file将存储日志的参数。

                                                       第二个参数决定的level记录的,并且可以使以下中的一个:

                                                       debug,info,notice,warn,error,crit,alert或emerg。上述日志级别按严重性增加的顺序列出。

                                                       若要使用debug级别,需要在编译nginx时使用–with-debug选项;

                      h)  总结,常需要进行调整的参数

                                 woker_processes,worker_connections,worker_cpu_affinity,worker_priority

                      i)  新改动配置生效的方式

                                 nginx    –s    reload

                                                  stop,quit,reopen

Nginx作为web服务器时使用的配置:

               http{}:由ngx_http_core_module模块所引入:

               配置框架:

                               http     {

                                          upstream    {

                                           …

                                        }

                                        server    {

                                                 location   {

                                                             root          “/path/to/somedir”;

                                                }                          #类似于httpd种的,用于定义URL与本地文件系统的映射关系;

                                                location   URL   {

                                                          if   …  {

                                                                 …

                                                          }

                                               }

                                      }                                     #每个server类似于httpd中的一个;

                                    server     {

                                               …

                                     }

  }

               注意:与http相关的指令仅能够放置于http,server,location,upstream,if上下文,但有些指令仅应用与这5种上下文种的某些种;

配置指令:

         1.  server {   } 

                       用来定于虚拟主机的

                       root指定的目录,index所载入的文件都可以放在任意位置

          2.    listen

                      指定监听的地址和端口:

                      listen   address[:port];

                      listen   port;

          3.  server_name      NAME […];

                      后可跟多个主机:名称还可以使用正则表达式(~)或通配符;

                            (1) 先做精确匹配检查:

                            (2) 左侧通配符匹配检查:*.magedu.com

                            (3) 右侧通配符匹配检查:如mail.*

                            (4) 正则表达式匹配检查:如~^.*\.magedu\.com$

                            (5) default_server;

                          server   {

                                   server_name    www.testnginx.com;

                           }

                         server  {

                                  server_name    *.testnginx.com

                           }

                         server  {

                                 server_name     mail.*

                           }

          4.   root    path;

                      设置资源路径映射,用于指明请求的URL所对应的资源所在的文件系统上的起始路径;

          5.   location   [ = | ~ | ~* | ^~ ] uri [ … ]

                    location   @name     […]

                       功能:允许根据用户请求的URI来匹配定义的各location;匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能;

                      =:  精确匹配检查

                      ~:  正则表达式模式匹配检查,区分字符大小写

                      ~*: 正则表达式模式匹配检查,不区分字符大小写

                      ^~:  URI的前半部分匹配,不检查正则表达式

                      匹配的优先级:精确匹配(=),^~,~,~*,不带任何符号的location;

                      server {

                                 listen    80;

                                 server_name     www.testnginx.com;

                                 location   /   {

                                           root   “/vhosts/web1”;

                                 }

                                 location   /images/{

                                           root   “/vhosts/images”;

                                 }

                                           location   ~*\.php$ {

                                                  fcgipass

                                 }

                      }

                           http://nginx.org/en/docs/http/ngx_http_core_module.html#location【官方地址,以上所有的配置指令,官方都有明确解释,前提是不被墙】

                           测试location使用规则,可以手动写一写测试一下,这个规则还是很神奇的(神奇之处(路径的相对性问题),会在root和alias中做了详细分析),里面有一些规则,不好表达,需要自己根据效果感受一下的!

          6.   alias    path

                    用于location配置段,定义路径别名

                    说明解释:

                    location    /images/   {

                             root   html;

                    }

                     http://127.0.0.1:8080/images/index.html       <——      /html/images/index.html (真实地址)

                     location    /images/  {

                                alias         /www/pictures/;

                     }

                     http://127.0.0.1:8080/images/index.html       <——      /www/pictures/index.html(真实地址)

                      注意(理解例子,就不用看这么绕来绕去的话了):

                      root表明指明路径为对用的location“/” URL;

                      alias表明路径映射,即location指令后定义的URL是相对于alias所指明的路径而言

         7.   index    file;

                      默认主页面:

                             index     index.php    index.html;

         8.   error_page code […] [=code] URI| @name

                     根据http响应状态码来指明特用的错误页面;

                     error_page    404/404_customed.html

                     [=code]:以指定的响应码进行响应,而不是默认的原来的响应;默认表示以新资源的响应码为其响应码

                                     (还可以更改返回的响应码,这样浏览器会显示你更改过的响应码类型)

           9.   基于IP的访问控制

                     allow       IP/IP段

                     deny       IP/IP段/all

                     可以放在server中,也可以放在location中,作用域不同;

         10.  基于用户的访问控制

                    basic,digest

                    auth_basic    “[说明认证]”

                    auth_basic_user_file        “/PATH/TO/PASSWORD_FILE”

                                          账号密码文件建立使用htpasswd(改名了需下载httpd)来创建:

                                          命令为   htpasswd  –c  –m [/PATH/TO/PASSWORD_FILE]  <name>

          11.   https服务(普通手动添加方式较多,等接下来详细研究企业购买证书并安装的流程)

                  生成私钥,生成证书签署请求,并获得证书

                  在nginx.conf文件中有关于完整版的配置模板

          12.  stub_status {on|off};

                  仅能用于location上下文;

                  状态信息允许IP可以自己设定

                  浏览器效果图如下

                  Active connections: 2#当前所有处于打开状态的连接数;

                  server accepts handled requests

                            19230 19230 74

                  (接受过的连接数)(处理过的连接数)(处理的请求,在“保持连接”模式下,请求数量可能会多于连接数量;)

                       Reading:正处于接受请求状态的连接数;

                       Writing:请求已经接受完成,正处于处理请求或发送响应的过程中的连接数;

                       waiting:保持连接模式,且处于活动状态的连接数

          13.  rewrite  [对于URL处理]

                 rewrite  regex  replacement  flag;

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

                              http://www.testnginx.com/images/a/b/1.jpg  —(根据设置规则的重定向)—>  http://www.testnginx.com/imgs/a/b/1.jpg

                  flag:

                             last:   一旦此rewrite规则重写完成后,就不在被后面其它的rewrite规则进行处理,而是由User  Agent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程

                             break:  一旦此rewrite规则重写完成后,由User Agent对新的URL重新发起新请求,且不再会被当前locatrion内的任何rewrite规则所检查 

                             redirect:  以302响应码(临时重定向)返回新URL;

                             permanent:  以301响应码(永久重定向)返回新URL;

         14.    if

                       语法:if (condition){…}

                       应用环境:  server,  location

                       condition:

                                 (1) 变量名:

                                                      变量值为空串,或者以“0”开始,则为false,其它的均为true;

                                 (2) 以变量为操作数构成的比较表达式

                                                       可以使用=,!=类似的比较操作符进行测试;

                                (3) 正册表达式的模式匹配操作

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

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

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

                                (4) 测试文件可用性:  -f,!-f

                                (5) 测试指定路径为目录的可能性:-d,!-d

                                (6) 测试文件的存在性:-e,!-e

                                (7) 检查文件是否有执行权限: -x,!-x

                        例如:

                                                     if    ($http_user_agent~* MSIE) {

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

                                                          }

                                       说明:通过$http_user_agent检测用户使用哪种操作系统/版本号等,MSIE是微软推出的网页浏览器,如果检测用户是用微软的这款浏览器的话,它会将URL按照规则重定向个URL。

         15.   防盗链

                           location    ~* \.(jpg|gif|jpeg|png)$   {

                                            valid_referer    noneblocked    www.testnginx.com;               #设置允许连接地址

                                        if   ($invalid_referer)   {                                                               #设置发生盗链的重定向地址

                                                  rewrite^/http://www.testnginx.com/403.html

                                        }

                          }

16.定制访问日志格式

                  log_formatmain                  '$remote_addr - $remote_user[$time_local] "$request" '

                                                             '$status $body_bytes_sent"$http_referer" '

                                                             '"$http_user_agent""$http_x_forwarded_for"';

                  access   _loglogs/access.log    main;

                                                               (格式名)

                  注意:此处可用变量为nginx各模块内建变量;

网络连接相关的配置:

             1.  keepalive_timeout #;                    长连接的超时时长,默认75s;

             2.  keepalive_requests #;                  在一个长连接上所能够允许请求的最大资源数;

             3.   keepalive_disable         [msie6|safari|none];

                                   为指定类型的User Agent禁用长连接;

             4.   tcp_nodelayon|off;

                                   是否对长连接使用TCP_nodelay选项;一般设为on,多小都发送;

            5.   client_header_timeout#;读取http请求报文首部的超时时长;

            6.   client_body_timeout#;读取http请求报文Body部分的超时时长;

            7.    send_timeout#;发送响应报文的超时时长;

       fastcgi的相关配置:

                    LNMP:php启用fpm模型;

                   php模块nginx配置模板中都有,可以看着模板进行编辑测试,原理采用反带方式,测试时注意iptables是否开启了外部网络访问该9000端口的权限。

上一篇下一篇

猜你喜欢

热点阅读