Nginx基础

============================================================================

概述:

  本章我们将介绍Nginx,内容权重都很重量级,内容包括:

  • Nginx的相关概念,功能,解决的问题,官方站点;

  • 5种I/O模型的介绍;

  • Nginx的程序架构概述;

  • Nginx的编译安装;

  • Nginx中配置文件的构成;

  • Nginx主配置段详解;

  • Nginx中http协议的核心模块配置

============================================================================

Nginx介绍

engineX = Nginx

  • NGINX is a free, open-source,high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxyserver.

  (NGINX是一个免费、开源、高性能的HTTP服务器和反向代理,以及IMAP/POP3代理服务器)。

功能:

  • 是http协议的实现:可作为web服务器(类似于httpd);

  • http reverse proxy反向代理(类似于httpd);

  • imap/pop3 reverse proxy(邮件服务器的反向代理)

官方站点:nginx.org

C10K(10K Connections):解决C10K(一万个并发链接)的问题 

相关概念

并发连接数:

  • 指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器链接的总TCP数量,就是并发连接数。

C10K问题:

  • 网络服务在处理数以万计的客户端连接时,往往出现效率低下甚至完全瘫痪,这被称为C10K问题。

国内nginx的二次开发:

  • Tengine

  • OpenResty

http协议回顾:

I/0模型介绍

阻塞型、非阻塞型、复用型、信号驱动型、异步

同步/异步:关注消息通知机制;

 消息通知:

  • 同步:等待对方返回消息; 

  • 异步:被调用者通过状态、通知或回调机制通知调用者被调用者的运行状态;

阻塞/非阻塞:

关注调用者在等待结果返回之前所处的状态; 

  • 阻塞:blocking,调用结果返回之前,调用者被挂起;

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

一次IO请求,都会由两阶段组成:

  • 第一步:等待数据,即数据从磁盘到内核内存;

  • 第二步:复制数据,即数据内核内存到进程内存; 

复用型IO调用:

  • select():1024

  • poll():

I/O模型

阻塞I/O模型 

应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。 
如果数据没有准备好,一直等待。。。。 
数据准备好了,从内核拷贝到用户空间 
I/O函数返回成功指示

非阻塞I/O模型 

我们把一个套接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。这样我们的I/O操作函数将不断的测试 数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为止。在这个不断测试的过程中,会大量的占用CPU的时间。

I/O复用模型 

I/O复用模型会用到select或者poll函数,这两个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。 

信号驱动I/O模型 

首先我们允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。

异步I/O模型 

调用aio_read函数,告诉内核描述字,缓冲区指针,缓冲区大小,文件偏移以及通知的方式,然后立即返回。当内核将数据拷贝到缓冲区后,再通知应用程序。

5个I/O模型的比较

   

Nginx的程序架构:

master/worker(两级架构)

一个master进程:

  • 负载加载配置文件、管理worker进程、平滑升级;

一个或多个worker进程

  • 处理并响应用户请求;

缓存相关的进程:

  • cache loader:载入缓存对象

  • cache manager:管理缓存对象

特性:异步、事件驱动和非阻塞

  • 并发请求处理:通过kevent/epoll/select

  • 文件IO:高级IO sendfile,异步,mmap

nginx高度模块块:

  • 高度模块化,但其模块早期不支持DSO机制;近期版本支持动态装载和卸载;

模块分类:

核心模块:core module

标准模块:

  • Standard HTTP modules(标准模块)

  • Optional HTTP modules(可选模块)

  • Mail modules

  • Stream modules

3rd party modules(第三方模块)

nginx的功用:

  • 静态的web资源服务器;

  • 结合FastCGI/uwSGI/SCGI等协议反代动态资源请求;(也可以缓存动态资源)

  • http/https协议的反向代理;

  • imap4/pop3协议的反抽代理;

  • tcp/udp协议的反代;

附图:

  Ningx程序架构图

Nginx的安装配置

官方的预制包:

编译安装: 

  • yum groupinstall "Development tools"  "Server Platform Development" 准备开发环境

  • yum install pcre-devel openssl-devel zlib-devel 解决依赖关系

  • useradd -r nginx

  • ./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

编译安装:

[root@centos7 nginx]# ls # 如下,这是我从官网下载的源码包和rpm包。nginx-1.10.0-1.el7.ngx.x86_64.rpm  nginx-1.10.0.tar.gz
# 这里我们首先进行编译安装[root@centos7 nginx]# tar xvf nginx-1.10.0.tar.gz  # 解压源码包[root@centos7 nginx]# lsnginx-1.10.0 (解压后的目录) nginx-1.10.0-1.el7.ngx.x86_64.rpm  nginx-1.10.0.tar.gz[root@centos7 nginx]# cd nginx-1.10.0/ # 进入目录[root@centos7 nginx-1.10.0]# lsauto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  man  README  src# 如上可以看到目录中的文件和我们之前编译过的程序大体相同,也同样遵循三步曲首先我们查看 ./configure --help 查看常用的选项

 1.在执行之前我们还要创建一个nginx的系统用户 :

  • useradd -r nginx

 2.执行./configure 指明要存放的程序位置,及配置文件,要添加的模块等等

[root@centos7 nginx-1.10.0]# ./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/run/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-aioConfiguration summary  + using threads  + using system PCRE library  + using system OpenSSL library  + md5: using OpenSSL library  + sha1: using OpenSSL library  + using system zlib library  nginx path prefix: "/usr/local/nginx"  nginx binary file: "/usr/local/nginx/sbin/nginx"  nginx modules path: "/usr/local/nginx/modules"  nginx configuration prefix: "/etc/nginx"  nginx configuration file: "/etc/nginx/nginx.conf"  nginx pid file: "/var/run/nginx.pid"  nginx error log file: "/var/log/nginx/error.log"  nginx http access log file: "/var/log/nginx/access.log"  nginx http client request body temporary files: "client_body_temp"  nginx http proxy temporary files: "proxy_temp"  nginx http fastcgi temporary files: "fastcgi_temp"  nginx http uwsgi temporary files: "uwsgi_temp"  nginx http scgi temporary files: "scgi_temp"

 3.如上第一步已经完成,下面我们执行 make && make install

 4.接下来,要把主程序文件添加至PATH环境变量

# 在/etc/profile.d/下创建一个脚本配置文件[root@centos7 nginx-1.10.0]# vim /etc/profile.d/nginx.sh 1 export PATH=/user/local/nginx/sbin:$PATH   # 然后保存退出,重读配置文件[root@centos7 nginx-1.10.0]#  . /etc/profile.d/nginx.sh# 可以测试一下语法[root@centos7 ~]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful

 如上整个编译过程就已将完成,因为这里没有UNIT file文件或者service脚本所以直接nginx就可启动程序(注意:httpd和nginx只能启动一个,如果httpd启动了,nginx就启动不了了)

[root@centos7 ~]# nginx  # 启动程序[root@centos7 ~]# ss -tnl # 查看80端口State       Recv-Q Send-Q                                      Local Address:Port                                                     Peer Address:Port              LISTEN      0      25                                                      *:514                                                                 *:*                  LISTEN      0      128                                                     *:80                                                                  *:*                  LISTEN      0      128                                                     *:22                                                                  *:*                  LISTEN      0      128                                             127.0.0.1:631                                                                 *:*                  LISTEN      0      100                                             127.0.0.1:25                                                                  *:*                  LISTEN      0      128                                             127.0.0.1:6010                                                                *:*                  LISTEN      0      25                                                     :::514                                                                :::*                  LISTEN      0      128                                                    :::22                                                                 :::*                  LISTEN      0      128                                                   ::1:631                                                                :::*                  LISTEN      0      100                                                   ::1:25                                                                 :::*                  LISTEN      0      128                                                   ::1:6010                                                               :::*

 nginx提供的网页文件在/usr/local/nginx/html

[root@centos7 ~]# ls /usr/local/nginx/client_body_temp  fastcgi_temp  html  proxy_temp  sbin  scgi_temp  uwsgi_temp[root@centos7 ~]# ls /usr/local/nginx/html/50x.html  index.html

 现在我们打开浏览器,访问服务如下:

5.为nginx提供SysV init脚本:

新建文件/etc/rc.d/init.d/nginx,内容如下:#!/bin/sh## nginx - this script starts and stops the nginx daemon## chkconfig:   - 85 15 # description:  Nginx is an HTTP(S) server, HTTP(S) reverse \#               proxy and IMAP/POP3 proxy server# processname: nginx# config:      /etc/nginx/nginx.conf# config:      /etc/sysconfig/nginx# pidfile:     /var/run/nginx.pid # Source function library.. /etc/rc.d/init.d/functions  # Source networking configuration.. /etc/sysconfig/network   # Check that networking is up.[ "$NETWORKING" = "no" ] && exit 0    nginx="/usr/local/nginx/sbin/nginx"prog=$(basename $nginx)     NGINX_CONF_FILE="/etc/nginx/nginx.conf"      [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx       lockfile=/var/lock/subsys/nginxmake_dirs() {   # make required directories   user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`   options=`$nginx -V 2>&1 | grep 'configure arguments:'`   for opt in $options; do       if [ `echo $opt | grep '.*-temp-path'` ]; then           value=`echo $opt | cut -d "=" -f 2`           if [ ! -d "$value" ]; then               # echo "creating" $value               mkdir -p $value && chown -R $user $value           fi       fi   done}start() {    [ -x $nginx ] || exit 5    [ -f $NGINX_CONF_FILE ] || exit 6    make_dirs    echo -n $"Starting $prog: "    daemon $nginx -c $NGINX_CONF_FILE    retval=$?    echo    [ $retval -eq 0 ] && touch $lockfile    return $retval} stop() {    echo -n $"Stopping $prog: "    killproc $prog -QUIT    retval=$?    echo    [ $retval -eq 0 ] && rm -f $lockfile    return $retval} restart() {    configtest || return $?    stop    sleep 1    start} reload() {    configtest || return $?    echo -n $"Reloading $prog: "    killproc $nginx -HUP    RETVAL=$?    echo} force_reload() {    restart} configtest() {  $nginx -t -c $NGINX_CONF_FILE} rh_status() {    status $prog} rh_status_q() {    rh_status >/dev/null 2>&1} case "$1" in    start)        rh_status_q && exit 0        $1        ;;    stop)        rh_status_q || exit 0        $1        ;;    restart|configtest)        $1        ;;    reload)        rh_status_q || exit 7        $1        ;;    force-reload)        force_reload        ;;    status)        rh_status        ;;    condrestart|try-restart)        rh_status_q || exit 0            ;;    *)        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"        exit 2esac#==================================================================================而后为此脚本赋予执行权限:# chmod +x /etc/rc.d/init.d/nginx添加至服务管理列表,并让其开机自动启动:# chkconfig --add nginx# chkconfig nginx on而后就可以启动服务并测试了:# service nginx start

Nginx的相关配置

配置文件的组成部分:

主配置文件:

  • nginx.conf

  • include conf.d/*.conf (这里没有指明)

fastcgi,uwsgi,scgi等协议相关的配置文件

mime.types:支持的mime类型

主配置文件的配置指令:

格式:

  • directive value [value2 ...];

注意:

指令必须以分号结尾;

支持使用配置变量;

  • 内建变量:由Nginx模块引入,可直接引用;

  • 自定义变量:由用户使用set命令定义;

            set variable_name value;

            引用变量:$variable_name

主配置文件结构:

http协议相关的配置结构(所有和web相关的都要在这里配置)

演示:

[root@centos7 ~]# cd /etc/nginx/[root@centos7 nginx]# lsconf.d     fastcgi.conf          fastcgi_params          koi-utf  mime.types          nginx.conf          scgi_params          uwsgi_params          win-utfdefault.d  fastcgi.conf.default  fastcgi_params.default  koi-win  mime.types.default  nginx.conf.default  scgi_params.default  uwsgi_params.default[root@centos7 nginx]# cp nginx.conf{,.bak} # 备份主配置文件[root@centos7 nginx]# vim nginx.conf # 编辑配置文件                       # 主配置段如下:  1                2 #user  nobody;  3 worker_processes  1;       4   5 #error_log  logs/error.log;  6 #error_log  logs/error.log  notice;  7 #error_log  logs/error.log  info;  8   9 #pid        logs/nginx.pid; 10  11  12 events { 13     worker_connections  1024; 14 } 15  16# ======================================================================== 17           # http配置段    http { 18     include       mime.types; 19     default_type  application/octet-stream; 20  21     #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ' 22     #                  '$status $body_bytes_sent "$http_referer" ' 23     #                  '"$http_user_agent" "$http_x_forwarded_for"'; 24  25     #access_log  logs/access.log  main; 26  27     sendfile        on; 28     #tcp_nopush     on; 29  30     #keepalive_timeout  0; 31     keepalive_timeout  65; 32  33     #gzip  on; 34  35     server { 36         listen       80; 37         server_name  localhost; 38  39         #charset koi8-r; 40  41         #access_log  logs/host.access.log  main; 42  43         location / { 44             root   html; 45             index  index.html index.htm; 46         }   ......

Nginx主配置段详述

主配置段(main block)

分类:

  • 正常运行必备的配置

  • 优化性能相关的配置

  • 用于调试及定位问题相关的配置

  • 事件驱动相关的配置

正常运行必备的配置:

性能优化相关的配置:

示例:

  1.worker_cpu_affinity auto [cpumask] ...;

 [root@centos7 ~]# vim /etc/nginx/nginx.conf   #user  nobody;    worker_processes  2;    worker_cpu_affinity 00000001 00000010; (# 表示仅用0号和1号cpu)    # 测试语法并重载nginx[root@centos7 ~]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@centos7 ~]# nginx -s reload# 查看进程,可见只有两个worker[root@centos7 ~]# ps auxroot       1127  0.0  0.3  47604  3512 ?        Ss   17:38   0:00 nginx: master process nginxnginx      1171  0.0  0.3  50180  3932 ?        S    17:51   0:00 nginx: worker processnginx      1172  0.0  0.3  50180  3932 ?        S    17:51   0:00 nginx: worker process[root@centos7 ~]# ps axo pid,comm,psr   PID COMMAND         PSR  1171 nginx             0  1172 nginx             1  =============================================================================================# worker_cpu_affinity auto 表示nginx启动自己选择好一颗cpu绑定[root@centos7 ~]# vim /etc/nginx/nginx.conf   #user  nobody;    worker_processes  auto;    worker_cpu_affinity auto;[root@centos7 ~]# ps axo pid,comm,psr   PID COMMAND         PSR      1235 nginx             0  1236 nginx             1  1237 nginx             2  1238 nginx             3

 2.worker_priority number;

 [root@centos7 ~]# ps axo pid,comm,psr  PID COMMAND           PSR  NI  1235 nginx             0   0  1236 nginx             1   0  1237 nginx             2   0  # 默认nice为0  1238 nginx             3   0  [root@centos7 ~]# vim /etc/nginx/nginx.conf   #user  nobody;    worker_processes  auto;    worker_cpu_affinity auto;        worker_priority -5;  # 修改nice为-5 [root@centos7 ~]# nginx -s reload[root@centos7 ~]# ps axo pid,comm,psr,nice   PID COMMAND         PSR  NI  1296 nginx             0  -5  1297 nginx             1  -5  1298 nginx             2  -5  # 变为-5  1299 nginx             3  -5

调试、定位问题:

事件驱动相关的配置:引入了新的上下文,定义在events{...}zhong 

http协议配置详述:

 1.(核心模块)

配置结构:

与套接字相关的配置

server { ... },配置一个虚拟主机

listen PORT|address[:port]|unix:/PATH/TO/SOCKET_FILE

server_name name ...;

tcp_nodelay on | off; 无延迟

  • 在keepalived模式下的连接是否启用TCP_NODELAY选项;

  • 建议为on(表示不启用打包多个小包为一个打包发送,无延迟,用户请求即相应)

sendfile on | off;

  • 表示是否启用sendfile功能;

  • sendfile 表示直接在内核级别封装资源传送给客户端,在效率上要高很多。

  • 优化nginx:建议启用 on

演示:

配置基于端口的虚拟主机

 1.首先创建虚拟主机的根目录,并提供页面文件

[root@centos7 ~]# mkdir -pv /vnhosts/www{1,2}mkdir: created directory ‘/vnhosts’mkdir: created directory ‘/vnhosts/www1’mkdir: created directory ‘/vnhosts/www2’[root@centos7 ~]# echo "www1.taotao.com" > /vnhosts/www1/index.html[root@centos7 ~]# echo "www2.taotao.com" > /vnhosts/www2/index.html[root@centos7 ~]# cat /vnhosts/www1/index.htmlwww1.taotao.com[root@centos7 ~]# cat /vnhosts/www2/index.htmlwww2.taotao.com

 2.编辑配置文件/etc/nginx/nginx.conf

[root@centos7 ~]# vim /etc/nginx/nginx.conf   # 定义两个基于端口的虚拟主机             server { 84         listen 8080; 85         server_name www1.taotao.com; 86         root /vnhosts/www1; 87     } 88     server { 89         listen 8088; 90         server_name www2.taotao.com; 91         root /vnhosts/www2; 92     }

 3.定义好之后保存退出,测试语法,重载,并查看端口8080和8088

[root@centos7 ~]# nginx -t # 测试语法nginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@centos7 ~]# nginx -s reload # 重载[root@centos7 ~]# ss -tnl # 查看端口8080和8088State       Recv-Q Send-Q                                      Local Address:Port                                                     Peer Address:Port              LISTEN      0      25                                                      *:514                                                                 *:*                  LISTEN      0      128                                                     *:8080                                                                *:*                  LISTEN      0      128                                                     *:80                                                                  *:*                  LISTEN      0      128                                                     *:22                                                                  *:*                  LISTEN      0      128                                             127.0.0.1:631                                                                 *:*                  LISTEN      0      128                                                     *:8088                                                                *:*                  LISTEN      0      100                                             127.0.0.1:25                                                                  *:*                  LISTEN      0      128                                             127.0.0.1:6010                                                                *:*                  LISTEN      0      25                                                     :::514                                                                :::*                  LISTEN      0      128                                                    :::22                                                                 :::*                  LISTEN      0      128                                                   ::1:631                                                                :::*                  LISTEN      0      100                                                   ::1:25                                                                 :::*                  LISTEN      0      128                                                   ::1:6010                                                               :::*

 浏览器访问如下:

后续内容将详见将继续介绍nginx中http配置段的内容,谢谢关注!!!