Nginx (web server web reverse proxy)

I/O类型:

        同步和异步:synchronous,sayncronous,关注的是消息通知机制。同步请求:请求后等待一段时间返回最终需要的结果。异步请求:发送请求立即得到返回,等到处理结果出来后会通过回调函数来处理处理结果。

        阻塞和非阻塞:block,nonblock,观察角度是调用者。阻塞:在等到结果出来之前是被挂起的,得到结果后才能继续。非阻塞:调用者在结果返回之前不会被挂起。


I/O模型:取数据分为两断,从硬盘到内核内存和从内核内存复制进程内存。从内核内存复制数据到进程内存的过程称之为IO。

        blocking IO:阻塞式IO,调用者被挂起,如下图:

12230408-c8b30331f20a41dcb224d20719ffa1da.png

        nonblocking IO:非阻塞型IO,如下图:

12231306-35dca310d92e4184bd4c0b3f42bee2c1.png

        IO multiplexing:复用型IO,把请求扔给助理,请求者依然被挂起。prefork模式,请求发给master,master把请求分给线程,master继续接受请求。

                select(),poll()

        signal driven IO:事件驱动型IO,从磁盘取数据到内存空间这个过程是阻塞的,取完数据通过事件驱动,调用者通过回调函数取数据。从内核空间复制到进程空间这部分是非阻塞的,进程可以接受多个请求。event模型。

        asynchronous IO:异步IO,得到请求数据后,进程将这取数据的两部分都做好后再通知调用者来取数据,进程是解放的,可以接受多个请求。event也支持异步请求。性能真正的得到提升。

        prefork和worker用的都是复用型机制。event是事件驱动型IO,一个进程响应多个请求。

五种IO的比较:

QQ截图20180204222232.png

Nginx特性:

        模块化设计,较好的扩展性,高可靠,低内存消耗,支持热部署,主控进程master进程生成多个worker子进程,master负责解析配置等。低内存消耗体现在10000个keep-alive模式下的connection,仅需要2.5M内存。热部署体现在,不停机而更新配置文件,日志文件滚动,升级程序版本等。

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

基本功能:

        静态资源的web服务器,能缓存打开的文件描述符。支持http、smtp、pop3协议的反向代理。缓存加速,负载均衡,支持FsatCGI(fpm,LAMP),uWSGI(Python)等。模块化(非DSO机制),过滤zip,SSI及图像的大小调整,支持SSL。

扩展功能:

        基于名称和IP的虚拟主机,支持keepalive,支持平滑升级,定制访问日志,支持使用日志缓冲区提供日志存储性能,支持url rewrite,支持路径别名,支持基于IP及拥挤的访问控制,支持速率限制,支持并发限制。

Nginx的基本架构:

        一个master进程,生成一个或多个worker进程。sendfile:将数据直接从内核内存发送给请求端。事件驱动:kqueue, epoll, /dev/poll,消息通知:select, poll, rt signals,支持sendfile, sendfile64,文件AIO,支持mmap。

Nginx工作模式:

        非阻塞,事件驱动,由一个master进程生成多个worker线程,每个worker线程响应n个请求,worker * n

模块类型:

        核心模块,Standard HTTP moudules,Optional HTTP modules,Mail modules,3rd part modules。

安装方法:

        编译安装:要使用编译安装先安装开发环境,yum groupinstall "Development Tools" "Server Platform Development",然后安装 yum install pcre-devel,用来扩展正则表达式实现Rewrite重写功能。再安装SSL需要的包 yum install openssl openssl-devel,安装nginx之前先看下帮助,进入到安装目录后使用./configure --help来查看帮助。

        --prefix=PATH                         set installation prefix

        --sbin-path=PATH                  set nginx binary pathname

        --modules-path=PATH           set modules path

        --conf-path=PATH                  set nginx.conf pathname

        --error-log-path=PATH           set error log pathname

        --pid-path=PATH                    set nginx.pid pathname

        --lock-path=PATH                   set nginx.lock pathname

        --user=USER                            set non-privileged user for worker processes

        --group=GROUP                     set non-privileged group for worker processes

        --build=NAME                         set build name

        --builddir=DIR                         set build directory

        ......

编译安装:

        ./configure --prefix=/usr/local/nginx \

        --conf-path=/etc/nginx/nginx.conf \

        --user=nginx \

        --group=nginx \

        --error-log-path=/var/log/nginx/error.log \

        --http-log-path=/var/log/nginx/access.log \

        --pid-path=/varrun/nginx/nginx.pid \

        --lock-path=/var/lock/nginx.lock \

        --with-http_ssl_module \

        --with-http_stub_status_module \

        --without-http_gzip_module \

        --with-http_flv_module \

        --with-http_mp4_module \

        --with-zlib=/usr/lib64/libz.so.1.2.7 \

        --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/log/nginx/uwsgi

创建目录:

        mkdir -pv /var/tmp/nginx/{client,proxy,fastcgi,uwsgi}

启动进程:

        /usr/local/nginx/sbin/nginx

编辑配置文件:

        vim /etc/nginx/nginx.conf

        配置文件分为main配置段,这是全局配置。event { } 配置段,定义event模型工作特性。http { } 配置段,定义http协议相关的配置。

        配置指令:分号结尾。支持使用变量,有内置变量和自定义变量。使用set varaname value可以设置自定义变量。

正常运行的必备配置:

        1、user指定运行nginx的用户和组:user username groupname,默认为注释,使用编译时的用户。

        2、pid指定nginx守护进程的pid文件,默认为注释,使用编译时的值。

        3、worker_rlimit_nofile指定所有worker进程所能够打开的最大句柄数。

性能优化相关的配置:

        1、worker_processes为进程的个数,通常少于核心数,核心数减一。

        2、worker_cpu_affinity cpumask,设定worker进程绑定在那些cpu上,cpumask为cpu掩码,0000 0001代表第一颗cpu,0000 0002代表第二颗cpu,等等。例:worker_cpu_affinity 00000001 00000010 00000100; 

        3、timer_resolution计时器解析度,建议降低此值,可以减少gettimeofday()系统调用的次数。

        4、worker_priority number;指明worker进程的优先级,基于nice值,-20到19,-20的优先级最高。

事件相关配置:

        1、accept_mutex off | on;为on时worker进程轮流响应请求。

        2、lock_file /path/to/lock_file; accept_mutex 用到的锁文件路径。

        3、use [epoll|rtsig|select|poll];指定使用的事件模型,建议自行选择。

        4、worker_connections number;单个worker进程所处理的最大并发连接数量,最终的并发连接量要乘以worker_processes。

用于调试、定位问题:

        编译时要打开--with-debug才能生效,

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

        2、master_process on|off 是否以master/worker模式运行nginx;默认为on;调试时可设置off以方便追踪。

        3、error_log /path/to/error_log level;错误日志文件及其级别;默认为error级别;调试时可以使用debug级别,但要求在编译时必须使用--with-debug启用debug功能;


/usr/local/nginx/sbin/nginx -h        查看帮助信息

        nginx version: nginx/1.13.8

        Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

        Options:

          -?,-h         : this help

          -v            : show version and exit

          -V            : show version and configure options then exit

          -t            : test configuration and exit

          -T            : test configuration, dump it and exit

          -q            : suppress non-error messages during configuration testing

          -s signal     : send signal to a master process: stop, quit, reopen, reload

          -p prefix     : set prefix path (default: /usr/local/nginx/)

          -c filename   : set configuration file (default: /etc/nginx/nginx.conf)

          -g directives : set global directives out of configuration file

重载配置:

        /usr/local/nginx/sbin/nginx -s reload    重新加载配置文件,其他的stop, quit, reopen, reload


nginx配置


Nginx作为web服务器的配置:

        http { }:由 ngx_http_core_module 模块所引入。配置一个静态的web服务器。

        http {

                uptream { }

                server {

                        location URL { }

                        location URL { }

                }

                server { }

        }

配置指令:

        server {} 定义一个虚拟主机。

        例:基于端口的虚拟主机

        server {

            listen 8080;

            server_name www.zhuqiyang.com;

            root "/www/web1";

        }

listen:

        listen 127.0.0.1:8000;

        listen 127.0.0.1;

        listen 8000;

        listen *:8000;

        listen localhost:8000;

server_name:

        1、先做精确匹配;www.scriptjc.com 

        2、左侧通配符匹配;*.scriptjc.com

        3、右侧通配符匹配;www.scriptjc.com, www.*

        4、正则表达式匹配: ~^.*\.scriptjc\.com$

        5、default_server;

root path:

        资源路径映射,请求的资源路径。

location:

        根据请求的URI来匹配对应的规则。

        server{

                listen 80;

                server_name www.scriptjc.com;

                 location / {        #这里的根目录是相对于里面的root而言的。

                        root "/vhosts/web1";

                }

                location /images/ {#匹配到就从root定义的位置找,实际的地址为/vhosts/images/images

                        root "/vhosts/images";

                }

                location ~* \.php$ {

                        fastcgi

                }

        }

优先级:

        =      精确匹配

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

        ~*     正则表达式模式匹配,匹配时忽略字符大小写

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

        不带任何符号的URL

alias path:

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

        location /images/ {#这里的实际的地址为/vhosts/images/,也就是将长地址替换为短地址。

                alias "/vhosts/images/";        后面的斜线 / 不能省略,因为是别名。

        }

默认主页:

        格式:index file;例:index index.php index.html

错误页面:

        格式:error_page code ... [=code] URI | @name;

        根据错误码来指明特定的错误页面。

        例:error_page 404  /404.html

        [=code] 指定响应吗,当前页面响应吗为404,但是可以指定其响应吗,error_page 404 =200 /page.html。

基于IP访问控制:

        allow IP/网段

        deny IP/网段

        deny all 拒绝所有。

基于用户访问控制:

        basic,digest

        auth_basic "any name";

        auth_basic_user_file "user and passwd file path",使用htpasswd创建

        htpasswd -c -m /etc/nginx/user/.htpasswd  username,回车输入密码,这个路径就是上面的路径

https服务:

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

        server {

                listen       443 ssl;

                server_name  localhost;

                ssl_certificate      cert.pem;

                ssl_certificate_key  cert.key;

                ssl_session_cache    shared:SSL:1m;

                ssl_session_timeout  5m;

                ssl_ciphers  HIGH:!aNULL:!MD5;

                ssl_prefer_server_ciphers  on;

                location / {

                        root   html;

                        index  index.html index.htm;

                }

        }

状态页:

        stub_status on | off 显示nginx服务器状态信息的页面

        location /status {

                stub_status on;

                allow 192.168.96.0/24;

                deny all;

        }

rewrite:

        rewrite regex replacement flag;

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

        flage:

                last:被此规则匹配后忽略后面的规则,将重写后的地址重新交给nginx,再重新匹配。

                break:直接请求重写后的地址。

                redirect:临时重定向 302

                permanent:永久重定向 301

        例:

        location {

                rewrite ^/bbs/(.*)$   /form/$1 break;

        }

if:

        if condition { }, 应用于server location,condition可以使用

        变量名,

        =、

        !=、

        ~区分大小写、

        ~*不区分大小写,

        !~,!~*对上面两种取反,

        -f文件、!-f不是文件

        -d 目录 !-d

        -e 、!-e是否存在

        -x、!-x 是否有权限

        例:客户端类型判断

        if ($http_user_agent ~* MSIE) {

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

        }

防盗链:

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

                valid_referer none blocked www.scriptjc.com;

                if () {

                        rewrite ^/ http://www.scriptjc.com;

                }

        }

定制访问日志格式:

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                          '$status $body_bytes_sent "$http_referer" '

                          '"$http_user_agent" "$http_x_forwarded_for"';

        access_log  logs/access.log  main;

        此处可用nginx的内建变量

网络连接相关配置:

        keepalive_timeout #;长连接超时时长。默认75s。

        keepalive_requests #;请求的最大资源数。

        keepalive_disable [mise6|safari|none]禁用长连接

        tcp_nodelay on | off 是否对长连接使用TCP_NODELY选项

        client_header_timeout #;读取http请求报文的超时时长

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

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

fastcgi的相关配置:

        LNMP:php启用fpm模型

        location ~ \.php$ {

                root           html;

                fastcgi_pass   127.0.0.1:9000;

                fastcgi_index  index.php;

                fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;

                include        fastcgi_params;

        }


文章地址:http://www.scriptjc.com/article/805