首页 > 代码库 > 初识nginx

初识nginx

先来一波官方站点关于nginx介绍。nginx相关历史这里不再赘述啦。

 

nginx 是免费,开源,高性能 HTTP 服务器和反向代理服务器,也可作为IMAP/POP3代理服务器。nginx以它的高性能,稳定性,丰富的特征设定,配置简单和资源消耗低而著称。

 nginx是为数不多可以解决C10K问题的服务器。不像传统服务器,nginx不依赖线程处理请求。它使用的是更为高明事件驱动(异步)架构。在高负荷下,也能保持低消耗,更重要的是可预估的内存占用量。如果你不期望去解决上千的并发请求难题,你也可以从nginx的高性能,低消耗而尝到好处。nginx应用规模可大可小:小至 VPS,大至组建服务器集群。

 了解nginx架构

nginx为什么是高性能,低消耗的,可解决高并发问题 

首先是master/worker二层架构,master负责加载配置文件、管理worker进程、平滑升级;worker负责 处理请求。而且是基于事件驱动模型设计的处理模型,这使得

worker数量和cpu核心数相当即可,但是一个worker进程可以同时处理多个请求,在高并发访问的情况下使用较少的资源从容应对。

简单来讲,异步非阻塞,事件驱动机制是其核心特征。

同时nginx拥有一套缓存机制,可以进一步降低网络压力,加速用户响应。

模块化设计 

 nginx总体设计理念秉承模块化设计思想,把各功能细分模块进行开发,实现灵活地装卸载所需模块,方便后续功能拓展。

nginx模块 分为五类

1)核心模块

2)标准http模块

3)可选http模块

4)mail模块

5)第三方模块

 安装nginx

rpm包,官方预制,下载地址: http://nginx.org/packages

编译安装:编译安装根据需要选择编译的模块,因人而异,下例仅供参考
~]# yum install pcre-devel openssl-devel zlib-devel
~]# useradd -r nginx
~]#  ./configure --prefix=/usr/local/nginx  --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

 了解nginx配置

 主配置文件:nginx.conf从此处为入口,开始你的nginx配置吧。主配置文件中,使用include命令引用分支配置文件。

 nginx配置风格为划地而治,要严格按照模块为区域进行配置

配置结构如下:

main block:主配置段,也即全局配置段;
event {
...

事件驱动相关的配置;

 }

http {
...

http/https 协议相关的配置段; 

}
mail {
...

mail相关模块

       } 

stream {
...

tcp/udp 传输层负载均衡配置段; 

}

再来讲讲配置语法

directive      value...;  #语法格式

(1) 指令必须以分号结尾;
(2) 支持使用配置变量;
内建变量:由Nginx模块引入,可直接引用;
自定义变量:由用户使用set命令定义;
set variable_name value;
引用变量:$variable_name

 内建变量传送门:http://nginx.org/en/docs/varindex.html  数量繁多,用起来也是非常方便滴,想用什么变量,来这里查查。

 配置nginx,从基础开始————

主配置段

1、定义进程用户,用户组

user   username  usergroup;

默认为nobody。 指定一个系统用户。

 2、定义主程序pid文件路径

pid /PATH/TO/PID_FILE;

3、 引入分支配置文件

include file;

~ include  conf.d/*.conf      ####“~”在本文中表示配置实例语句####

 4、装载动态模块

load_modulefile;

~  load_module modules/ngx_mail_module.so;

 5、error 日志

error_logfile[level]

~ error_log logs/error.log  info 

主配置段中,性能调优的指令 

 1、指定worker数量

worker_processes number | auto;

数量最宜和cpu核心数相同。

2、绑定worker与cpu核心对应关系

worker_cpu_affinity auto | cpumask; 

 如果不设置此项,worker会在不同的工作内核上切换,这会造成不必要的开销,将它们固定起来就好,一般设置为auto即可。

worker_cpu_affinity0001 0010 0100 1000   #指定cpumask例子

3、指定worker进程的nice值 范围[-20,20]

worker_priority number; 

 4、设置worker打开文件数量限制

worker_rlimit_nofile  number;

 ~ worker_rlimit_nofile   2390251

当然系统内核参数要改大,sysctl -w fs.file-max=2390251;sysctl -p

 Event 区域设置

 1、每个worker进程所能够打开的最大并发连接数数量;

worker_connections number;

~ worker_connections  65535; #一般设置为65535,最大端口数量

2、指明并发连接请求的处理方法;

use method;

~ use epoll; #linux平台
3、网络连接序列化

accept_mutex  on | off;

处理新的连接请求的方法;on表示开启网络连接序列化,避免“惊群”效应——即一个新连接请求,所有worker进程都被激活。建议开启

 4、多路接收

multi_accept  on|off;

 on表示一个worker同时接受尽可能多的请求。建议开启

Http区域设置----进阶开始

1、配置虚拟主机:server

 使用server指令配置虚拟主机,一般格式如下:

server {
  listen address[:PORT]|PORT;
  server_name SERVER_NAME;
  root /PATH/TO/DOCUMENT_ROOT;

}

1.1 listen 指令

配置监听地址,端口指令

有三种形式:

1) listen  address[:port] [args..];

  监听在指定IP,指定端口;当端口省略时,监听所有端口

2) listen  port [args...];

  监听主机所有IP的80端口

3) listen unix:path  [args...];

  监听unix socket,一种本机内部通信IPC机制,非重点。

-----介绍上面[args] 内容:

listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]

default_server: 标识符,表示此虚拟主机为address:port 的默认主机

ssl:标识符,虚拟主机使用https协议通信时,标识此项

backlog=number:设置允许同时最大网络监听连接处于挂起状态的个数,默认为511

rcvbuf=size:设置监听socket接收缓冲区大小

sndbuf=size:设置监听socket发送缓冲区大小

-----小结:

一般listen 指令无需太过复杂

~ listen 10.1.0.1:8080 default_server  backlog=1024

~ listen  8080;

1.2 server_name 指令

使用server_name 指令配置基于名称或基于IP的虚拟主机

1)基于名称的虚拟主机

格式: server_name   name...   允许跟多个名称,空格符分隔

------name支持glob通配符*

*可以出现在三段式名称中的首段或尾段;以及两段式名称中的尾段

server_name  *.cutemsyu.com  www.cutemsyu.*  cutemsyu.*;

------name支持正则表达式~

以~起始表示正则表达式标记

server_name  ~^www\d+\.cutemsyu\.com$

其中\d代表数字0-9,像这样的表达式可匹配www1.cutemsyu.com,www2.cutemsyu.com 等等

拓展:nginx 支持name 正则表达式字符捕捉功能

server_name  ~^([^.]+)\.cutemsyu\.com$

如此定义,当该表示式匹配www.cutemsyu.com 名称时,在server块中可使用$1 表示 www 字符串

-----关于一个名称被多个表达式匹配的问题

如果一个主机配置多个虚拟主机,则有可能发生此种情况

nginx有如下server_name 匹配规定:

对于一个名称匹配多个表达式情况,按以下规则处理,排在前面优先级高

1.准确匹配

2.左侧*通配符

3.右侧*通配符

4.正则表达式

如果被同一级别的多个表达式匹配,则按第一个匹配的表达式处理

2)基于IP的虚拟主机

用法: server_name  IP;

1.3 配置请求根目录指令:root

 root指令定义根路径目录,可定义在http,server,location块;

语法:root  path;

web服务器接收到请求后,首先在根目录下寻找资源。后面会介绍location块,root在location用到的情况比较多。

2、配置location块

用法:

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

应用在server块中,或在location块中嵌套使用。

在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置;

uri部分方便下面叙述,称不含正则表达式的uri为标准uri;反之,含有正则的uri称为正则uri,而且正则uri 前必须使用~或~*。同时支持正则字符串捕捉,使用$1等应用。

[ = | ~ | ~* | ^~ ] 这部分符号是具有特殊定义的符号,表示特定含义,可省略。

server接收到一个请求uri后,先与所有标准uri进行匹配,并记录匹配度最高的一个。然后按序与正则uri进行匹配,匹配到第一个正则uri后,立即按相应location块处理。如果所有正则匹配失败,则应用之前记录的标准uri对应的location块进行处理。

1) =    使用在标准uri前,表示精准匹配,如果请求uri与此对应,则该请求立即由该location块进行处理,不再与正则uri匹配。

2) ~    使用在正则uri前,并且区分大小写字母

3) ~*  使用在正则uri前,不区分大小写字母

4) ^~  使用在标准uri前,要求与标准uri匹配,找到匹配度最高的一个后不进行与正则uri匹配

如,对于"/" 的请求较多的话,使用以下定义

  location = / {

    ....

  }

则能实现快速匹配。

看一看nginx官方文档给出的例子:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

请求URI            应用的location配置

/                configuration A

/index.html                 configuration B

/documents/document.html   configuration C

/images/1.gif           configuration D

/documents/1.jpg              configuration E

 

至于@name 形式的location,是用来处理重定向类型的请求。在try_files 指令中会提到。

3、路径重定向类的指令

3.1 路径别名 alias

用法: alias  path;

定义路径别名,文档映射的另一种机制;仅能用于location上下文。

与root 指令容易混淆。参考下面示例

  location /data {

    alias  /documents/www;

    }

请求uri为/data/index.html,则nginx服务器将在路径 /documents/www 下寻找index.html 文件。

3.2 设置网站默认首页

作用是用户不需输入完整的uri来访问默认主页

用法: index  filename... ;

可设置多个默认网页,如果前一个页面文件不存在则显示下一页面文件,以此类推。

3.3 错误页面重定向

用法:error_page code ... [=[response]] uri|path;

当客户端访问遇到问题时,nginx支持自定义错误页面显示,并返回一个指定状态码,如果指定的话。

作用域为 http,server,location 。具有在子域有效的特征。

  Example:

error_page 404             /404.html;
error_page 500 502 503 504 /50x.html;

此示例跳转的资源使用相对路径方式,意味着从定义的根路径下查找文件。

  Example:

error_page 404 =200 /empty.gif;

此示例指定转换的状态码。

  Example:

error_page 404 = /404.php;

如果响应的错误状态码来自代理服务器,或者FastCGI/uwsgi/SCGI 服务器,应使用该示例方式返回代理服务器返回的状态码。

  Example:

error_page 403      http://example.com/forbidden.html;
error_page 404 =301 http://example.com/notfound.html;

该示例重定向为一个指定uri。此种情况重定向的状态码为302。可修改为 301,302,303,307。

3.4 尝试查找文件

用法: try_files file ... uri;

    try_files file ... =code;

按顺序检查文件,如果都不存在,则定向最后一个参数。最后一个参数如果是文件则必须存在;可以是状态码;内部重定向。

  example:

location /images/ {
    try_files $uri /images/default.gif;
}
location / {
    try_files $uri $uri/index.html $uri.html =404;
}

  example:重定向型

location / {
    try_files $uri $uri/ @wordpress;
}

location ~ \.php$ {
    try_files $uri @wordpress;         #这里使用重定向,如果请求的资源页不在会自动跳转@wordpress块中的index.php。如果使用uri的话,不会显示动态资源页面。

    fastcgi_pass ...;

    fastcgi_param SCRIPT_FILENAME /path/to$fastcgi_script_name;
    ... other fastcgi_param‘s
}

location @wordpress {
    fastcgi_pass ...;

    fastcgi_param SCRIPT_FILENAME /path/to/index.php;
    ... other fastcgi_param‘s
}

4、套接字相关配置

   作用域:httpserverlocation

4.1  tcp_nodelay on | off;

  在keepalived模式下的连接是否启用TCP_NODELAY选项;默认开启;建议开启

4.2  sendfile   on|off;

  是否开启sendfile 特性,减少数据在内核与用户空间之间的copy次数。建议开启。详见标题6内容

4.3  sendfile_max_chunk  size;

  worker process 每次调用sendfile() 传输数据的最大值,减少一次调用sendfile()最大阻塞时长,0为不限制,建议设置128K

5、定义客户端请求的相关配置

作用域:httpserverlocation

 

5.1  keepalive_timeout timeout [header_timeout];
  设定保持连接的超时时长,0表示禁止长连接;默认为75s;header_timeout 可选项,在应答报文首部中表示keepalive超时时间

5.2  keepalive_requests number;
  在一次长连接上所允许请求的资源的最大数量,默认为100;

5.3  keepalive_disable none | browser ...;
  对哪种浏览器禁用长连接;

5.4  send_timeout time;
  向客户端发送响应报文的超时时长,此处,是指两次写操作之间的间隔时长;如果客户端在规定时长内无任何活动则关闭连接

  send_timeout 10s;

5.5  client_header_buffer_size  size;
  设置客户端请求报文首部缓冲区大小,默认值为1K。有时客户端请求首部带有cookie很大的信息,会造成400错误,强烈建议增大大小

  大小设置为系统分页大小,命令 getconf PAGESIZE 可查看

  一般设置为 client_header_buffer_size 4K;
5.6  client_body_buffer_size size;
  用于接收客户端请求报文的body部分的缓冲区大小;默认为16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令所定义的位置;

5.7  client_body_temp_path path [level1 [level2 [level3]]];
  设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量;16进制的数字;

  client_body_temp_path path  /var/tmp/client_body  1 2 2   #可定义在高性能磁盘分区上

6、文件操作优化的配置

作用域:httpserverlocation

6.1  aio on | off | threads[=pool];
  是否启用aio功能;

6.2  directio size | off;
  在Linux主机启用O_DIRECT标记,此处意味文件大于等于给定的大小时使用,例如directio 4m;

6.3  directio_alignment size;

  为directio设置 alignment 大小,默认512字节,一般不用调整。但是xfs 文件系统需要增大至4k

--------这里花一定篇幅讲讲aio,directio,和sendfile之间的关系-------

首先aio和sendfile是互相排斥的。启用aio,必须也启用directio,不然的话read()将成为阻塞。

sendfile适合小文件,占用的是系统缓存。当传输大文件时,而且系统内存不够大的情况,使用sendfile()将较不适宜。此时应使用aio机制。

推荐的一个配置示例:文件小于8M,使用sendfile,大于或等于8M使用aio

location /video/ {
    sendfile       on;
  sendfiel_max_chunk 256K; aio on; directio 8m;
  output_buffers 1 128k;
}

特别地,在大文件传输较多的情况下,适宜启用aio  threads 。nginx编译需要--with-threads 选项

location /video/ {
    sendfile       on;
  sendfiel_max_chunk 256K; aio threads; #这里使用默认的线程池,可自行创建。 directio 8m;
  output_buffers 1 128k;
}


6.4  open_file_cache off;
open_file_cache max=N [inactive=time];
nginx可以缓存以下三种信息:
(1) 文件的描述符、文件大小和最近一次的修改时间;
(2) 打开的目录结构;
(3) 没有找到的或者没有权限访问的文件的相关信息;

max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现缓存管理;

inactive=time:缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_users指令所指定的次数的缓存项即为非活动项;

6.5 open_file_cache_valid time;
缓存项有效性的检查频率;默认为60s;

6.6  open_file_cache_min_uses number;
在open_file_cache指令的inactive参数指定的时长内,至少应该被命中多少次方可被归类为活动项;

6.7  open_file_cache_errors on | off;
是否缓存查找时发生错误的文件一类的信息;

  Example:

open_file_cache          max=1000 inactive=20s;
open_file_cache_valid    30s;
open_file_cache_min_uses 2;
open_file_cache_errors   on;

 

本篇就介绍到这里,nginx余下内容请关注后续博客。

 

 

 

 

初识nginx