Linux之nginx

Nginx简介

解决基于进程模型产生的C10K问题,请求时即使无状态连接如web服务都无法达到并发响应量级一万的现状,2006年由俄罗斯lgor sysoev编写,全称为engine X, 缩写为nginx,官方站点为http://nginx.org,2013年发出企业版本Nginx Plus. 二次发行版本:Tengine, OpenResy....

Nginx特性

  • 1 模块化设计,较好的扩展性,早期不支持模块的动态装卸载
  • 2 高可靠性,基于master/worker模式
    • master:负责启动服务,分析配置文件,负责启动子进程和worker进程
    • worker: 真正响应用户请求进程
  • 3 支持热部署(平滑迁移):不停机更新配置文件,更换日志文件,更新服务器程序版本
  • 4 内存消耗低: 10K个keep-alive连接模式下的非活动连接仅消耗2.5M内存
  • 5 支持event-driven事件驱动模型,aio驱动机制,mmap内存映射机制

Nginx基本功能

  • 1 静态资源的web服务器,自身只能简单的接收和响应http
  • 2 http协议的反向代理服务器
  • 3 pop3,smtp imap4等邮件协议的反向代理
  • 4 能缓存打开的文件(元数据缓存:文件的描述符等信息),能加快文件的打开速度
  • 5 支持FastCGI(php-fpm),UWSGI(python web framwork框架)等协议机制,实现代理后端应用程序交互
  • 6 模块化(非DSO机制)
standard HTTP modules 标准(核心)HTTP模块:自动编译进程序不止一个
Optional HTTP modules 可选http模块
Mail modules 邮件模块
3rd party modules 第三方模块,在编译时需手动指明加载方式加载
  • 7 支持过滤器,例如ZIP,SSI(服务端包含)
  • 8 支持SSL加密机制

web服务相关的功能

  • 虚拟主机(server)
  • keepalive
  • 支持访问日志
  • 支持基于日志进行缓冲,以提高日志的存取性能
  • url rewrite
  • 路径别名
  • 基于IP及用户的访问控制
  • 支持速率限制(每客户端连接速度)
  • 支持并发数限制(每客户端的并发连接)

Nginx的基本架构:master/worker

master/worker模型:
  • 一个master进程可以生成一个或多个worker进程,每个worker基于事件驱动,linux(epoll),freeBSD(kqueue),solaris(/dev/poll)响应用户请求, 其支持sendfile,sendfile64,这两种支持的文件大小不同

  • master负责内容:

    • 加载配置文件
    • 管理worker进程
    • 平滑升级
  • worker负责内容

    • 响应客户端请求
    • 提供http服务
    • 提供http代理
    • 提供fastcgi代理
nginx工作原理图
img

Nginx编译安装配置

环境准备
  • yum install -y "Development Tools"
  • yum install -y "Server platform development"
  • yum install -y pcre-devel openssl-devel zlib-devel
  • useradd -r nginx
  • 检查Linux系统上epoll机制是否存在
Nginx的编译及安装
./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx  --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-debug

make && make install
Nginx的配置文件
  • /etc/nginx/nginx.conf : 主配置文件
    • Include conf.d/*.conf
  • /etc/nginx/mime.types : 所支持的MIME类型列表
  • /etc/nginx/fastcgi_params : fastcgi的配置文件
  • /etc/nginx/fastcgi.conf : 与fastcgi_params一般只使用一个
  • /etc/nginx/uwsgi_params : 与uwsgi框架的配置文件
  • /etc/nginx/scgi_params : cgi的配置文件
  • /etc/nginx/proxy.conf : 代理的配置
  • /etc/nginx/sites.conf : 配置虚拟主机的
/etc/nginx/nginx.conf配置文件的一般格式:
  • 1 全局指令 : 放置于main block中,即文档根

  • 2 模块指令 : 由模块引用,其它必须放置于directive中

  • 3 Directive Value1 [Value2,....]

  • 4 支持使用变量:

    • 内置变量: 由模块引入
    • 自定义变量(较新版本支持)
      • set variable value;
    • 引用 变量: $variable
  • 5 每条指令都以;号结束,否则就是语法错误

  • 6 主配置文件组织结构

    main block : 不能放在花括号中,正常运行必备的配置,优化性能相关的配置,用于调度,定位问题的配置.
    
    event {
        ...
    }      
    
    #事件驱动模块段,面向用户并发连接请求响应组织配置机制
    
    http {
        ...
    }
    
    #web模块相关配置
    
    mail {
        ...
    }
    
    #邮件模块相关配置, 编译时候默认无此模块
    
    
  • 7 Nginx HTTP configuration示意图:


    img

主配置文件框架解析

Main配置段常用参数
  • (1) 正常运行必备的配置指令

    • uesr USERNAME [GROUPNAME];
      • 指定用于运行worker进程的用户和组,默认是nginx用户,nginx组
    • pid /path/to/pid_file;
      • 指定nginx进程的PID文件路径, 默认为:pid /var/runl/nginx/nginx.pid
    • worker_rlimit_nofile #;
      • 指定每个worker进程能打开的最大文件描述符数量(nofile: number of file)
    • worker_rlimit_sigpending #;
      • 指定每个用户能够发往worker进程的信号的最大数量
  • (2) 性能优化相关的配置

    • woker_processes #;

      • worker进程的个数,通常应该为物理CPU核心数量减1或者减2,worker_processes auto;可以根据物理CPU自动设定. worker不使用进程或线程处理请求, 而是直接将worker绑定到CPU上, 这样就没有进程切换的说法了.
    • worker_cpu_affinity CPUMASK CPUMASK...;

      • 将worker进程与指定的CPU进行绑定,这种绑定不能隔离CPU,CPU还可能会响应其它进程请求.
      示例:
          worker_cpu_affinity 00000001 00000010 00000100;
      
    • worker_priority NICE;

      • [-20,19],worker进程的优先级, 默认为0
  • (3)调试定位问题的配置

    • daemon [off|on];
      • 是否以守护进程方式启动nginx
    • master_process [on | off];
      • 是否以master/worker模型运行nginx,off后,只单个进程启动Nignx.
    • error_log /path/to/error_log Level;
      • 错误日志文件及级别, 出于调试的需要,可以设定为debug,但在debug级别在编译时使用--with-debug选项时才有效
event配置段常用参数
  • worker_connections #;
    • 每个worker进程所能够响应的最大并发请求数量, 请求的最大上限为:worker_processes * worker_connections
  • use [epoll | rgsig | select | poll]]
    • 定义使用的事件模型, 建议让nginx自动选择
  • accept_mutex [on | off];
    • 定义内部调用请求至worker时请求的互斥锁文件(各worker接收用户的请求的负载均衡锁),on:能够让多个worker轮流地,序列化的响应新请求
  • lockfile /path/to/lockfile
    • 锁文件定义位置
http配置段常用参数
  • server {}

    • 定义一个虚拟主机,server可以出现一次或多次
    server {
        listen [IP:]PORT;
        server_name NAME;
        root /path/to/documentroot;
    }
    
  • listen address [:port] [default_server] [[ssl] [http2 | spdy]]

  • listen port [default_server] [ssl] [http2 | spdy]

    • default_server:设置默认虚拟主机, 当用户使用IP地址访问时,就返回default_server的虚拟主机, 如果未定义default_server时,第一个虚拟主机将做为默认的主机
    • ssl : 用于限制只能通过SSL连接提供服务,不是以端口确认其协议的, 故需要启用ssl,需要在监听的端口后面, 添加ssl选项
    • spdy : spdy protocol(google研发的http协议,比http/1.1性能要好, 全称为speedy),在编译时编译了spdy模块的情况下,用于支持spdy协议
    • http2 : http version2,在编译时需要开启http2协议支持
  • server_name NAME [....]; : 指明主机名称

    • servername后可跟一个或多个主机名, 名称还可以使用通配符和正则表达式(~),域名匹配顺序

      • (1) 先做精确匹配,例如:www.zhenping.me
      • (2) 左侧通配符,例如:*.zhenping.me
      • (3) 右侧通配符,例如:www.zhenping.*
      • (4) 正则表达式匹配,例如:~^.*.zhenping.me$
      • default_server
      nginx默认工作法则: 先将域的匹配规则,先做hash计算,把计算的结果放置进内存,下次访问请求过来时, 直接做对比
      
  • tcp_nodelay [on | off];

    • 对keepalive模式下的连接是否使用tcp_nodelay选项,默认关闭.其功能为:把多个小报文合并为一个报文,一起发送. 此机制可以提高带宽利用率,将发往同一个主机很小的TCP报文合并成一个,实际生产对于用户请求即使浪费带宽也不能合并请求
  • tcp_nopush [on | off];

    • 是否启用tcp_nopush(FreeBSD)或tcp_cork(linux)选项,仅在sendfile为on时有用, 其功能:尝试将多个报文首部压缩成一个发送, 默认为off,不启用该功能
  • sendfile [on | off];

    • 是否启用sendfile功能,静态文件直接在内核中封装响应,而不是从内核空间到用户空间封装后,再发往内核空间.
  • roo /PATH/TO/Directory;

    • 设置web资源的路径映射,用于指明请求的URL所对应的文件的目录路径,可用于server或location中.
    示例:
        server {
            ...
            root /www/html;
        }
        
        http://www.zhenping.me/images/logo.jpg --> /www/html/images/logo.jpg
        
        
        server {
            ...
            server_name www.zhenping.me;
            location /images/ {
                root /www/html;
                ...
            }
        }
        
        http://www.zhenping.me/images/logo.jpg --> /www/html/images/logo.jpg
    
  • location [ = | ~ | ~* | ^~ ] url { ...}

  • location @name {...}

    • 允许根据用户请求的URI来匹配定义的各location,匹配到时, 此请求将被相应的location块中的配置所处理, 简言之:用于为需要用到专用配置的uri提供特定配置.
    • 当匹配多次时,其匹配优先级为:精确匹配=,^,或~*,不带符号的URL, 如果优先级都一样, 就匹配最精确的规则
      • = : URI的精确匹配
      • ~ : 做正则表达式匹配,区分字符大小写
      • ~* : 做正则表达式匹配,不区分字符大小写
      • ^~ : URI的左半部分匹配,不区分字符大小写
    location = / {
        [configuration A]
    }
    
    location / {
        [configuration B]
    }
    
    location /documents/ {
        [configuration C]
    }
    
    location ^~ /images/ {
        [configuration D]
    }
    
    location ~* \.(gif|jpg|jpeg)$ {
        [configuration E]
    }
    
  • alias

    • 只能用于location配置段,用于定义路径别名
    location /imags/ {
        root /data/imgs/;
    }
    
    location /imags/ {
        alias /data/imgs/;
    }
    
    注意: root指令:给定的路径对应location的"/",这个URI
            /imags/test.jpg --> /data/imgs/imags/test.jpg
          alias指令:路径为对应的location的"/url/"这个URI
            /imags/test.jpg --> /data/imgs/test.jpg
    
  • index

    • 设置默认主页(nginx_http_index_module模块引入), 可以带上变量,如$geo根据不同IP地址来设置不同的语言主页,应用上下文为:http,server,location
    index index.html index.php;
    
  • error_page code ...[=[response]] uri;

    • 自定义错误页面,根据http状态码重写向错误页面
    示例:
        1) 指明错误页面
            error_page 404 /404.html;
            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
                root html;
            }
        2) 根据指定的响应状态码进行响应
            error_page 404 = 200 /404.html;
            
    
  • try_files file... uri;

  • try_files file... =code;

    • 可用于server,location中, 以指定的顺序检查文件的存在性响应
    • 尝试查找第1至第N-1个文件,第一个即为返回给请求者的资源,若1至N-1文件都不存在, 则跳转至最后一个uri(必须 不能匹配至当前location,而应该匹配至其它location,否则会导致死循环)
    示例:
        server {
            listen 80 default_server;
            server_name www.zhenping.me;
            root /data/imgs/;
            index index.html;
            location /images/ {
                try_files index.html /images/test1.html /images/test2.html /images/test3.html;
            }
            
            location = /images/test3.html {
                expires 10s;
            }
            
    
面向客户端请求相关的配置
  • keepalive_disable none | browser;

    • 禁止那些浏览器使用keepalive功能,如: keepalive_disable msie6
  • keepalive_timeout #s;

    • 设定keepalive连接的超时时长,0表示禁止长连接,默认启用为75s
  • keepalive_requests #;

    • 在keepalive连接上所允许请求的最大资源数量,默认为100;
  • send_timout #;

    • 发送响应报文的超时时长,默认为60s;
  • client_body_buffer_size SIZE(8k | 16k);

    • 接收客户请求报文body的缓冲区大小, 默认为16k(64位系统,32位系统为8K),超出指定大小时将被移存于磁盘上.
  • client_body_temp_path [Level1 [level2 [level3]]]

    • 设定用于存储客户端请求body的临时存储路径及子目录结构和数量
    client_body_temp_path /var/tmp/client_body 2 2;
    
        表示一级子目录用2字符表示,二级子目录下用2字符表示,每级目录都有256个文件夹. 其是采用16进制的表示文件,1个字符最多表示16,2字符表示256
    
对客户端请求进行限制
  • limit_except METHOD {...};

    • 对指定范围之外的其它方法进行访问控制,应用于location上下文
    limit_except GET {
        allow 172.16.0.0/16;
        deny all;
    }
    
  • limit_rate SPEED;

    • 限制客户端每秒种所能够传输的字节数, 默认为0,表示不限制,应用于http,server,location,if in location上下文中
    server {
        ...
        if ($slow) {
            set $limit_rate 4k;
        }
    }
    
  • limit_rate_after SIZE;

    • 超出SIZE的值, 就限制速度,应用于http,server,location,if in locataion上下文中
    location /flv/ {
        flv;
        limit_rate_after 500k;
        limit_rate 50k;
    }
    
文件操作优化相关的配置
  • aio on | off;

    • 是否启用异步IO模式, 应用于http, server,location上下文中
  • directio size | off;

    • 是否启用直接IO操作, 不在内存中缓冲, 直接从硬盘加载使用(当大于指定的size),应用于http,server,location
  • open_file_cache off | max=N [inactive=time];

    • 对打开的文件进行缓存 ,nginx可以缓存以下三种信息

      • (1) 文件描述符
      • (2) 文件大小
      • (3) 最近一次的修改时间
      • (4) 打开的目录的结构
      • (5) 没有找到或者没有权限操作的文件的相关信息
    • max=N : 可缓存的最大条目上限,一旦达到上限, 则会使用LRU算法从缓存中删除最近最少使用的缓存项

    • inactive=time : 在此处指定的时长内没有被访问过的缓存项识别为非活动缓存项, 因此直接删除

  • open_file_cache errors on|off;

    • 是否缓存找不到其路径的文件,或没有权限访问的文件相关信息
  • open_file_cache_valid time;

    • 每隔多久检查一次缓存中缓存项的有效性,默认为60秒
  • open_file_cache_min_uses number;

    • 缓存项在非活动其限内最少应该被访问的次数
ngx_http_access_module模块的配置(基于IP的访问控制)
  • allow address | CIDR | unix: | all; 允许

  • deny address | CIDR | unix: | all; 拒绝

    • 应用上下文件:http,server,location,limit_except
    示例:
        location / {
            deny 192.168.1.1;
            allow 192.16.1.0/24;
            allow 10.1.1.0/16;
            allow 2001:0db8::32;
            deny all;
        }
    
ngx_http_auth_basic_module模块的配置(basic认证)
  • auth_basic string | off;

    • 用户定义认证的名称,string为所给定字符,其作用在于认证时显示的提示信息
  • auth_basic_user_file FILE;

    • 实现用户认证的用户及帐号文件,文件格式如下(需手动创建):
    name1:password1
    name2:password2:comment
    
    • 密码可以使用httpd程序自带的工具htpasswd创建
    示例:
        location /admin/ {
            auth_basic "Admin Area";
            auth_basic_user_file /etc/nginx/.htpasswd;
        }
        
        ~]# htpasswd -c -m /etc/nginx/.htpasswd tom
        ~]# htpasswd -m /etc/nginx/.htpasswd jerry
        
    
ngx_http_log_module模块的配置(访问日志)
  • log_format name string....;

    • 定义日志格式及其名称,日志格式一般通过调用内置变量来定义,默认格式为combined
  • access_log path [format[buffer=size [flush=time]]];

  • access_log off

    • 定义日志文件路径,格式名称以及缓存大小和刷写时间间隔,建议定义缓冲以提升性能
  • open_log_file_cache max=N [inactive=time] [min_uses] [valid=time];

  • open_log_file_cache off;

    示例:
        access_log /var/log/nginx/$host;
        access_log /var/log/nginx/www.zhenping.me.gz combined gzip flush=5m;
    
ngx_http_stub_status_module模块配置(stub_status)

启用stub_status功能, 只能用于server,location中,通过指定的URL输出stub_status

示例:
    location /status/ {
        stub_status on;
    }
    
    http://www.zhenping.me/status
  • status的信息:
Active connections: 1 
server accepts handled requests
 2 2 18 
Reading: 0 Writing: 1 Waiting: 0 
  • 各参数说明
    • active connections : 当前活动的客户端连接数,包括等待的.
    • accepts : 已接受的客户端的连接总数量
    • handled : 已处理完成的客户端连接请求总数量
    • requests : 客户端总的请求数
    • reading : 当前正在读取的客户端请求报文首部信息的数量
    • writing : 当前正在向客户端发送响应报文的连接数量
    • wating : 等待其发出请求的空闲连接数量
ngx_http_referer_module模块配置

基于请求报文中的referer首部的值, 做访问控制 ,可以防止盗链,其只应用于server,location上下文

  • referer_hash_bucket_size SIZE;

    • 可以放多个缓存我要上,默认是64
  • referer_hash_max_size SIZE;

    • 默认2048
  • valid_referers none|blocked|server_names|string...;

    • none : 请求的报文不存在referer首部
    • blocked : 请求报文中存在referer首部,但其没有有效值,或其值非以http://或https开头
    • server_names :其值为一个主机名
    • arbitrary string : 直接字符串,可以使用*号匹配
    • rugular expression : 以~起始的正则表达式
    注意: 内置变量:$invalid_referer(所有不能符合valid_referer指定定义的引用请求均为不合法引用),需要加上条件判断语句
        示例:
            valid_referers none blocked server_name *.example.com example.* www.example.org/aglleries/ ~\.google\.;
            if ($invalid_referer) {
                return 403;
            }
    
ngx_http_ssl_module模块配置
  • listen 443 ssl;

    • 在指定端口上启用必须ssl连接
  • server_name www.zhenping.me;

    • ssl主机的FQDN名称
  • ssl_certificate cert.pem;

    • ssl的公钥
  • ssl_certificate_key cert.key;

    • ssl的私钥
  • ssl_session_cache off | none | [builtin[:size]] [shard:name:size];

    • 默认使用shared模式
    • off : 禁止缓存 ,关闭缓存,不支持缓存功能
    • none :禁止缓存 ,不响应缓存
    • builtin : 使用openssl内置的ssl会话缓存 ,此机制为各worker私有
    • shared: 在各worker之间使用一个共享的缓存,name:独有名称,size:缓存空间大小, 默认为1M,可以调到10M
    示例: ssl_session_cache shared:ssl:1m;
    
  • ssl_session_timeout 5m;

    • ssl会议超时时长,即ssl session cache中的缓存有效时长,默认为5m
  • ssl_prefer_server_ciphers on;

    • 优先使用服务端选择的加密算法
  • ssl on | off;

    • 启用或关闭ssl,若不在listen处定义,也可以在server{ }中定义ssl on; 来启用https服务
  • ssl_buffer_size SIZE;

    • ssl缓冲大小
  • ssl_ciphers CIPHERS;

    • 指明由nginx使用的加密算法,可以是openssl库所支持各加密套件
  • ssl_client_certificate file;

    • 需要验证客户端证书
  • ssl_crl FILE;

    • 证书吊销列表
  • ssl_protocols [sslv2][sslv3][tlsv1][tlsv1.1][tlsv1.2];

    • 使用哪些协议版本, 默认为TLSv1,TLSv1.1,TLSv1.2
  • ssl_trusted_certificate FILE;

    • 信任的根证书
  • ssl_session_ticket_key FILE;

ngx_http_rewrite_module模块配置(URL重写)

将请求的url基于正则表达式进行重写(URL重定向),在如下情况下可以使用:http转换成httpd服务(http-->https),域名转换domain.tld -->domain2.tld, URL转换uri --> uri2,实现SEO搜索引擎优化效果.... 将用户请求的URL基于正则表达式进行重写

  • rewrite regex replacement [flag];

    • 应用于server,location,if上下文
    • regex : 基于perl的正则表达式,用于匹配用户请求的URL;
      • PCRE正则表达式元字符
        • 字符: .,[],[^]
        • 次数: *,+,?,{m},{m,}{m,n}
        • 位置锚定: ^,$
        • 或者: |
        • 分组: (), 后向引用: $1,$2,.....
    • replacement : 重写为的结果
    • flag:标志位
      • last : 重写完成之后停止对当前uri的进一步处理,改为对新uri的新一轮处理(对URI的重写规则进行匹配,当检查到第一条匹配到的时候,进行重写.然后返回到重写规则的第一条位置进行重新匹配,如果有匹配到的再进行重写,默认只能10次匹配). 此过程用户端感受不到.
      • break : 对URI的重写规则进行匹配,只要匹配到就重写,不再进行再次匹配,此过程用户端感受不到.
      • redirect : 重写完成之后返回客户端一个临时重定向,由客户端对新的URI重新发起请求, 即302的状态码
      • permanent : 重写完成之后,会返回客户端一个永久的重写向,由客户端对新的URI重新发起请求,即301的状态码
    示例1:
        server {
            ...
            rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
            rewrite ^(/download/.*)audio(.*)\..*$ $1/mp3/$2.ra last;
            return 403
            ....
        }
            
        http://www.zhenping.me/download/a/b/c/media/32.wmv --> /download/a/b/c/mp3/32.mp3
    示例二:
        server {
            rewrite ^/bbs/(.*)$ /forum/$1;
        }
        
    示例三:
        server {
            ...
            rewrite ^/bbs/(.*)$ https://www.baidu.com/ redirect;
        }
        
    另外重写:
        rewrite ^/images/(.*)$ http://www.zhenping.me/imgs/$1 redirect;
    
        rewrite ^/download/?(.*)$ http://www.zhenping.me/imgs/$1 break; 
    
        rewrite ^(/.*)$ http://www.baidu.com break;
    
    
    
    
    
  • if(condition) {...} :条件判断,引用新的配置上下文

    • condition比较表达式:
      • ==, !=
      • ~ : 模式匹配,区分字符大小写
      • ~* : 模式匹配,不区分字符大小写
      • !~ : 模式不匹配, 区分字符大小写
      • !~* : 模式不匹配,不区分字符大小写
    • 文件及目录判断:
      • -f,!-f : 是否存在且为普通文件
      • -d,!-d : 是否存在且为目录
      • -e,!-e : 是否存在
      • -x,!-x : 是否存在且可执行
    实例:
        1) cookie首部检测匹配
            if($http_cookie ~* "id=([^;]+)(?:;l$)") {
                set $id $1;
            }
        2) 请求报文的请求方法是POST,返回405
            if($request_method = POST) {
                return 405;
            }
        3) 限速
            if($slow) {
                limit_rate 10k;
                break;
            }
        4) 非法引用,返回403,注:也可以对非法引用到其它页面
            if($invalid_referer) {
                return 403;
            }
        5) 根据IE类型重写
            if($http_user_agent ~ MSIE) {
                rewrite ^(.*)$ /msie/$1 break;
            }
    
  • return : 立即停止对请求的URI的处理,并返回指定的状态码

    • returncode [text];
    • returncode URL
    • return URL;
  • set : 设定变量值,或者自定义变量

    • set $variable value;
  • rewrite_log on | off;

    • 是否将重写日志记录errorlog中,默认为关闭(调试方法:错误日志debug,并开启rewrite_log)
ngx_http_gzip_module模块的配置(压缩功能)
  • gzip on | off;
    • 启用或禁用gzip压缩响应报文
  • gzip_buffers number size;
    • default 32位系统4k,64位系统8k
  • gzip_comp_level LEVEL;
    • 压缩比,1-9,默认为1
  • gzip_disable regex ...;
    • regex是为用于匹配客户端响应器类型的正则表达式,表示对何种浏览器禁止使用压缩功能
  • gzip_min_length LENGTH;
    • 触发压缩功能的响应报文的最小长度
  • gzip_http_version 1.0 | 1.1;
    • 设定启用压缩功能的最小版本
  • gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etg | auth | any ...;
    • 定义对客户端请求的具有何种请求属性的资源启用压缩功能,如expired表示:对由于使用expire首部而无法缓存的对象启用压缩功能
  • gzip_types mime.type;
    • 指明对那些类型的资源进行压缩
示例:
    http {
        ....
        gzip on;
        gzip_http_version 1.0;
        gzip_comp_level 6;
        gzip_disable msie6;
        gzip_types text/plain text/css text/xml application/x-javascript application/xml application/json application/java-script;
        gzip_min_length 2;
    }

ngx_http_fastcgi_module模块配置(LNMP架构搭建)

fastcgi_module只能对后端的一台应用服务器进行反代,如果需要给多台应用服务器进行反代实现负载,需借助upstream模块定义一组服务器,由fastcgi功能引用来完成, lnmp的架构中, ningx只支持fastcgi的模式连接后端php服务器,不能将应用服务运行为一个子模块的方式.nginx不支持动态加载模块机制(DSO),所以需要编译php工作为fpm机制时,将ngnx_http_fastcgi_module编译到nginx程序中,在php编译时需使用 --enable-fpm,将Php设置为fpm模式.

  • LNMP架构仅支持一种nginx+php的结合方式,实现方式如下:

    server {
      ...
      location ~* \.php$ { 
          ...
      }
    }
    
  • php-fpm程序包

    php-fpm包提供fcgi模式的Php程序包端,其不能和php程序包同时安装 ,rpm形式安装完成后提供主配置文件/etc/php-fpm.conf,分段配置文件/etc/php-fpm.d/*

    • /etc/php-fpm.d/www.conf配置文件说明
      • ; : ;开始的行表示注释行
      • listen = 127.0.0.1:9000 : 监听端口,0.0.0.0表示本机所有地址
      • ;listen.backlog = -1 : 后援等待队列长度,-1表示无限制
      • listen.allowed_clients = 127.0.0.1 : 授权允许可请求主机,基于IP的控制机制,注释表示允许所有
      • ;listen.owner = nobody : 监听服务进程的主机默认以什么用户身份运行,nobody表示普通用户
      • ;listen.group = nobody : 监听服务进程的主机默认以什么用户组身份运行
      • ;listen.mode = 0666 : 监听服务进程的主机默认以什么权限运行
      • user = apache : 用户,LNMP的架构时建议修改为nginx
      • group = apache : 组, LNMP的架构时建议修改为nginx
      • pm = static | dynamic : fpm的工作方式
        • static : 固定数量子里程, 只有pm.max_children有效
        • dynamic : 类prefork模型的工作方式
          • pm.start_servers = : 开始启用进程数
          • pm.min_spare_servers= : 最小空闲进程数
          • pm.max_spare_servers= : 最大空闲进程数
          • ;pm.max_requests= :每个子进程最多允许响应多少请求,超过就kill
      • ;pm.status_path = /status : 状态机制
      • ;ping.path = /ping : ping机制,一般用于提供监控机制
      • php_admin_value[error_log]= : 连接池错误日志位置
      • php_admin_flag [log_errors] = on : 是否在错误日志中将于管理相关的标志打开
      • php_value[session.save_handler] = files : php的session记录存放形式: 文件
      • php-value[session.save_path]= :php的session记录存放路径,集群是关键
  • fastcgi模块指令:

    • fastcgi_pass address;

      • address为fastcgi server监听的地址,如: fastcgi_pass localhost:9000;
    • fastcgi_index NAME;

      • 定义fastcgi应用的默认主机,如: fastcgi_index index.php;
    • fastcgi_param PARAMETER VALUE[if_not_empty];

      • 用户定义客户端请求的哪些属性传递给后端fastcti_server
      示例:
          fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
          fastcgi_param QUERY_STRING $query_string;
      
      示例:
          server {
              ...
              index index.php index.html;
              location ~ \.php$ {
                  root html;
                  fastcgi_pass 127.0.0.1:9000
                  fastcgi_index index.php;
                  fastcgi_param SCRIPT_FILENAME /data/www$fastcgi_script_name;
                  include fastcgi_params;
              }
          }
      
      • /etc/nginx/fastcgi_params配置文件
         Fastcgi_param REMOTE_ADDR  $remote_addr;
      
         Fastcgi-param REMOTE_PORT  $remote_port;
      
         Fastcgi_param SERVER_ADDR  $server_addr;
      
         Fastcgi_param SERVER_PORT  $server_port;
      
         Fastcgi_param  SERVER_NAME $server_name
      nginx通过参数将远程客户端的地址通过$remote_addr传递给REMOTE_ADDR变量,以便后端的php服务器引用 ,例如需要保存用户的session会话的时候,需要知道用户的地址
      
    • fastcgi_pass_header field;

      • 允许把fastcgi的响应首部直接发送给客户端
    • fastcgi_cache_path path [levels=levels][use_temp_path=on|off] keys_zone=name:size [inactive=time][max_szie=size];

      • 用于定义缓存,缓存 空间等,可应用于http上下文,需要运行php的用户对path有写权限.
      • 缓存机制:
        • 缓存对象名字都以16进制进行编码,故一级目录一般为16个或者256个
        • 元数据存在内存中,即为keys_zone
        • 数据存在硬盘,即为path
      • levels=#[:#[:#]] : 表示可以使用三级目录进行保存
      • keys_zone=name:size : name名称要全局唯一,cache的标识符
      • inactive=time : 缓存的非活动时间,缓存的访问次数在指定的time内比较少,就需要清理出去
      • max-size : 缓存空间上限,指磁盘的缓存空间上限
    • fastcgi_cache zone | off;

      • 调用定义过的缓存,zone即为通过fastcgi_cache_path定义缓存时其keys_zone参数中的name
    • fastcgi_cache_key string;

      • 定义那些键需要进行缓存,如用户访问的URI,如:fastcgi_cache_key $request_uri;
    • fastcgi_cache_methods GET|HEAD|POST...;

      • 为何种请求方法对应的请求进行缓存,默认为get和head
    • fastcgi_cache_min_uses number;

      • 缓存项的最少使用次数,默认为1次
    • fastcgi_cache_revalidate on |off;

    • fastcgi_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_503 | http_403 | http_404 | off;

      • 是否可使用stale缓存项(不新鲜)响应用户请求,默认是off
    • fastcgi_cache_valid [code...] time;

      • 对不同响应码的响应设定可缓存 时长
      fastcgi_caache_valid 200 302 10m;
      fastcgi_cache_valid 404 1m;
      
```
示例:
    http {
        ....
        fastcgi_cache_path /var/cache/fastcgi levels=1:1 keys_zone=fcache:10m inactive=5m max_size=1g;
        location ~ \.php$ {
            ....
            fastcgi_cache fcache
            fastcgi_cache_key $request_uri;
            fastcgi_cache_valid 202 302 10m;
            fastcgi_cache_valid 404 1m;
        }
    }
 ```
 
 * 缓存的设定及调用:
    
 ```
 首先使用fastcgi_cache_path设定缓存的存放路径,及内存中的存放名称,以便后面调用. 还需设置其它信息
 再分别使用:
    fastcgi_cache : 调用内存中存放的缓存名称
    fastcgi_cache_key : 以什么键来进行缓存
    fastcgi_cache_valid : 必须指定哪些状态码的响应才能进行缓存
 ```
ngx_http_proxy_module模块配置(http和https的代理 )

反向代理(reverse proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器, 并将从服务器上得到的结果返回给internet上请求连接的客户端,此时站在服务器角度来看,代理服务器对外就表现为一个反向代理服务器,对反向代理服务器的攻击并不会使得后端内网web服务器上网页信息破坏,增强了web服务器的安全性

  • proxy_pass URL;

    • 应用上下文:Location,if in location, limit_except
    1) 代理所有URI的请求至后端应用服务器:
    
    location / {
        proxy_pass http://172.16.100.68/;
    }
    
    2) 只代理指定URL到后端应用服务器
    
    location /name/ {
        proxy_pass http://172.16.100.68/remote/;
    }
        注意:请求的/name/ url将直接替换为/remote/,实际上是请求的/remote/目录下的资源
        
    location /name/ {
        proxy_pass http://172.16.100.68;
    }
        注意:请求/name/ url将直接请求后端backend服务根目录下的/name/路径
    
    • 如果location URI时使用正则表达模式匹配时, 其proxy_pass后面的路径一定不能带URI地址
    location ~* \.(jpg|gif|jpeg)$ {
        proxy_pass http://hostname;
    }
    
    • 如果location 中有rewrite重写,在proxy_pass后面的连接地址一定不能带URI地址, 那怕有/也不可以
    location /name/ {
        rewrite /name/([^/]) /users?name=$1 break;
        proxy_pass http://172.16.100.68;
    }
    
    If ($request_method ~*  PUT|POST) {
    
        Proxy_pass
    
    }
    
  • proxy_pass_header field;

    • 传递首部给客户端
  • proxy_hide_header field;

    • 有意隐藏首部
  • proxy_set_header field value;

    • 用于proxy_server向backend_server发请求报文时,将某请求首部重新赋值,或在原有值后面添加一个新的值
      • proxy_set_header HOST $http_host
        • $http_host代表客户端请求的哪个虚拟主机,即客户端发起报文首部中的host首部,将$request_host传递给host变量,再由代理服务器发起请求的时候,加入host首部(有的情况下代理服务器与backend服务器连接使用的IP地址, 这种传递host参数的情况下,代理发起的访问,都会转为默认的虚拟主机)
      • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        • 将客户端的真实IP地址赋值给X-Forwarded-For变量,代理请求的时候,将发送给后端的backend server.如果中间有多层代理 , 每经过一层代理时,代理服务器都会将在后面增加自己的IP地址,并以分号分隔开来
```
示例:
    一   利用nginx完成反向代理,并且通过poxy_set_header 参数将客户端真实IP地址传递给后端真实服务器
    server { 
        listen 80; 
        server_name www.zhenping.me; 
        root /www/html; 
        index index.php index.html; 
        access_log /var/log/nginx/access.log combined; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        location ~* /name/? { 
            proxy_pass http://172.16.36.72; 
        } 
    }
    
    二  在后端的真实服务器上需要修改日志的记录格式后,才能将客户端的真实IP记录下来

    LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"” combined
```
  • proxy_cache_path path [levels=levels][use_temp_path=on|off] keys_zone=name:size [inactive=time][max_size=size];

    • 定义缓存,可用于http上下文
  • proxy_cache zone | off;

    • 调用缓存,可用于http,server,location上下文
  • proxy_cache_key string;

    • 定义缓存键,默认为:proxy_cache_key $scheme$proxy_host$request_uri;

      • $scheme : 所使用的协议
      • $proxy_host : 请求的那个代理服务器地址
      • $request_uri : 向那个URI发出的请求,带参数的: www.zhenping.me?username=1&userid=1
      • $uri : 向那个URI发出的请求,不带参数
      proxy_cache_key "$host$request_uri$cookie_user";
      
      默认的缓存键会有一个问题, 它把域名整个作为一个键了, 当一个网站有多个域名时,如:www.magedu.com/download, www.mageedu.com/download都会做为单独的一个缓存结果,这样就重复缓存了,同时也降低了缓存的命中
      
  • `proxy_cache_valid [code...] time;

    • 对不同响应码设定其可缓存时长
    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 404 1m;
    
示例:
    http {
        ...
        proxy_cache_path /var/cache/proxy/ levels=1:2 keys_zone=pcache:10m max_size=1g;
        server {
            listen 80;
            server_name www.c.org c.org web.c.org;
            root /data/www;
            add_header via $server_addr;
            location / {
                proxy_pass http://172.16.100.68;
                proxy_cache pcahce;
                proxy_cache_key $request_uri;
                proxy_cache_valid 200 302 10m;
                proxy_cache_valid 404 1m;
            }
        }
    }
  • proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 |http_503 | http_504 | http_403 | http_404 | off...;
    • 定义如果后端服务器连接不成功,是否可以使用缓存数据进行响应
跟连接相关的选项
  • proxy_connect_timeout time;
    • 定义后端服务器建立连接的超时时长,默认为60s,此值不应该超过75s
  • proxy_send_timeout time;
    • 把请求发送给后端服务器的超时时长,默认为60s
  • proxy_read_timeout time;
    • 等待后端服务器发送响应报文的超时时长,如果有大量的502,就需要考虑这个时长是否过短
示例:
    http { 
        proxy_cache_path /var/cache/pcache levels=1:2 keys_zone=pcache:10m inactive=5m max_size=1g; 
        server { 
            listen 80; 
            server_name www.zhenping.me; 
            root /www/html; 
            index index.php index.html; 
            access_log /var/log/nginx/access.log combined; 
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
            location ~* /name/? { 
                proxy_pass http://172.16.36.72; 
                proxy_cache pcache; 
                proxy_cache_key $uri; 
                proxy_cache_valid 200 202 301 302 10m; 
                proxy_cache_valid 404 1m; 
                proxy_connect_timeout 60s; 
                proxy_send_timeout 60s; 
                proxy_read_timeout 60s; 
            } 
        }
    }
ngx_http_headers_module模块配置
  • add_header_name value [always]; : (其可操作响应报文首部)

    • 向响应报文添加自定义首部,并为其赋值,应用上下文为:http,server,location, if in location
    add_header Via $server_addr; 
    
  • expires [modified] time;

  • expires epoch | max | off;

    • 默认expires off, 允许或禁止向响应报文的cache-control或expires首部添加新值或修改其值
示例:
    http { 
        proxy_cache_path /var/cache/pcache levels=1:2 keys_zone=pcache:10m inactive=5m max_size=1g; 
        server { 
            listen 80; 
            server_name www.zhenping.me; 
            root /www/html; 
            index index.php index.html; 
            access_log /var/log/nginx/access.log combined; 
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
            location ~* /name/? { 
                proxy_pass http://172.16.36.72; 
                proxy_cache pcache; proxy_cache_key $uri; 
                proxy_cache_valid 200 202 301 302 10m; 
                proxy_cache_valid 404 1m; 
                proxy_connect_timeout 60s; 
                proxy_send_timeout 60s; 
                proxy_read_timeout 60s; 
                add_header Via $server_addr; 
                expires 30m; 
            } 
        } 
    }
ngx_http_upstream_module模块配置

用于将多个服务器定义成服务器组,而由proxy_pass fastcgi_pass等指令引用,应用于http上下文

  • upstream name {...};
    • 定义一个后端服务器组,name为组名称,仅用于http上下文
  • server address [parameters];
    • 在upstream中定义一个服务器及相关参数,仅能用于upstream上下文
    • 常用参数:
      • weight=number : 定义服务器权重,默认为1
      • max_fails=number : 最大失败连接尝试次数(做健康状态检测),失败连接超时时长由fail_timeout参数指定
      • fail_timeout=number : 等待目标服务器发送响应的时长,总的超时时长
      • backup : 备用服务器,所有主服务器均故障时,才启用此服务器(即sorry server)
      • down : 手动标记其不再处理任何用户请求
示例1:
    upstream backend {
        server backend1.example.com weight=5;
        server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
        server unix:/tmp/backend3;
        server backup1.example.com backup;
    }
    
示例2:
    upstream websrvs {
        server 172.16.100.68 weight=2 max_fails=2 fail_timeout=6s;
        server 172.16.100.6 weight=6 max_fails=2 fail_timeout=6s;
    }
    
    server {
        listen 80;
        server_name www.zhenping.me;
        root /data/www;
        add_header via $server_addr;
        location / {
            proxy_pass http://websrvs/;
        }
    }
  • ip hash

    • 源地址hash,把来自同一个IP地址的请求始终发往同一个backend server,除非backend server不可用
    upstream websrvs {
        server 172.16.100.68 weight=2 max_fails=2 fail_timeout=6s down;
        server 172.16.100.6 weight=6 max_fails=6 fail_timeout=6s;
        ip_hash;
    }
    
  • least_conn;

    • 最少连接,当各server权重不同时,即为加权最少连接
  • match name {...}

    • 对backend server做健康状态检测时,定义其结果判断机制,只能用于http上下文
    • 常用参数
      • status code[code...]; : 期望的响应状态码
      • header HEADER[oprator value] : 期望存在响应首部,也可对期望的响应首部值基于比较操作符和值进行比较
      • body : 期望响应报文的主体部分应该有的内容
  • health_check [parameters]; (较新版本中的nginx支持)

    • 健康状态检测机制,应用上下文:location
    • 常用参数
      • interval=time :检测的时间频率,默认为5秒钟
      • fails=number : 判定服务器不可用的失败检测次数,默认为1次
      • passes=number : 判定服务器可用的检测次数,默认为1次
      • uri=URI; : 应用层的检测,做健康状态检测测试的目标URI,默认为"/"
      • match=name : 健康状态检测的结果评估调用(match name {...}参数)指定的match配置块
示例:
    http {
        server
            ...
            location / {
                proxy_pass http://backend;
                health_check match=webcome;
            }
        }
        
        match welcome {
            status 200;
            header content-type = text/html;
            body ~ "welcom to nginx!";
        }
    }
  • hash key[consistent];
    • 应用于upstream中,指明基于hash方式进行调度时,其hash键, hash $remote_addr 相当于ip_hash;
    • 常用的hash key:
      • $cookie_name : 将一个用户的请求始终发往同一个backend server,能实现会话绑定的功能,此处的name为cookie中某些参数的名称,此处常用的有:cookie_username.
      • $request_method
      • $request_uri : 将对同一个uri的请求始终发往同一个backend server,后端为cache server时特别有用
      • $uri
示例: 实现动静分离
    http { 
        upstream http_servers { 
            server 172.16.36.71 weight=1 max_fails=2 fail_timeout=6s; 
            server 172.16.36.72 weight=2 max_fails=2 fail_timeout=6s; 
            # ip_hash; 
            } 
        server { 
            listen 80; 
            server_name www.zhenping.me; 
            root /www/html; 
            index index.php index.html; 
            access_log /var/log/nginx/access.log combined; 
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
            location ~* \.php$ { 
                proxy_pass http://172.16.36.72; 
            } 
            location / { 
                proxy_pass http://http_servers/; 
            } 
        }
session会议保持机制:
  • session sticky : 基于IP,nginx还可以基于请求报文首部中的多种信息,例如:cookie,uri
  • session cluster : 每个server均把其创建和维护的sesion同步集群中的其它主机,仅适用较小规模的环境
  • session server : 使用一个共享的存储服务存储session信息
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 1.简介:  Nginx:engine X ,2002年,开源,商业版 http协议:web服务器(类似于ht...
    尛尛大尹阅读 1,858评论 0 3
  • I/O模型Nginx介绍Nginx的安装和目录结构Nginx的配置Nginx的编译安装 一、I/O模型 (一)I/...
    哈喽别样阅读 888评论 0 4
  • 1. Nginx的模块与工作原理 Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单...
    rosekissyou阅读 10,184评论 5 124
  • 第一章 Nginx简介 Nginx是什么 没有听过Nginx?那么一定听过它的“同行”Apache吧!Ngi...
    JokerW阅读 32,635评论 24 1,002
  • 上一篇《WEB请求处理一:浏览器请求发起处理》,我们讲述了浏览器端请求发起过程,通过DNS域名解析服务器IP,并建...
    七寸知架构阅读 80,910评论 21 356