nginx的基本详解

时间:2022-11-01 04:37:13

nginx简介

  Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的。从2004年发布至今,凭借开源的力量,已经接近成熟与完善。Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。

  nginx可以作为反向代理、负载均衡和web缓存使用,本节主要讲解nginx的负载均衡功能,按照不同的负载策略可以分发到不同的后端服务器。负载均衡的结构图如下图所示:

nginx的基本详解

配置文件详解

1、全局块

  配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。

user
语法: user user [group]
缺省值: nobody nobody
指定Nginx Worker进程运行用户,默认是nobody帐号。

error_log
语法: error_log file [ debug | info | notice | warn | error | crit ]
缺省值: ${prefix}/logs/error.log
指定错误日志的存放位置和级别。

include
语法: include file | *
缺省值: none
include 指令还支持像下面配置一样的全局包含的方法,例如包含一个目录下所有以".conf"结尾的文件: include vhosts/*.conf;
pid

语法: pid file
进程id存储文件。可以使用 kill -HUP cat /var/log/nginx.pid/ 对Nginx进行配置文件重新加载。

worker_processes
语法: worker_processes number
缺省值: 1,指定工作进程数。nginx可以使用多个worker进程(建议与本机CPU核心数一致)。

  实例

user  root root;
worker_processes  24;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;
pid        logs/nginx.pid;

2、events块

  配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。

events

{
use epoll;
使用epoll的I/O 模型。linux建议epoll,FreeBSD建议采用kqueue,window下不指定。
补充说明:与apache相类,nginx针对不同的操作系统,有不同的事件模型
A)标准事件模型
Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll
B)高效事件模型
Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
Epoll:使用于Linux内核2.6版本及以后的系统。
/dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。

worker_connections 204800;
每个工作进程的最大连接数量。根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为。worker_processes*worker_connections

keepalive_timeout 60;
keepalive超时时间。

client_header_buffer_size 4k;
客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
分页大小可以用命令getconf PAGESIZE 取得。

open_file_cache max=65535 inactive=60s;
#这个是指多长时间检查一次缓存的有效信息。
#语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.

open_file_cache_valid 80s;
#open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。

open_file_cache_min_uses 1;
#语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location  这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.

open_file_cache_errors on;
#语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.
}

  实例

events {
    worker_connections  65535;
}

3、http块

  可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。

1)http中的全局变量

http
{
include mime.types;
设定mime类型,类型由mime.type文件定义
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format log404 '$status [$time_local] $remote_addr $host$request_uri $sent_http_location';
日志格式设置。
$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
$remote_user:用来记录客户端用户名称;
$time_local: 用来记录访问时间与时区;
$request: 用来记录请求的url与http协议;
$status: 用来记录请求状态;成功是200,
$body_bytes_sent :记录发送给客户端文件主体内容大小;
$http_referer:用来记录从那个页面链接访问过来的;
$http_user_agent:记录客户浏览器的相关信息;
通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

access_log  logs/host.access.log  main;
access_log  logs/host.access.404.log  log404;
用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径;

server_names_hash_bucket_size 128;
#保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.

client_header_buffer_size 4k;
客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。

large_client_header_buffers 8 128k;
客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。

open_file_cache max=102400 inactive=20s;
这个指令指定缓存是否启用。
例: open_file_cache max=1000 inactive=20s; 

open_file_cache_valid 30s; 
语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.

open_file_cache_min_uses 2; 
语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location 这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.

open_file_cache_errors on;
语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.

client_max_body_size 300m;
设定通过nginx上传文件的大小

sendfile on;
sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。

tcp_nodelay on;
tcp_nopush on;
此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用

keys_zone=cache_one:200m inactive=1d max_size=30g;
#设置内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。

keepalive_timeout 120;
keepalive超时时间。

client_body_buffer_size 512k;
如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,
8k或者16k,问题就出现了。无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误 #http_proxy模块
。。。。。。 #gzip模块 。。。。。。 upstream bakend { 。。。。。。。 } #server模块 。。。。。 }

2)gzip模块

gzip_static on;
gzip_http_version   1.0;
gzip_proxied        expired no-cache no-store private auth;
gzip_vary           on;
gzip  on;
gzip_types text/plain text/css text/xml application/xml application/xml+rss application/json;
gzip_min_length 1100;
gzip_buffers 4 8k;

  gzip on|off
  # 默认值: gzip off 
  # 开启或者关闭gzip模块

  gzip_static on|off

  # nginx对于静态文件的处理模块
  # 该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。该模块启用后,nginx首先检查是否存在请求静态文件的gz结尾的文件,如果有则直接返回该gz文件内容。为了要兼容不支持gzip的浏览器,启用gzip_static模块就必须同时保留原始静态文件和gz文件。这样的话,在有大量静态文件的情况下,将会大大增加磁盘空间。我们可以利用nginx的反向代理功能实现只保留gz文件。
  #可以google"nginx gzip_static"了解更多

  gzip_comp_level 4

  # 默认值:1(建议选择为4)
  # gzip压缩比/压缩级别,压缩级别 1-9,级别越高压缩率越大,当然压缩时间也就越长(传输快但比较消耗cpu)。

  gzip_buffers 4 16k
  # 默认值: gzip_buffers 4 4k/8k 
  # 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。 例如 4 4k 代表以4k为单位,按照原始数据大小以4k为单位的4倍申请内存。 4 8k 代表以8k为单位,按照原始数据大小以8k为单位的4倍申请内存。
  # 如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。

  gzip_types mime-type [mime-type ...]

  # 默认值: gzip_types text/html (默认不对js/css文件进行压缩)
  # 压缩类型,匹配MIME类型进行压缩
  # 不能用通配符 text/*
  # (无论是否指定)text/html默认已经压缩 
  # 设置哪压缩种文本文件可参考 conf/mime.types

  gzip_min_length  1k
  # 默认值: 0 ,不管页面多大都压缩
  # 设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。
  # 建议设置成大于1k的字节数,小于1k可能会越压越大。 即: gzip_min_length 1024

  gzip_http_version 1.0|1.1

  # 默认值: gzip_http_version 1.1(就是说对HTTP/1.1协议的请求才会进行gzip压缩)
  # 识别http的协议版本。由于早期的一些浏览器或者http客户端,可能不支持gzip自解压,用户就会看到乱码,所以做一些判断还是有必要的。 
  # 注:99.99%的浏览器基本上都支持gzip解压了,所以可以不用设这个值,保持系统默认即可。
  # 假设我们使用的是默认值1.1,如果我们使用了proxy_pass进行反向代理,那么nginx和后端的upstream server之间是用HTTP/1.0协议通信的,如果我们使用nginx通过反向代理做Cache Server,而且前端的nginx没有开启gzip,同时,我们后端的nginx上没有设置gzip_http_version为1.0,那么Cache的url将不会进行gzip压缩

  gzip_proxied [off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any] ...
  # 默认值:off
  # Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含"Via"的 header头。
  off - 关闭所有的代理结果数据的压缩
  expired - 启用压缩,如果header头中包含 "Expires" 头信息
  no-cache - 启用压缩,如果header头中包含 "Cache-Control:no-cache" 头信息
  no-store - 启用压缩,如果header头中包含 "Cache-Control:no-store" 头信息
  private - 启用压缩,如果header头中包含 "Cache-Control:private" 头信息
  no_last_modified - 启用压缩,如果header头中不包含 "Last-Modified" 头信息
  no_etag - 启用压缩 ,如果header头中不包含 "ETag" 头信息
  auth - 启用压缩 , 如果header头中包含 "Authorization" 头信息
  any - 无条件启用压缩

  gzip_vary on
  # 和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩

  gzip_disable "MSIE [1-6]."

  #禁用IE6的gzip压缩,又是因为杯具的IE6。当然,IE6目前依然广泛的存在,所以这里你也可以设置为“MSIE [1-5].”

  #IE6的某些版本对gzip的压缩支持很不好,会造成页面的假死,今天产品的同学就测试出了这个问题后来调试后,发现是对img进行gzip后造成IE6的假死,把对img的gzip压缩去掉后就正常了为了确保其它的IE6版本不出问题,所以建议加上gzip_disable的设置

3)upstream模块

    作为负载均衡池,可以为一个请求分配多个负载,防止单台服务器宕机后请求无法处理,负载均衡的策略有:轮询、加权轮询和哈希一致,配置如下:

#加权轮询
upstream back_openaccess {
                server 10.159.39.136:12080 weight=2 max_fails=3 fail_timeout=10s;
                server 10.159.39.137:12080 weight=2 max_fails=3 fail_timeout=10s;
        }
#ip_hash
upstream back_openadmin {
                ip_hash;
		server 10.159.39.136:12081;
                server 10.159.39.137:12081;
        }

  加权轮询配置参数:

  down 表示单前的server暂时不参与负载.

  weight 默认为1.weight越大,负载的权重就越大。

  max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误.

  fail_timeout : max_fails次失败后,暂停的时间。

  backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

  max_conns:限制分配给某台Server处理的最大连接数量,超过这个数量,将不会分配新的连接给它。默认为0,表示不限制。注意:1.5.9之后的版本才有这个配置

4)server模块

    server {
        listen       80;
        server_name  "127.0.0.1";
        root   /kingdee/www/;
        #Open underscores_in_headers
        underscores_in_headers on;
        proxy_redirect off;  
        include  conf.d/*.conf;

	location /ngs {
        	stub_status on;
        	access_log on;
        }

        location /upss {
        	check_status;
        	access_log off;
        }
    }

  listen:监听端口,默认80,小于1024的要以root启动。可以为listen *:80listen 127.0.0.1:80等形式。

  server_name:服务器名,如localhost、www.example.com,可以通过正则匹配。

  root:设定响应的根目录。

  include:引入其他的配置文件。  

  underscores_in_headers:支持读取非nginx标准的用户自定义header的,但是需要在http或者server下开启header。

  proxy_redirect:语法:proxy_redirect [ default|off|redirect replacement ] ,默认值:proxy_redirect default ,修改被代理服务器返回的响应头。例如:proxy_redirect http://localhost:8000/two/ http://frontend/one/;将Location字段重写为http://frontend/one/。

  location:根据请求的RUI设置配置,进行负载均衡。location中的配置参数如下:

     1、proxy_set_header参数:语法为:proxy_set_header Field Value。常见的设置如: 

      proxy_set_header Host $proxy_host;

       获取nginx配置中的server_name值。

      proxy_set_header X-Real-IP $remote_addr;

      有了这个配置就可以在web服务器端获得用户的真实ip 

      proxy_set_header X-Forwarded-For $remote_addr;

      我们先看看这里有个X-Forwarded-For变量,这是一个squid开发的,用于识别通过HTTP代理或负载平衡器原始IP一个连接到Web服务器的客户机地址的非rfc标准,如果有做X-Forwarded-For设置

      的话,每次经过proxy转发都会有记录,格式就是client1, proxy1, proxy2,以逗号隔开各个地址,由于他是非rfc标准,所以默认是没有的,需要强制添加,在默认情况下经过proxy转发的请求,在后端看

      来远程地址都是proxy端的ip 。也就是说在默认情况下我们使用request.getAttribute("X-Forwarded-For")获取不到用户的ip,如果我们想要通过这个变量获得用户的ip,我们需要自己在nginx添加配置。

    2、proxy_pass:转发的代理路径

        情况一、location /test/ { 
                      proxy_pass http://t6:8300; 
              }
        情况二、location /test/ { 
                      proxy_pass http://t6:8300/; 
             }

        针对情况2,如果访问url = http://server/test/test.jsp,则被nginx代理后,请求路径会变为 http://proxy_pass/test.jsp,直接访问server的根资源 

        针对情况1,如果访问url = http://server/test/test.jsp,则被nginx代理后,请求路径会便问http://proxy_pass/test/test.jsp,将test/ 作为根路径,请求test/路径下的资源   

5)proxy_buffer模块

proxy_buffer_size 256k;
设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
proxy_buffers 4 256k;
设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
proxy_busy_buffers_size 256k;
proxy_connect_timeout 90; 
后端服务器连接的超时时间_发起握手等候响应超时时间

proxy_read_timeout 180;
连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)

proxy_send_timeout 180;
后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据

proxy_temp_file_write_size 256k;
设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长

proxy_temp_path /data0/proxy_temp_dir;
proxy_temp_path和proxy_cache_path指定的路径必须在同一分区

  1. proxy_buffering

  语法:proxy_buffering on|off

  默认值:proxy_buffering 0n

  该 指令开启从后端被代理服务器的响应内容缓冲。如果缓冲区开启,nginx假定被代理的后端服务器会以最快速度响应,并把内容保存在由指令 proxy_buffer_size 和 proxy_buffers指定的缓冲区里边.如果响应内容无法放在内存里边,那么部分内容会被写到磁盘上。如果缓冲区被关闭了,那么响应内容会按照获取 内容的多少立刻同步传送到客户端。nginx不尝试计算被代理服务器整个响应内容的大小,nginx能从服务器接受的最大数据,是由指令 proxy_buffer_size指定的.对于基于长轮询(long-polling)的Comet 应用来说,关闭 proxy_buffering 是重要的,不然异步响应将被缓存导致Comet无法工作。

  2. proxy_buffers

  语法:proxy_buffers  数量  大小

  默认值:proxy_buffers 8  4k/8k

  该指令设置缓冲区的大小和数量,从被代理的后端服务器取得的响应内容,会放置到这里. 默认情况下,一个缓冲区的大小等于内存页面大小,可能是4K也可能是8K,这取决于平台。

  3. proxy_buffer_size

  语法:proxy_buffer_size  the size

  默认值:proxy_buffer_size 4k/8k

  该指令设置缓冲区大小,从代理后端服务器取得的第一部分的响应内容,会放到这里.小的响应header通常位于这部分响应内容里边.默认来说,该缓冲区大小等于指令 proxy_buffers所设置的;但是,你可以把它设置得更小.

  4. proxy_busy_buffers_size

  语法:proxy_busy_buffers_size                大小

  默认值:proxy_busy_buffers_size  proxy_buffer_size*2

  buffer 工作原理

  1. 所有的proxy buffer参数是作用到每一个请求的。每一个请求会安按照参数的配置获得自己的buffer。proxy buffer不是global而是per request的。

  2. proxy_buffering 是为了开启response buffering of the proxied server,开启后proxy_buffers和proxy_busy_buffers_size参数才会起作用。

  3. 无论proxy_buffering是否开启,proxy_buffer_size(main buffer)都是工作的,proxy_buffer_size所设置的buffer_size的作用是用来存储upstream端response的header。

  4. 在proxy_buffering 开启的情况下,Nginx将会尽可能的读取所有的upstream端传输的数据到buffer,直到proxy_buffers设置的所有buffer们 被写满或者数据被读取完(EOF)。此时nginx开始向客户端传输数据,会同时传输这一整串buffer们。同时如果response的内容很大的 话,Nginx会接收并把他们写入到temp_file里去。大小由proxy_max_temp_file_size控制。如果busy的buffer 传输完了会从temp_file里面接着读数据,直到传输完毕。

  5. 一旦proxy_buffers设置的buffer被写入,直到buffer里面的数据被完整的传输完(传输到客户端),这个buffer将会一直处 在busy状态,我们不能对这个buffer进行任何别的操作。所有处在busy状态的buffer size加起来不能超过proxy_busy_buffers_size,所以proxy_busy_buffers_size是用来控制同时传输到客户 端的buffer数量的。4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。

Nginx的部分模块

stub_status模块

  stub_status模块主要用来展示nginx的状态信息也就是nginx的统计信息。配置信息如下:

location /ngs {
    stub_status on;
    access_log on;
        }

  在输入域名/ngs后会展示nginx的统计信息如下:

nginx的基本详解

  Active connections: 当前nginx正在处理的活动连接数.
  Server accepts handled requests request_time: nginx总共处理了13057 个连接,成功创建13057 握手(证明中间没有失败的),总共处理了11634 个请求,总共请求时间2230854。
  Reading: nginx读取到客户端的Header信息数.
  Writing: nginx返回给客户端的Header信息数.
  Waiting: 开启keep-alive的情况下,这个值等于 active – (reading + writing),意思就是nginx已经处理完成,正在等候下一次请求指令的驻留连接。所以,在访问效率高,请求很快被处理完毕的情况下,Waiting数比较多是正常的.如果reading +writing数较多,则说明并发访问量非常大,正在处理过程中。