天天看点

1.Nginx基础(一)

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协议回顾:

1.Nginx基础(一)

I/0模型介绍

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

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

 消息通知:

  • 同步:等待对方返回消息; 
  • 异步:被调用者通过状态、通知或回调机制通知调用者被调用者的运行状态;

★阻塞/非阻塞:

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

  • 阻塞:blocking,调用结果返回之前,调用者被挂起;
  • 非阻塞:nonblocking,调用结果返回之前,调用者不会被挂起;
★一次IO请求,都会由两阶段组成:
  • 第一步:等待数据,即数据从磁盘到内核内存;
  • 第二步:复制数据,即数据内核内存到进程内存; 
★复用型IO调用:
  • select():1024
  • poll():

★I/O模型

⊙阻塞I/O模型 

应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。 

如果数据没有准备好,一直等待。。。。 

数据准备好了,从内核拷贝到用户空间 

I/O函数返回成功指示

1.Nginx基础(一)

⊙非阻塞I/O模型 

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

1.Nginx基础(一)

⊙I/O复用模型 

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

1.Nginx基础(一)

⊙信号驱动I/O模型 

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

1.Nginx基础(一)

⊙异步I/O模型 

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

1.Nginx基础(一)
★5个I/O模型的比较
1.Nginx基础(一)

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程序架构图

1.Nginx基础(一)

Nginx的安装配置

★官方的预制包:
  • http://nginx.org/packages/centos/7/x86_64/RPMS/
★编译安装: 
  • 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]# ls
nginx-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]# ls
auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  man  README  src

# 如上可以看到目录中的文件和我们之前编译过的程序大体相同,也同样遵循三步曲
首先我们查看 ./configure --help 查看常用的选项      

 1.在执行之前我们还要创建一个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-aio

Configuration 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 -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: 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      

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

1.Nginx基础(一)

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

make_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 2
esac

#==================================================================================
而后为此脚本赋予执行权限:
# 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

★主配置文件结构:

1.Nginx基础(一)
☉http协议相关的配置结构(所有和web相关的都要在这里配置)
1.Nginx基础(一)

演示:

[root@centos7 ~]# cd /etc/nginx/
[root@centos7 nginx]# ls
conf.d     fastcgi.conf          fastcgi_params          koi-utf  mime.types          nginx.conf          scgi_params          uwsgi_params          win-utf
default.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.Nginx基础(一)
⊙性能优化相关的配置:
1.Nginx基础(一)

示例:

  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 -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@centos7 ~]# nginx -s reload
# 查看进程,可见只有两个worker
[root@centos7 ~]# ps aux
root       1127  0.0  0.3  47604  3512 ?        Ss   17:38   0:00 nginx: master process nginx
nginx      1171  0.0  0.3  50180  3932 ?        S    17:51   0:00 nginx: worker process
nginx      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      
⊙调试、定位问题:
1.Nginx基础(一)
⊙事件驱动相关的配置:引入了新的上下文,定义在events{...}zhong 
1.Nginx基础(一)

http协议配置详述:

 1.ngx_http_core_module(核心模块)

★配置结构:
1.Nginx基础(一)

★与套接字相关的配置

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

1.Nginx基础(一)
⊙listen PORT|address[:port]|unix:/PATH/TO/SOCKET_FILE
1.Nginx基础(一)
⊙server_name name ...;
1.Nginx基础(一)
⊙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.html
www1.taotao.com
[root@centos7 ~]# cat /vnhosts/www2/index.html
www2.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 ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@centos7 ~]# nginx -s reload # 重载

[root@centos7 ~]# ss -tnl # 查看端口8080和8088
State       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                                                               :::*      

 浏览器访问如下:

1.Nginx基础(一)
1.Nginx基础(一)

后续内容将详见http://1992tao.blog.51cto.com/11606804/1866443,将继续介绍nginx中http配置段的内容,谢谢关注!!!

继续阅读