zqhong / pelican-blog

Use Pelican generate static blog site
1 stars 0 forks source link

深入理解Nginx(第2版) #6

Open zqhong opened 7 years ago

zqhong commented 7 years ago

第一部分:如何使用 Nginx

第一章:编译安装Nginx

编译安装 Nginx 最简单的方式

./configure
make
make install

configure

检测操作系统内核和已安装的软件、参数解析,中间目录的生成以及根据各种参数生成 C 源码文件、Makefile 文件等。

configure 的命令参数 路径相关参数

参数名称 意义 默认值
--prefix=PATH Nginx 安装部署后的根目录 默认为 /usr/local/nginx
--sbin-path=PATH 可执行文件的放置路径 /sbin/nginx
--conf-path=PATH 配置文件的放置路径 /conf/nginx.conf
--error-log-path=PATH error 日志的防止路径 /logs/error.log
--pid-path=PATH pid 文件的存放路径。该文件仅保存 Nginx Master 进程 ID,在使用命令行(如 nginx -s reload)时,就是通过读取 Master 进程 ID 向 Master 进程发送信号,对运行中的 Nginx 服务产生作用。 /logs/nginx.pid
--lock-path=PATH lock 文件的放置路径 /logs/nginx.lock
--builddir=DIR configure 执行时与编译期间产生的临时文件放置的目录,包括产生的 Makefile、C 源文件、目标文件、可执行文件等。 /objs
--http-log-path=PATH accsss 日志放置的位置 /logs/access.log

B编译相关的参数

编译参数 意义
--with-cc=PATH C 编译器的路径
--with-cpp=PATH C 编译器的路径
--with-cpu-opt=CPU 指定 CPU 处理器架构,可选值:pentium、pentiumpro、pentium3、pentium4、athlon、opteron、sparc32、sparc64、ppc64

依赖软件的相关参数

PCRE 库的设置参数 意义
--without-pcre 如果确认 Nginx 不用解析正则表达式,则可以使用这个参数
--with-pcre 强制使用 PCRE 库
--wit-pcre=DIR 指定 PCRE 库的源码位置,在编译 Nginx 时会进入该目录编译 PCRE 源码
--with-pcre-opt=OPTIONS 编译 PCRE 源码时希望加入的编译选项
OpenSSL 库的设置参数 意义
--with-openssl=DIR 指定 OpenSSL 库的源码位置。注意:如果 Web 服务器支持 HTTPS,Nginx 要求必须使用 OpenSSL。
--with-openssl-opt=OPTIONS 编译 OpenSSL 源码时希望加入的编译选项

make

根据 configure 命令生成的 Makefile 文件编译 Nginx 工程,并生成目标文件、最终的二进制文件。

make install

根据 configure 执行时的参数将 Nginx 部署到指定的安装目录,包括相关目录的建立和二进制文件、配置文件的复制。

Nginx 命令行

指定配置文件启动

$ /usr/local/nginx/sbin/nginx -c /tmp/nginx.conf

测试配置信息是否有错误

$ /usr/local/nginx/sbin/nginx -t

在测试配置阶段不输出信息(-q 参数可以不把 error 级别以下的错误输出到屏幕上)

$ /usr/local/nginx/sbin/nginx -t -q

显示编译阶段的参数

$ /usr/local/nginx/sbin/nginx -V

快速停止服务(强制停止 Nginx 服务)

-s 参数其实是告诉 Nginx 程序向正在运行的 Nginx 服务发送信号量,Nginx 程序通过 nginx.pid 文件中得到 master 进程的进程 ID,再向运行中的 master 进程发送 TERM 信号来快速地关闭 Nginx 服务。实际上,如果通过kill命令直接向nginx master进程发送TERM或者INT信号,效果是一样的。如:kill -s SIGTERM nginx_pid

$ /usr/local/nginx/sbin/nginx -s stop

优雅地停止服务

该命令与快速停止 Nginx 服务的区别:

当快速停止服务时,worker 进程与 master 进程在收到信号后会立即跳出循环,退出进程。而优雅地停止服务的话,首先会关闭监听端口,停止接收新的连接,然后把正在处理的连接全部处理完,最后再退出进程。

与快速停止服务相似,可以直接发送QUIT信号给master进程来停止服务,其效果与执行-s quit命令是一样的。例如:kill -s SIGQUIT <nginx master pid>

如果希望“优雅”地停止某个worker进程,那么可以通过向该进程发送WINCH信号来停止服务。例如:kill -s SIGWINCH <nginx worker pid>

$ /usr/local/nginx/sbin/nginx -s quit

使运行中的 Nginx 重新读取配置并生效

事实上,Nginx会先检查新的配置项是否有误,如果全部正确就以“优雅”的方式关闭,再重新启动Nginx来实现这个目的。类似的,-s是发送信号,仍然可以用kill命令发送HUP信号来达到相同的效果。

$ /usr/local/nginx/sbin/nginx -s reload

日志文件回滚

使用-s reopen参数可以重新打开日志文件,这样可以先把当前日志文件改名或转移到其他目录中进行备份,再重新打开时就会生成新的日志文件。这个功能使得日志文件不至于过大。

$ /usr/local/nginx/sbin/nginx -s reopen

第二章:Nginx 的配置

当Nginx上的进程数与CPU核心数相等时(最好每一个worker进程都绑定特定的CPU核心),进程间切换的代价是最小的。

示例配置

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    gzip  on;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

Nginx 的配置特点

Nginx 基本配置项

用于调试、定位问题的配置项

(1)是否以守护进程方式运行Nginx

语法:daemon on|off;

默认:daemon on;

(2)是否以master/worker方式工作

语法:master_process on|off;

默认:master_process on;

(3)error日志的设置

语法:error_log/path/file level;

默认:error_log logs/error.log error;

注意 如果日志级别设定到debug,必须在configure时加入——with-debug配置项。

(4)是否处理几个特殊的调试点

语法:debug_points[stop|abort]

(5)仅对指定的客户端输出debug级别的日志

语法:debug_connection[IP|CIDR]

注意 使用debug_connection前,需确保在执行configure时已经加入了——with-debug参数,否则不会生效。

(6)限制coredump核心转储文件的大小

语法:worker_rlimit_core size;

(7)指定coredump文件生成目录

语法:working_directory path;

正常运行的必备配置项

(1)定义环境变量

语法:env VAR|VAR=VALUE

(2)嵌入其他配置文件

语法:include/path/file;

(3)pid文件的路径

语法:pid path/file;

默认:pid logs/nginx.pid;

(4)Nginx worker进程运行的用户及用户组

语法:user username[groupname];

默认:user nobody nobody;

(5)指定Nginx worker进程可以打开的最大句柄描述符个数

语法:worker_rlimit_nofile limit;

(6)限制信号队列

语法:worker_rlimit_sigpending limit;

优化性能的配置项

(1)Nginx worker进程个数

语法:worker_processes number;

默认:worker_processes 1;

(2)绑定Nginx worker进程到指定的CPU内核

语法:worker_cpu_affinity cpumask[cpumask……]

(3)SSL硬件加速

语法:ssl_engine device;

(4)系统调用gettimeofday的执行频率

语法:timer_resolution t;

(5)Nginx worker进程优先级设置

语法:worker_priority nice;

默认:worker_priority 0;

注意 worker_cpu_affinity配置仅对Linux操作系统有效。Linux操作系统使用sched_setaffinity()系统调用实现这个功能。

事件类配置项

(1)是否打开accept锁

语法:accept_mutex[on|off]

默认:accept_mutext on;

(2)lock文件的路径

语法:lock_file path/file;

默认:lock_file logs/nginx.lock;

(3)使用accept锁后到真正建立连接之间的延迟时间

语法:accept_mutex_delay Nms;

默认:accept_mutex_delay 500ms;

(4)批量建立新连接

语法:multi_accept[on|off];

默认:multi_accept off;

(5)选择事件模型

语法:use[kqueue|rtsig|epoll|/dev/poll|select|poll|eventport];

默认:Nginx会自动使用最适合的事件模型。

对于Linux操作系统来说,可供选择的事件驱动模型有poll、select、epoll三种。epoll当然是性能最高的一种.

(6)每个worker的最大连接数

语法:worker_connections number;

虚拟主机与请求的分发

(1)监听端口

语法:listen address:port[default(deprecated in 0.8.21)|default_server|[backlog=num|rcvbuf=size|sndbuf=size|accept_filter=filter|deferred|bind|ipv6only=[on|

默认:listen 80;

配置块:server

例如:

listen 127.0.0.1:8000;

listen 127.0.0.1; #注意:不加端口时,默认监听80端口

listen 8000;

listen *:8000;

listen localhost:8000;

在地址和端口后,还可以加上其他参数,例如:

listen 443 default_server ssl;

listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;

下面说明listen可用参数的意义:

(2)主机名称

语法:server_name name[……];

默认:server_name"";

配置块:server

server_name后可以跟多个主机名称,如server_name www.testweb.com、download.testweb.com;。

在开始处理一个HTTP请求时,Nginx会取出header头中的Host,与每个server中的server_name进行匹配,以此决定到底由哪一个server块来处理这个请求。有可能一个Host与多个server块中的server_name都匹配,这时就会根据匹配优先级来选择实际处理的server块。server_name与Host的匹配优先级如下:

  1. 首先选择所有字符串完全匹配的server_name,如www.testweb.com。
  2. 其次选择通配符在前面的server_name,如.testweb.com。
  3. 再次选择通配符在后面的server_name,如www.testweb.*。
  4. 最后选择使用正则表达式才匹配的server_name,如~^.testweb.com$。

(3)server_names_hash_bucket_size

语法:server_names_hash_bucket_size size;

默认:server_names_hash_bucket_size 32|64|128;

配置块:http、server、location

为了提高快速寻找到相应server name的能力,Nginx使用散列表来存储server name。server_names_hash_bucket_size设置了每个散列桶占用的内存大小。

(4)server_names_hash_max_size

语法:server_names_hash_max_size size;

默认:server_names_hash_max_size 512;

配置块:http、server、location

server_names_hash_max_size会影响散列表的冲突率。server_names_hash_max_size越大,消耗的内存就越多,但散列key的冲突率则会降低,检索速度也更快。server_names_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能增高。

(5)重定向主机名称的处理

语法:server_name_in_redirect on|off;

默认:server_name_in_redirect on;

配置块:http、server或者location

该配置需要配合server_name使用。在使用on打开时,表示在重定向请求时会使用server_name里配置的第一个主机名代替原先请求中的Host头部,而使用off关闭时,表示在重定向请求时使用请求本身的Host头部。

(6)location

语法:location[=|~|~*|^~|@]/uri/{……}

配置块:server

location的匹配规则:

  1. = 表示把URI作为字符串,以便与参数中的uri做完全匹配。例如:
location = / {
    #只有当用户请求是/时,才会使用该location下的配置
    …
}
  1. ~表示匹配URI时是字母大小写敏感的。
  2. ~*表示匹配URI时忽略字母大小写问题。
  3. ^~表示匹配URI时只需要其前半部分与uri参数匹配即可。例如:
location ^~ /images/ {
    # 以/images/开始的请求都会匹配上
    … 
}
  1. @表示仅用于Nginx服务内部请求之间的重定向,带有@的location不直接处理用户请求。

当然,在uri参数里是可以用正则表达式的,例如:

location ~* \.(gif|jpg|jpeg)$ {
    # 匹配以.gif、.jpg、.jpeg结尾的请求
    …
}
  1. localhost / {} 可以匹配所有请求
location / {
    # /可以匹配所有请求
    …
}

注意,location是有顺序的,当一个请求有可能匹配多个location时,实际上这个请求会被第一个location处理。

文件路径的定义

(1)以root方式设置资源路径

语法:root path;

默认:root html;

配置块:http、server、location、if

(2)以alias方式设置资源路径

语法:alias path;

配置块:location

(3)访问首页

语法:index file……;

默认:index index.html;

配置块:http、server、location

(4)根据HTTP返回码重定向页面

语法:error_page code[code……][=|=answer-code]uri|@named_location

配置块:http、server、location、if

(5)是否允许递归使用error_page

语法:recursive_error_pages[on|off];

默认:recursive_error_pages off;

配置块:http、server、location

(6)try_files

语法:try_files path1[path2]uri;

配置块:server、location

内存及磁盘资源的分配

(1)HTTP包体只存储到磁盘文件中

语法:client_body_in_file_only on|clean|off;

默认:client_body_in_file_only off;

配置块:http、server、location

(2)HTTP包体尽量写入到一个内存buffer中

语法:client_body_in_single_buffer on|off;

默认:client_body_in_single_buffer off;

配置块:http、server、location

(3)存储HTTP头部的内存buffer大小

语法:client_header_buffer_size size;

默认:client_header_buffer_size 1k;

配置块:http、server

(4)存储超大HTTP头部的内存buffer大小

语法:large_client_header_buffers number size;

默认:large_client_header_buffers 48k;

配置块:http、server

(5)存储HTTP包体的内存buffer大小

语法:client_body_buffer_size size;

默认:client_body_buffer_size 8k/16k;

配置块:http、serveer、location

(6)HTTP包体的临时存放目录

语法:client_body_temp_path dir-path[level1[level2[level3]]]

默认:client_body_temp_path client_body_temp;

配置块:http、server、location

(7)connection_pool_size

语法:connection_pool_size size;

默认:connection_pool_size 256;

配置块:http、server

(8)request_pool_size

语法:request_pool_size size;

默认:request_pool_size 4k;

配置块:http、server

网络连接的设置

(1)读取HTTP头部的超时时间

语法:client_header_timeout time(默认单位:秒);

默认:client_header_timeout 60;

配置块:http、server、location

(2)读取HTTP包体的超时时间

语法:client_body_timeout time(默认单位:秒);

默认:client_body_timeout 60;

配置块:http、server、location

(3)发送响应的超时时间

语法:send_timeout time;

默认:send_timeout 60;

配置块:http、server、location

(4)reset_timeout_connection

语法:reset_timeout_connection on|off;

默认:reset_timeout_connection off;

配置块:http、server、location

(5)lingering_close

语法:lingering_close off|on|always;

默认:lingering_close on;

配置块:http、server、location

(6)lingering_time

语法:lingering_time time;

默认:lingering_time 30s;

配置块:http、server、location

(7)lingering_timeout

语法:lingering_timeout time;

默认:lingering_timeout 5s;

配置块:http、server、location

(8)对某些浏览器禁用keepalive功能

语法:keepalive_disable[msie6|safari|none]……

默认:keepalive_disablemsie6 safari

配置块:http、server、location

(9)keepalive超时时间

语法:keepalive_timeout time(默认单位:秒);

默认:keepalive_timeout 75;

配置块:http、server、location

(10)一个keepalive长连接上允许承载的请求最大数

语法:keepalive_requests n;

默认:keepalive_requests 100;

配置块:http、server、location

(11)tcp_nodelay

语法:tcp_nodelay on|off;

默认:tcp_nodelay on;

配置块:http、server、location

(12)tcp_nopush

语法:tcp_nopush on|off;

默认:tcp_nopush off;

配置块:http、server、location

对客户端请求的限制

(1)按HTTP方法名限制用户请求

语法:limit_except method……{……}

配置块:location

(2)HTTP请求包体的最大值

语法:client_max_body_size size;

默认:client_max_body_size 1m;

配置块:http、server、location

(3)对请求的限速

语法:limit_rate speed;

默认:limit_rate 0;

配置块:http、server、location、if

(4)limit_rate_after

语法:limit_rate_after time;

默认:limit_rate_after 1m;

配置块:http、server、location、if

文件操作的优化配置项

(1)sendfile系统调用

语法:sendfile on|off;

默认:sendfile off;

配置块:http、server、location

(2)AIO系统调用

语法:aio on|off;

默认:aio off;

配置块:http、server、location

此配置项表示是否在FreeBSD或Linux系统上启用内核级别的异步文件I/O功能。注

(3)directio

语法:directio size|off;

默认:directio off;

配置块:http、server、location

此配置项在FreeBSD和Linux系统上使用O_DIRECT选项去读取文件,缓冲区大小为size,通常对大文件的读取速度有优化作用。注意,它与sendfile功能是互斥的。

(4)directio_alignment

语法:directio_alignment size;

默认:directio_alignment 512;

配置块:http、server、location

(5)打开文件缓存

语法:open_file_cache max=N[inactive=time]|off;

默认:open_file_cache off;

配置块:http、server、location

(6)是否缓存打开文件错误的信息

语法:open_file_cache_errors on|off;

默认:open_file_cache_errors off;

配置块:http、server、location

(7)不被淘汰的最小访问次数

语法:open_file_cache_min_uses number;

默认:open_file_cache_min_uses 1;

配置块:http、server、location

(8)检验缓存中元素有效性的频率

语法:open_file_cache_valid time;

默认:open_file_cache_valid 60s;

配置块:http、server、location

对客户端请求的特殊处理

(1)忽略不合法的HTTP头部

语法:ignore_invalid_headers on|off;

默认:ignore_invalid_headers on;

配置块:http、server

(2)HTTP头部是否允许下划线

语法:underscores_in_headers on|off;

默认:underscores_in_headers off;

配置块:http、server

(3)对If-Modified-Since头部的处理策略

语法:if_modified_since[off|exact|before];

默认:if_modified_since exact;

配置块:http、server、location

(4)文件未找到时是否记录到error日志

语法:log_not_found on|off;

默认:log_not_found on;

配置块:http、server、location

(5)merge_slashes

语法:merge_slashes on|off;

默认:merge_slashes on;

配置块:http、server、location

(6)DNS解析地址

语法:resolver address……;

配置块:http、server、location

(7)DNS解析的超时时间

语法:resolver_timeout time;

默认:resolver_timeout 30s;

配置块:http、server、location

(8)返回错误页面时是否在Server中注明Nginx版本

语法:server_tokens on|off;

默认:server_tokens on;

配置块:http、server、location

ngx_http_core_module 模块提供的变量

参数名称 注释
$arg_PARAMETER HTTP 请求中某个参数的值,如/index.php?site=www.ttlsa.com,可以用$arg_site取得www.ttlsa.com这个值.
$args HTTP 请求中的完整参数。例如,在请求/index.php?width=400&height=200 中,$args表示字符串width=400&height=200.
$binary_remote_addr 二进制格式的客户端地址。例如:\x0A\xE0B\x0E
$body_bytes_sent 表示在向客户端发送的http响应中,包体部分的字节数
$content_length 表示客户端请求头部中的Content-Length 字段
$content_type 表示客户端请求头部中的Content-Type 字段
$cookie_COOKIE 表示在客户端请求头部中的cookie 字段
$document_root 表示当前请求所使用的root 配置项的值
$uri 表示当前请求的URI,不带任何参数
$document_uri 与$uri 含义相同
$request_uri 表示客户端发来的原始请求URI,带完整的参数。$uri和$document_uri未必是用户的原始请求,在内部重定向后可能是重定向后的URI,而$request_uri 永远不会改变,始终是客户端的原始URI.
$host 表示客户端请求头部中的Host字段。如果Host字段不存在,则以实际处理的server(虚拟主机)名称代替。如果Host字段中带有端口,如IP:PORT,那么$host是去掉端口的,它的值为IP。$host 是全小写的。这些特性与http_HEADER中的http_host不同,http_host只取出Host头部对应的值。
$hostname 表示 Nginx所在机器的名称,与 gethostbyname调用返回的值相同
$http_HEADER 表示当前 HTTP请求中相应头部的值。HEADER名称全小写。例如,示请求中 Host头部对应的值 用 $http_host表
$sent_http_HEADER 表示返回客户端的 HTTP响应中相应头部的值。HEADER名称全小写。例如,用 $sent_ http_content_type表示响应中 Content-Type头部对应的值
$is_args 表示请求中的 URI是否带参数,如果带参数,$is_args值为 ?,如果不带参数,则是空字符串
$limit_rate 表示当前连接的限速是多少,0表示无限速
$nginx_version 表示当前 Nginx的版本号
$query_string 请求 URI中的参数,与 $args相同,然而 $query_string是只读的不会改变
$remote_addr 表示客户端的地址
$remote_port 表示客户端连接使用的端口
$remote_user 表示使用 Auth Basic Module时定义的用户名
$request_filename 表示用户请求中的 URI经过 root或 alias转换后的文件路径
$request_body 表示 HTTP请求中的包体,该参数只在 proxy_pass或 fastcgi_pass中有意义
$request_body_file 表示 HTTP请求中的包体存储的临时文件名
$request_completion 当请求已经全部完成时,其值为 “ok”。若没有完成,就要返回客户端,则其值为空字符串;或者在断点续传等情况下使用 HTTP range访问的并不是文件的最后一块,那么其值也是空字符串。
$request_method 表示 HTTP请求的方法名,如 GET、PUT、POST等
$scheme 表示 HTTP scheme,如在请求 https://nginx.com/中表示 https
$server_addr 表示服务器地址
$server_name 表示服务器名称
$server_port 表示服务器端口
$server_protocol 表示服务器向客户端发送响应的协议,如 HTTP/1.1或 HTTP/1.0

Example

http raw request

POST https://learn.app/test.php?test=a&p1=v1 HTTP/1.1
User-Agent: Fiddler
Host: learn.app
Content-Length: 23
Content-Type: text/plain
Cookie: name=test
Name: http_name field value
Authorization: Basic enFob25nOnBhc3N3b3JkCg==

hello world
123
456

http raw response

HTTP/1.1 200 OK
Server: nginx/1.9.11
Date: Sun, 05 Feb 2017 11:02:55 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Content-Length: 11

hello world

log

arg_test: a
args: test=a&p1=v1
binary_remote_addr: \xC0\xA8\x0A\x01
body_bytes_send: 21
bytes_sent: 191
connection: 21
connection_requests: 1
content_length: 23
content_type: text/plain
cookie_name: test
document_root: /home/vagrant/Code/learn/public
document_root: /home/vagrant/Code/learn/public
document_uri: /test.php
host: learn.app
hostname: homestead
http_name: http_name field value
https: on
is_args: ?
limit_rate: 0
msec: 1486292575.656
nginx_version: 1.9.11
pid: 9367
pipe: .
proxy_protocol_addr: 
query_string: test=a&p1=v1
realpath_root: /home/vagrant/Code/learn/public
remote_addr: 192.168.10.1
remote_port: 47566
remote_user: zqhong
request: POST /test.php?test=a&p1=v1 HTTP/1.1
request_body: hello world\x0D\x0A123\x0D\x0A456\x0D\x0A
request_body_file: -
request_completion: OK
request_method: POST
request_time: 0.204
request_uri: /test.php?test=a&p1=v1
scheme: https
sent_http_content_type: text/html; charset=UTF-8
server_addr: 192.168.10.10
server_name: learn.app
server_port: 443
server_protocol: HTTP/1.1
status: 200
tcpinfo_rtt: 2589
tcpinfo_rttvar: 4995
tcpinfo_snd_cwnd: 10
tcpinfo_rcv_space: 28960
time_iso8601: 2017-02-05T11:02:55+00:00
uri: /test.php

用HTTP proxy module配置一个反向代理服务器

负载均衡的基本配置

(1)upstream块

语法:upstream name{……}

配置块:http

upstream块定义了一个上游服务器的集群,便于反向代理中的proxy_pass使用。例如:

upstream backend {
  server backend1.example.com;
  server backend2.example.com;
  server backend3.example.com;
}

server {
  location / {
    proxy_pass http://backend;
  }
}

(2)server

语法:server name[parameters];

配置块:upstream

server配置项指定了一台上游服务器的名字,这个名字可以是域名、IP地址端口、UNIX句柄等,在其后还可以跟下列参数。

□ weight=number:设置向这台上游服务器转发的权重,默认为1。

□ max_fails=number:该选项与fail_timeout配合使用,指在fail_timeout时间段内,如果向当前的上游服务器转发失败次数超过number,则认为在当前的fail_timeout时间段内这台上游服务器不可用。max_fails默认为1,如果设置为0,则表示不检查失败次数。

□ fail_timeout=time:fail_timeout表示该时间段内转发失败多少次后就认为上游服务器暂时不可用,用于优化反向代理功能。它与向上游服务器建立连接的超时时间、读取上游服务器的响应超时时间等完全无关。fail_timeout默认为10秒。

□ down:表示所在的上游服务器永久下线,只在使用ip_hash配置项时才有用。

□ backup:在使用ip_hash配置项时它是无效的。它表示所在的上游服务器只是备份服务器,只有在所有的非备份上游服务器都失效后,才会向所在的上游服务器转发请求。

例如:

upstream backend {
  server backend1.example.com weight=5;
  server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
  server unix:/tmp/backend3;
}

(3)ip_hash

语法:ip_hash;

配置块:upstream

(4)记录日志时支持的变量

变量名 意义
$upstream_addr 处理请求的上游服务器地址
$upstream_cache_status 表示是否命中缓存,取值范围:MISS、EXPIRED、UPDATING、STALE、HIT
$upstream_status 上游服务器返回的响应的 HTTP 响应码
$upstream_response_time 上游服务器的响应时间,精确到毫秒
$upstream_http_HEADER HTTP 头部,如 upstream_http_host

反向代理的基本配置

(1)proxy_pass

语法:proxy_pass URL;

配置块:location、if

此配置项将当前请求反向代理到URL参数指定的服务器上,URL可以是主机名或IP地址加端口的形式,例如:

proxy_pass http://localhost:8000/uri/;

也可以是UNIX句柄:proxy_pass http://unix:/path/to/backend.socket:/uri/;

还可以如上节负载均衡中所示,直接使用upstream块,例如:

upstream backend {
  …
}

server {
  location / {
    proxy_pass http://backend;
  }
}

用户可以把HTTP转换成更安全的HTTPS,例如:

proxy_pass https://192.168.0.1;

默认情况下反向代理是不会转发请求中的Host头部的。如果需要转发,那么必须加上配置:

proxy_set_header Host $host;

(2)proxy_method

语法:proxy_method method;

配置块:http、server、location

(3)proxy_hide_header

语法:proxy_hide_header the_header;

配置块:http、server、location

(4)proxy_pass_header

语法:proxy_pass_header the_header;

配置块:http、server、location

(5)proxy_pass_request_body

语法:proxy_pass_request_body on|off;

默认:proxy_pass_request_body on;

配置块:http、server、location

作用为确定是否向上游服务器发送HTTP包体部分。

(6)proxy_pass_request_headers

语法:proxy_pass_request_headers on|off;

默认:proxy_pass_request_headers on;

配置块:http、server、location

作用为确定是否转发HTTP头部。

(7)proxy_redirect

语法:proxy_redirect[default|off|redirect replacement];

默认:proxy_redirect default;

配置块:http、server、location

(8)proxy_next_upstream

语法:proxy_next_upstream[error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off];

默认:proxy_next_upstream error timeout;

配置块:http、server、location


第二部分:如何编写 HTTP 模块


第三部分:深入 Nginx

zqhong commented 7 years ago

配置文件结构

  1. 一个简单的指令包含:指令名、参数以及结束符(分号)。例如, root /data/www;
  2. 一个块指令(block directive)包含:指令名、开始符({)和结尾符(})。如果一个块指令能够包含其他指令,那它则被称为 context(像 events、http、server 和 location,都是 context)。
  3. 最外层的块指令被 main context 包围。

例如:

http {
    server {
    }
}
zqhong commented 7 years ago

map 用法 map 在这里为映射的意思,$foo 的值会根据 $args 的值在映射表中寻找。即,$foo = map['$args']。需要注意的是,Nginx 会在第一次取值之后缓存结果。

map $args $foo {
    default     0;
    debug       1;
}

server {
    listen 8080;

    location /test {
        set $orig_foo $foo;
        set $args debug;

        echo "original foo: $orig_foo";
        echo "foo: $foo";
    }
}
$ curl 'http://localhost:8080/test'
original foo: 0
foo: 0
$ curl 'http://localhost:8080/test?debug'
original foo: 1
foo: 1

参考: agentzh 的 Nginx 教程 - Nginx 变量漫谈(四)

zqhong commented 7 years ago

Nginx 平滑升級

  1. 查看当前版本的编译参数
    $ nginx -V
  2. 下载新版本的 nginx,并编译
    $ tar zxvf nginx-1.0.5.tar.gz
    $ cd nginx-1.0.5
    $ ./configure
    --user=www 
    --group=www 
    --prefix=/usr/local/nginx 
    --with-http_stub_status_module 
    --with-http_ssl_module 
    --with-http_flv_module 
    --with-cc-opt='-O3' 
    --with-cpu-opt=opteron 
    --with-http_gzip_static_module
    $ make
  3. 重命名原先的 nginx 可执行文件为 nginx.old
    $ mv /usr/sbin/nginx /usr/sbin/nginx.old
  4. 替换原先的 nginx
    $ cp objs/nginx /usr/sbin/nginx
  5. 测试新版本的 nginx 能否正常工作
    $ /usr/sbin/nginx -c /etc/nginx/nginx.conf
  6. 让 nginx 把 nginx.pid 文件修改为 nginx.pid.oldbin,随即启动 nginx
    $ kill -USR2 `cat /run/nginx.pid`
  7. 停止旧的 nginx master进程及 worker 进程
    # 平滑停止旧的 worker process
    $ kill -WINCH `cat /run/nginx.pid.oldbin`
    # 停止旧的 master 进程
    # kill -QUIT `cat /run/nginx.pid.oldbin`

备注: 升级失败的处理

# 发送 HUP 信号给旧的 master 进程,它将开启新的 worker 进程
$ kill -HUP `cat /run/nginx.pid.oldbin`
# 发送 QUIT 给新的 master 进程
$ kill -QUIT `cat /run/nginx.pid`
zqhong commented 7 years ago

rewrite指令 语法:rewrite regex replacement flag 默认值:none 使用环境:server, location, if 该指令根据表达式来重定向URI,或者修改字符串。指令根据配置文件中的顺序来执行。 注意重写表达式只对相对路径有效。如果你想配对主机名,你应该使用if语句,代码如下:

如果替换串以http://开头,将会采用301或302跳转进行URL重定向。 rewrite指令的最后一项参数为flag标记,支持的flag标记有: · last——相当于Apache里的[L]标记,表示完成rewrite; · break——本条规则匹配完成后,终止匹配,不再匹配后面的规则; · redirect——返回302临时重定向,浏览器地址栏会显示跳转后的URL地址; · permanent——返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。 在以上的标记中,last和break用来实现URI重写,浏览器地址栏的URL地址不变,但在服务器端访问的路径发生了变化。redirect和permanent用来实现URL跳转,浏览器地址栏会显示跳转后的URL地址。 last和break标记的实现功能类似,但二者之间有细微的差别,使用alias指令时必须用last标记,使用proxy_pass指令时要使用break标记。last标记在本条rewrite规则执行完毕后,会对其所在的server{......}标签重新发起请求,而break标记则在本条规则匹配完成后,终止匹配,不再匹配后面的规则。例如以下这段规则,就必须使用break标记,使用last标记会导致死循环: