0%

【转】web应用之Nginx

http协议回顾

http协议为应用层协议,其本身是statelss(无状态跟踪)。为了能够让服务端能够识别客户端,防止反复进行身份认证,会在客户端留下cookie文件,而服务端可以使用session关联至客户端。

默认情况下,客户端每一个http资源(一个页面会包含多个资源)请求都需要进行tcp三次握手四次断开,浪费了大量资源,为了解决这一问题,可以在服务端打开keepalive

http事务:

即完整的一次请求与响应过程。

request:请求报文

1
2
3
<headers> ... #可以有多个
#空行
<entity-body> #数据部分,可能为空

response:响应报文

1
2
3
<headers> ... #可以有多个
#空行
<entity-body> #数据部分

常用method(请求方法):

GETHEADPUTPOSTDELETETRACEOPTIONS

version格式:

1
HTTP/major.minor  #如HTTP/1.21

status code:

|分类|常见状态码
|——-|——————–|——————|———————|
|2xx|200:OK| | |
|3xx|301:永久重定向|302:临时重定向|304:未重定向|
|4xx|401:Unauthorized|403:Forbidden|404:Not found|
|5xx|500:Internal Server Error|502:Bad Gateway| |

I/O模型

IO models.PNG

应用程序调用内核(system call)访问存储设备中的数据,数据会先①由内核从存储设备加载至内核空间;然后再②从内核空间复制到用户空间。

同步/异步:关注的是消息通知机制

同步:synchronous

调用者等待被调用者返回消息;

异步:asynchronous

被调用者通过状态、通知或回调通知调用者;

阻塞/非阻塞:关注的是调用者在结果返回之前所处的状态

阻塞:block

调用结果返回前,调用者会被挂起;

非阻塞:nonblock

调用结果返回前,调用者不会被挂起,可继续处理其他任务;

I/O类型:

网络IO:本质是socket存取;

磁盘IO:本质是数据流;

无论网络IO还是磁盘IO,都会经过上面①②两个步骤。

I/O模型:

同步阻塞:blocking

在整个过程等待内核操作完成,并且被挂起,不能处理其他任务;

同步非阻塞:nonblocking

在①步骤主动检查内核是否准备好数据,非阻塞状态,在第②步骤仍然被阻塞;

I/O复用:I/O multiplexing

单个进程同时管理跟踪多个sock,在不同时间片跟踪在不同sock上;

常见系统调用:select、poll、epoll(linux独有)、kqueue(BSD上对epoll的实现)等

信号驱动I/O:singnal driven I/O

数据准备好(可从内核空间复制到进程空间),内核发出信号通知进程;

异步I/O:asynchronous I/O

数据准备完成(已完成内核空间复制到进程空间),内核发出信号通知进程;

nginx简介

官方站点:nginx.org

nginx是一个免费、开源、高性能的http和反向代理服务器

次版本号为偶数时,为稳定版。如1.8.x等。

特征:

高度模块化设计,较好扩展性

高可靠性

基于master/worker模型

支持热部署

不停机更新配置文件、更换日志文件、更新服务程序版本

低内存消耗

1w个keep-alive连接模式下的非活动连接仅消耗2.5M内存

event-drivenaiommap

基本功能:

静态资源web服务器

虚拟主机、keepalive、访问日志、url rewrite、路径别名、基于IP与用户的访问控制、支持速率限制及并发数限制等

http协议反向代理服务器

pop3/imap4协议反向代理服务器

FastCGI(LNMP),uwsgi等协议

模块化(非DSO),著名的有zip,SSL等

nginx程序架构:

2016-04-29 11-00-55屏幕截图.png

master/worker模型

master进程:仅有一个。加载配置文件、管理worker进程、平滑升级等

worker进程:可有多个。通过事件驱动机制,并发响应http服务、http代理、fcgi代理等。通过IO多路复用完成cache loader与cache manager。

模块类型

core module

standard module

standard HTTP modules

optional HTTP modules

mail modules

3rd party modules

nginx配置

官方源目前并没有收录nginx,所以需要使用epel源来安装

编译安装:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[root@ns1 ~]# yum groupinstall "Development Tools" "Server Platform Development"
 #需要单独安装部分软件开发包,以支持重写、https、压缩
[root@ns1 ~]# yum -y install pcre-devel openssl-devel zlib-devel
 #获取源码包并解压
[root@ns1 ~]# wget 
[root@ns1 ~]# tar -xzf nginx-1.8.1.tar.gz
[root@ns1 ~]# cd nginx-1.8.1/
 #官方configure选项
./configure 
--prefix=/usr/local
--sbin-path=/usr/sbin/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
--http-client-body-temp-path=/var/cache/nginx/client_temp #当客户端请求报文的body部分太大,内存容量难以胜任时,使用磁盘目录临时存放
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--user=nginx
--group=nginx
--with-http_ssl_module  #https相关
--with-http_realip_module
--with-http_addition_module
--with-http_sub_module
--with-http_dav_module
--with-http_flv_module
--with-http_mp4_module
--with-http_gunzip_module
--with-http_gzip_static_module
--with-http_random_index_module
--with-http_secure_link_module
--with-http_stub_status_module  #nginx状态信息页面。很多时候需要脚本调用页面输出信息来分析nginx状态
--with-http_auth_request_module  #认证请求相关
--with-threads
--with-stream
--with-stream_ssl_module
--with-http_slice_module
--with-file-aio
--with-http_v2_module
--with-debug  #如果需要开启debug级别的日志记录信息,需要此条目
[root@ns1 nginx-1.8.1]# make -j 4; make install

自带管理工具:

nginx -t 检查配置文件语法

nginx 启动服务

nginx -s {reload|stop|quit} 重新加载配置文件、平滑终止服务、立即停止服务

配置文件:

主配置文件:conf/nginx.conf

建议可以添加”include conf.d/*.conf”以使子配置文件生效,子配置文件及目录需手动创建。

其他配置文件:

fastcgi、scgi、uwsgi等相关配置

mime.types 定义了文件类型

配置指令(必须以分号结尾)

directive value1 [value2 ...];

支持使用变量:

内置变量:模块引入,可直接调用;

自定义变量:set VAR value;

引用变量:$VAR_NAME

配置详解:

参考官方站点:http://nginx.org/en/docs/

main block:全局配置

[toggle Title=展开全局配置条目]

正常运行必背
1
2
3
user USERNAME [GROUPNAME];  #指定运行worker进程的用户和组
pid FILE;  #pid文件路径
worker_rlimit_nofile NUMBER;  #单个worker进程能够打开的最大文件数
性能优化相关
1
2
3
4
worker_processes  NUMBER|auto;  #worker进程数量(通常应设置为CPU核心数-1,给系统运行留一个核心),最好将worker绑定到特定cpu核心。auto值在1.8版本以后可用
worker_cpu_affinity CPUMASK ...;  #绑定worker到特定cpu。这里的CPUMASK为cpu掩码。如4核心cpu则掩码有0001/0010/0100/1000
worker_cpu_affinity auto [CPUMASK];
worker_priority NICE;  #调整worker的nice值。取值范围[-20,19]
调试、定位问题相关
1
2
3
4
5
6
7
8
daemon on|off;  #是否以守护进程方式启动,守护进程方式会放入后台(默认是daemon方式)。调试时设置off。这样就可以在前台显示错误信息了
master_process on | off;  #是否以master/worker模型启动。正常启动应设置为on,默认方式为on,调试设置为off。
error_log file | stderr | syslog:server=address[,parameter=value] | memory:size [debug | info | notice | warn | error | crit | alert | emerg];  #错误日志文件的记录方式,及其日志级别
    file /LOG_FILE;
    stderr  发送到标准错误输出
    syslog:server=address[,parameter=value]  发送到syslog服务器
    memory:size 
    日志级别:debug级别需要在configure的时候指明--with-debug选项

事件驱动相关:

1
2
3
4
5
events {
worker_connections  1024;  #设置单个worker进程最大并发连接数。注意还受限于worker_rlimit_nofile(单个worker能够打开的最大文件数)设置
use METHOD;  #可选参数有{select|poll|kqueue|epoll|/dev/poll},但对linux来说,可用的仅由epoll
accept_mutex on|off;  #是否打开轮训响应,默认开启。打开后,worker会轮训响应新连接
}

http协议相关:

1
http {
套接字相关:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
    #配置listen、server_name、root等条目
    ...
}  #设置虚拟主机,可以有多个
listen address[:port] [default_server] [ssl] [backlog=number] [rcvbuf=size] [sndbuf=size];  #配置监听IP与端口
listen port [default_server] [ssl];
listen unix:path [default_server] [ssl];  #监听到unix socket上,仅用于本机不同进程间通讯
    default_server  #设置为默认虚拟主机
    ssl  #使用https
    backlog  #后缓队列长度
    rcvbuf  #接受缓冲区大小
    sndbuf  #发送缓冲区大小
server_name name ...;  #服务名,可用空格分隔多个
    支持使用通配符(*符号)和正则表达式(以~开头来标识)来表示
        server_name www.systemd.cn;
        server_name *.systemd.cn;
        server_name www.systemd.*;
        server_name ~^.*\.systemd\..*$;
    匹配次序:
        精确匹配 --> 左侧*通配 --> 右侧*通配 --> 正则模式匹配
tcp_nodelay  on|off;  #在keepalive打开的前提下,延时发送。(多个小资源会组合成一个大数据包后发送,节约了带宽,但会降低客户端体验)
sendfile on | off;  #是否开启sendfile功能。开启后响应报文直接由内核封装后发出,即省略了内核转发给nginx进程 --> nginx进程封装响应报文再传递给内核步骤
路径相关:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
root PATH;  #定义web资源路径,注意相对路径与绝对路径。可定义在http、server、location(推荐)、if in localtion语句内
    如定义在location内,则表示在location定义的目录的子目录
location [ = | ^~ | ~ | ~* ] uri {
    ...
}  #对用户请求资源的不同路径(类型)进行匹配,从而进行不同设定
    =  #uri精确匹配
    ^~  #锚定uri的左半部分做匹配检查
    ~  #做正则模式匹配,区分大小写
    ~*  #做正则模式匹配,不区分大小写
    匹配优先级:=  ^=  ~/~*  无符号
    注意:当本location中定义了root路径时,location后跟的uri是相对此路径的。未定义时,继承上级root的定义。
location @name {
    ...
}
alias PATH;  #定义链接路径。仅使用在location中。不能与root一起使用!
    如:
    localtion /bbs/ {
alias /www/web/vhost1/; 将uri "/bbs/"映射到系统路径"/www/web/vhost1/"
    }  #用户访问http://IP/bbs/会被映射到系统路径/www/web/vhost1/
index file ...;  #设置主页文件,可设置在http,server,location
error_page code ... [=[response]] uri;  #错误重定向。
    如:
    error_page 404 = 200 /404.html;  #将不存在的页面重定向到404.html,并将网页状态码修改为200。
try_files file ... uri;  #依次尝试显示不同资源,直到找到资源。应定义在server或location中。
try_files file ... =code;
客户端请求的相关
1
2
3
4
5
6
7
8
9
keepalive_timeout timeout [header_timeout];  #保持连接超时时长。0表示禁止长连接;默认75s
keepalive_requests NUMBER;  #在一次长连接允许请求的最大资源数,默认为100
keepalive_disable none | browser ...;  #对那种浏览器关闭keepalive功能
send_timeout time;  #发送响应报文的超时时长。特指服务端响应报文距客户端下次请求报文的时间差。默认60s
client_body_buffer_size size;  #接收客户端请求报文body部分缓冲区大小;默认16k,超过此大小则被暂存到磁盘上client_body_temp_path指定目录
client_body_temp_path path [level1 [level2 [level3]]];  #设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量。level为数字
    如:
    client_body_temp_path /var/tmp/nginx/body/ 1 2
    则表示在/var/tmp/nginx/body/目录下,会随机创建1位16进制字符子目录(文件名随机0-f);而在子目录下,随机创建2位16进制字符的子目录(文件名随机00-ff)
客户端请求限制:
1
2
3
4
5
6
7
8
9
limit_rate rate;  #限制响应给客户端的传输速率,单位bytes/s,0表示无限制
limit_except method ... { ... };  #限制客户端使用除特定方法之外的其他方法。仅在location中配置
    如:
    location /admin/ {
        limit_except GAT POST {
            allow 172.18.0.0/16;
            deny all;
        }
    }  #仅允许172.18.0.0/16网段使用除GAT、POST之外的其他方法,其他仅能使用GAT、POST这两种方法
文件操作优化:
1
2
3
4
5
6
7
aio on | off | threads[=pool];  #是否启用aio功能(异步IO)
directio size | off;  #当文件大小大于设定的size后,会启动directio
open_file_cache off|on;  #文件缓存功能是否开启
open_file_cache max=N [inactive=time];  #设置文件缓存项上限,达到上限则使用LRU算法(最近最少使用)实现缓存管理;设置缓存过期时长,即设置LRU算法中的最近是多少时长
open_file_cache_errors on | off;  #是否缓存请求错误的文件信息
open_file_cache_min_uses number;  #最近最少使用标准,即LRU算法中最少使用次数。小于此number会被认为是非活动项
open_file_cache_valid time;  #缓存项有效性的检查频率。默认为60s

ip访问控制:依赖ngx_http_access_module

1
2
allow address |CIDR | unix: |all;  #允许特定客户端访问,可在http, server, location, limit_except配置。多条自上而下直到匹配上,所以一般在随后一条设置默认策略
deny address |CIDR | unix: |all;  #进制特定客户端访问

basic认证机制:依赖ngx_http_auth_basic_module

1
2
3
4
5
6
7
auth_basic string | off;  #启用basic认证的系统提示字符,或设置关闭basic认证
auth_basic_user_file file;  #认证文件
    文件格式:
        明文:username:password:注释
        密文:htpasswd命令生成
            htpasswd -c -m /FILE username  #第一次生成认证文件并添加第一个用户
            htpasswd -m /FILE username  #存在认证文件,添加新用户

nginx基本状态信息:依赖ngx_http_stub_status_module

1
2
3
4
5
Active connections: 3   #处于活动状态的客户端连接数量
server accepts handled requests
 157 157 300      #已接收客户端连接总数,已处理完成的客户端请求总数,客户端总请求数
Reading: 0 Writing: 1 Waiting: 2  
#处于读取客户端请求报文首部的连接数,处于向客户端发送响应报文过程的连接数,处于等待客户端发出请求的空闲连接数(当这个值太大时,可能是由于keep-lived设置超时时长太长导致)

限制请求报文referer(防盗链):依赖ngx_http_referer_module

1
2
3
4
5
6
7
8
9
10
11
12
13
valid_referers none | blocked | server_names | STRING ...;  #匹配请求报文referer字段(由何链接跳转到本链接)
    none:请求报文不包含referer字段
    blocked:请求报文包含referer字段,但没有值
    server_names:域名匹配,server_name后跟域名匹配。可使用正则(以~开头)、通配符(*)进行匹配。
    STRING:子定义字符串。可使用正则(以~开头)、通配符(*)进行匹配。
    注意:匹配不到的会自动存放到$invalid_referer内置变量中
    如:
    location ~.*\.(gif|jpg|png|swf|flv)$ {
        valid_referers none blocked server_name *systemd.cn ~.*linux.*;
        if ($invalid_referer) {
            return 404;
        }
    }  #对本站特定格式图片资源,匹配请求报文referer字段为空或没有值或来自systemd.cn域名或包含linux字符;对匹配不到的请求报文回应404。即仅允许特定站点引用本站图片资源。

https:依赖ngx_http_ssl_module

ssl:Secure SocketLayer HTTPS(Hyper TextTransfer Protocol over Secure Socket Layer)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ssl on | off;  #是否启用当前虚拟主机ssl功能
ssl_certificate file;  #当前虚拟主机pem格式证书文件
ssl_certificate_key file;  #当前虚拟主机pem格式私钥文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];  #ssl协议版本
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];  #ssl会话缓存机制。
    off:关闭
    none:(默认值)优雅的告诉客户端可能不支持缓存机制
    builtin:使用openssl内建的缓存机制,各worker独立不共享缓存数据
    shared:各worker共享缓存数据。
        name:缓存空间名称;
        size:每1MB内存可以存储4000个session,根据需要调整size
builtin与shared可同时使用:
如:
ssl_session_cache builtin 1024 shared ssl-session-sharecache 10M;
ssl_verify_client;  #验证客户端证书,一般不需要此条目
ssl_ciphers CIPHPERS;  #指定ssl加密算法
ssl_session_timeout TIME;  #会话超时时长,指ssl_session_cache中缓存条目有效时长

日志:依赖ngx_http_log_module

1
2
3
4
5
6
7
8
9
10
11
12
13
access_log path [format [buffer=size [flush=time]] [if=condition]];
access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
access_log syslog:server=address[,parameter=value] [format [if=condition]];
  #上面3条的format为log_format条目中的NAME,即引用特定格式
  flush:设置刷写到磁盘的时长。即多久将数据写入磁盘
access_log off;
log_format name string ...;  #设置日志格式。使用内建变量进行标识STRING字段。如$time_local表示本地时间
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];  #启用日志缓存
    max:最大缓存条目,默认10个。会使用LRU(最近最少访问)算法自动计算。
    inactive:非活动时长
    min_uses:最少使用次数。小于此次数被认为非活动
    valid:验证缓存条目有效性的频率
open_log_file_cache off;

资源重定向:依赖ngx_http_rewrite_module

将客户端对某资源的请求重定向到另一个资源,将新资源响应给客户端。

首先需要明白一点,同一个location内的如果有多条rewrite条目,那么在未匹配到最终结果之前,会循环匹配。

如:

c –> d

a –> b

b –> c

客户端请求a资源时,a –> b –> c –>d,因为d没有rewrite条目了,所以返回最终结果d给客户端。使用flag可控制这种默认循环过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
rewrite regex replacement [flag];  #将regex能匹配到的客户端请求uri,注意是uri,而不是url,替换为replacement字符串。
    注意!regex为正则表达式,replacement为普通字符串。多个rewrite条目会逐个检查,flag用以控制检查方式。
    如:
    rewrite (.*)admin\.html $1a.html;
    rewrite ^\/admin\/admin\.html /admin/a.html last;
    flag取值:
        last  #匹配到此条,不再继续下面条目的匹配,跳到此location第1条rewrite条目开始下一轮匹配。类似shell脚本中的continue。
        break  #匹配到此条,返回客户端新的uri,由客户端浏览器主动发起对新uri的资源请求(不需要用户参与)。类似shell脚本中的break。
        redirect  #返回状态码为临时重定向,与break类似,但返回状态码为302。
        permanent  #返回状态码为永久重定向,与break类似,但返回状态码为301。
rewrite_log on | off;  #是否启用重写日志。开启后,日志信息会被发往错误日志
if (condition) { ... };  #条件判断,当满足condition时,执行语句块中操作。
    condition可以是比较表达式、文件目录存在性判断
        ==, !=
        ~  模式匹配,区分字母大小写;
        ~*   模式匹配,不区分字符大小写;
        !~   模式不匹配,区分字母大小写;
        !~*  模式不匹配,不区分字母大小写;
        -f, !-f  是/不是文件
        -d, !-d  是/不是目录
        -e, !-e  存在/不存在
        -x, !-x  可执行/不可执行
return code [text];  #rewrite匹配不到时,返回给客户端响应码及文本信息
return code URL;
return URL;
set $variable value;  #设置用户自定义变量

资源压缩:依赖ngx_http_gzip_module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gzip on | off;  #启用或禁用gzip压缩响应报文;
gzip_comp_level level;  #指定压缩比,1-9,默认为1;
gzip_disable regex ...;  #regex是匹配客户端浏览器类型的模式,表示对所有匹配到的浏览器不执行压缩响应;
gzip_min_length length;  #触发启用压缩功能的响应报文的最小长度;
gzip_http_version 1.0 | 1.1;  #设定启用压缩响应功能时,协议的最小版本;
gzip_types mime-type ...;  #指定仅执行压缩的资源内容类型;默认为text/html;
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;  #作为代理服务器时,对何种类型报文进行压缩
    如:expired:响应报文包含"Expired"项并有值(设置报文过期时长),则启用压缩
    实例:
    gzip on;
    gzip_http_version 1.0;
    gzip_comp_level 6;
    gzip_disable msie6;
    gzip_min_length 2;
    gzip_types text/plain text/css text/xml application/x-javascript  application/xml  application/json application/java-script;

fastcgi:依赖ngx_http_fastcgi_module

fastcgi中会将匹配到的uri放入到$fastcgi_script_name变量中。如访问http://IP/zbog/index.php。$fastcgi_script_name内容为/zbog/index.php。所以在设定fastcgi_param时候需要特别注意。

最好保证root设定的文档目录与fastcgi_param中$fastcgi_script_name之前的路径一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#定义在一个location内
location ~ \.php$ {
    root html;
    fastcgi_pass 127.0.0.1:9000;  #php-fpm主机地址及端口
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html/$fastcgi_script_name;  #将nginx匹配到的请求资源映射到php-fpm的路径
    include fastcgi_params;  #指明子配置文件
}
fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
    path:文件系统路径,用于存储缓存的文件数据;
    max_size=size:定义此路径下的多大空间用于存储缓存数据;
    levels=#[:#[:#]]:缓存目录层级定义;
        levels=1:2
    keys_zone=name:size
        内存中用于缓存k/v映射关系的空间名称及大小;
    inactive=time
    注意:只能定义在http上下文。
fastcgi_cache zone | off;  #是否启用cache,如果启用,数据缓存于哪个cache中。ZONE为fastcgi_cache_path中设置的keys_zone名称。
fastcgi_cache_key string;  #定义要使用的缓存键;
    如: fastcgi_cache_key  $request_uri;
fastcgi_cache_methods GET | HEAD | POST ...;  #缓存哪些类型的请求的相关数据;
fastcgi_cache_min_uses number;  #最近最少使用量,少于此值被认为非活动
fastcgi_cache_valid [code ...] time;  #对不同响应码设定其可缓存时长

proxy:ngx_http_proxy_module(反代+缓存)

代理服务器会拆解所有封装,然后重新封装。所以其能够添加的规则/限制条件会很多;由于其工作在应用层,所以受限于能够打开的socket数量,故仅适用于并发请求不太多的情况。所以nginx通常用作反代服务器,后端使用apache。

正向代理:类似SNAT,在用户空间对远程server上资源转发给Client(常伴随着缓存)

反向代理:类似DNAT,作为前端主机。

涉及到与Client的会话保持、keepalive、延时发送;与后端Server的会话保持、keepalive。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
proxy_pass URL;  #将location匹配到的/uri转发到URL/uri
proxy_pass URL/; #将location匹配到的/uri转发到URL/
#↑↑ 可应用在location,if in location,limit_except
#自定义的upstream NAME调用方法:proxy_pass http://NAME
#注意URL带"/"与不带意义不同:
location /uri/ {
proxy_pass http://b.com/new_uri/;
#表示:http://a.com/bbs/ --> http://b.com/new_uri/
proxy_pass http://b.com/new_uri;
#表示:http://a.com/bbs/ --> http://b.com/new_uri/bbs
}

proxy_set_header FIELD VALUE; #设定向后端主机发送的请求报文的首部及其值。
#实现后端主机日志记录真正访问的Client IP,而不是代理服务器的:
proxy_set_header X-Client-IP $remote_addr; #自定义变量传递给后端主机
#修改后端apache Server: 获取传递过来的自定义变量
LogFormat:LogFormat "%{X-Client-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

#缓存相关选项(缓存要先定义,后调用)
#内存中缓存的key-value: url -> 内容校验码
#磁盘缓存目录: 文件名即为资源的校验码
proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] ; #指明缓存路径,目录结构,仅定义在http内
proxy_cache zone|off; #调用上面定义的key_zone
proxy_cache_key string; #定义缓存键,一般定义为uri,
#如 proxy_cache_key $request_uri;
proxy_cache_key $scheme$proxy_host$request_uri
proxy_cache_valid [code ...] time; #为不同的响应码设定其缓存时长,不指定则不缓存。
#如 proxy_cache_valid 200 302 10m;
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_read_timeout TIME; #等待后端主机响应报文的超时时长,默认60s
proxy_send_timeout TIME; #向后端主机发送请求报文的超时时长,默认60s

首部管理:ngx_http_headers_module

为响应给Client的报文中添加/修改首部信息

1
2
3
4
5
add_header name value [always];   #向响应报文添加自定义首部,并赋值
#如:add_header X-Via $server_addr;

expires [modified] time;
expires epoch | max | off; #用于添加Expire及Cache-Control首部或修改首部的值;

服务器组:ngx_http_upstream_module

将多个后端主机定义为服务器组,而后可由proxy_pass, fastcgi_pass, memcached_pass等进行引用;同样使用NAME来调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
upstream NAME {   #定义后端服务器组;引入新的上下文;只能用于http上下文
server address [parameters]; #定义服务器的地址和相关的参数
# address格式:
# IP[:port]
# HOSTNAME[:port]
# unix:/PATH/TO/SOME_SOCK_FILE
# parameters格式:
# weight=number #服务器权重
# max_fails=number #最大失败尝试次数
# fail_timeout=time #设置服务器不可用超时时长
# backup #备用主机
# down #手动标记其不再处理任何用户请求

ip_hash; #使用源地址哈希算法(Client地址)
least_conn; #最少连接算法
keepalive CONNECTIONS; #与后端主机的最少连接,通常后端有多少主机设置几个。
}

health_check [parameters]; #定义后端主机健康监测。仅用在location上下文,nginx2.0及以上版本才支持。
# 可用参数:
interval=NUMBER 监测频度,默认5s
fails=NUMBER 判定为失败的检测次数
passes=NUMBER 判定为成功的检测次数
uri=uri 执行健康检测时请求的uri
match=NAME 基于哪个match做健康检测
port=NUMBER 向服务器的那个port发起健康检测

match name { ... } #仅能用于http上下文 ;对后端主机做健康状态检测时,定义其结果判断标准
status:期望的响应码;
status CODE
status ! CODE
status CODE-CODE
header:基于响应首部进行判断
header HEADER=VALUE
header HEADER!=VALUE
header [!] HEADER
header HEADER ~ VALUE
body:期望的响应报文的主体部分应该有的内容;
body ~ "CONTENT"
body !~ "CONTENT"

hash key [consistent]; #定义调度方法,可自定义基于何种信息(key)进行绑定
# 如:
hash $remote_addr #定义绑定远程Client IP进行调度。较粗糙,同一公网地址的Client无法会被调度到同一后端主机
hash $request_uri #根据uri,同一页面由后端同台主机进行响应
hash $cookie_username #根据cookie,最精细

补充:内置变量的调用,向客户端展示缓存命令与否:add_header X-Cache $upstream_cache_status;
}

mail相关

1
mail { ... }