首页 > 代码库 > NGINX基础(一)

NGINX基础(一)


NGINX基础

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

概述:





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模型

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

技术分享

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

技术分享

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

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

技术分享5). 异步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的安装配置

官方的预制包:

  • http://nginx.org/packages/centos/7/x86_64/RPMS/

编译安装: 

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

  • # 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

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

技术分享

Nginx的相关配置

配置文件的组成部分:

  • 主配置文件:

      nginx.conf

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

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

  • mime.types:支持的mime类型

主配置文件的配置指令:

  格式:directive value [value2 ...];

  注意:

   (1)指令必须以分号结尾;

   (2)支持使用配置变量;

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

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

          set variable_name value;

          引用变量:$variable_name

主配置文件结构:

  main block:# 主配置段,也即全局配置段;
	     event {
		   ...# 事件驱动相关的配置;
	     }:
  
  # http/https 协议相关的配置段; 
  http {
          ...
    }
  
  # 邮件配置段;
   mail {
          ...
    }
  
  # tcp/udp等相关协议的配置段
   stream {
	  ...
    }

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

技术分享

演示如下:

[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各配置段详述

1.主配置段(main block)

main配置段常见的配置指令:

分类:

  • 正常运行必备的配置

  • 优化性能相关的配置

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

  • 事件驱动相关的配置


正常运行必备的配置:

技术分享


性能优化相关的配置:

技术分享

示例:

  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

调试、定位问题:

技术分享


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

技术分享

2.http协议的相关配置:

配置结构:

技术分享


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


与套接字相关的配置


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.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                                                               :::*

 浏览器访问如下:

技术分享

技术分享






NGINX基础(一)