Beginner's Guide
proxies 代理人,保险代理人,是干活的哪个哥们。(本文中称作 “后台代理”)
proxy 代理,保险代理公司,是业务,代理业务。(本文中称作 “代理”)
nginx 配置文件有一堆堆的指令构成,指令分为 简单指令和快指令。指令由参数名(指令名)和参数构成。
关于选项和参数的概念,在本文描述的 nginx 配置与 Linux 命令行命令,以及 Windows 命令行命令是一致的。(argor 个人认为的^_^)
配置文件的结构
- 配置文件由容器指令和简单指令组成。
- 简单指令,由空格分隔指令名和参数,以分号结尾。
- 容器指令,由一对大括号代替分号。
- 井号开头行,表示注释。
# 这是主容器 events { } http { server { location { } } }
主容器包含:events、http。……
静态资源发布
- 响应
http://localhost/images/demo1.png
请求,返回 /data/images/demo1.png
- 响应 URI 不是以 /images 开头的请求,返回 /data/www 下的内容
- 请求 http://localhost/hello.index,在 /data/www 下没有 hello.index 时返回 404
- 请求 http://localhost,没有 index.html 时,返回 403
server { location / { root /data/www; } location /images/ { root /data; } }
location 响应时,会把 uri 加到 root 指令的参数上去。
location 响应请求时,最长匹配优先。 - 官方文档
设置简单代理服务器
- 配置代理服务,响应请求转发到后台代理。
- 设定一个后台代理
server { listen 8080; root /data/up1; location / { } }
-
创建 server 块指令,放入 proxy_pass 指令。
server { location / { proxy_pass http://localhost:8080; } location ~ .(gif|jpg|png)$ { root /data/images; } }
代理模式:响应请求 http://localhost/ 会被发送到后台代理由 http://localhost:8080 来响应并返回。
图片匹配:响应请求 http://localhost/demo1.png 会返回本地目录 /data/images/demo1.png
location 优先最长精确匹配,然后查找正则表达式,最后迁就短匹配。
这个代理配置,过滤请求 .gif、.png、.jpg 由本地目录响应。转发其他请求到后台代理。
fastCGI代理
Admin's Guide
Configuring Nginx as a Web Server
- 虚拟主机用 server 指令定义在 http 容器。
- 虚拟主机常常包含 listen 指令,用来指定监听的地址和端口(Unix 套接字和路径)。
1.没有指定端口,使用默认端口 80。没有地址,默认监听全部地址。
2.根本就没有 listen 指令,标准端口 80/tcp,默认端口 8000/tcp 被启用在全部 ip 端口。
3.连 server 都没有,……?自己测,上边叙述的关于 listen 的情况是有 server 的。server { listen 127.0.0.1:8001; }
- 当有多个 server 匹配了一致的 IP address 和 port 时,nginx 依据 http 请求头的 Host 信息检查 server_name 指令。
server_name 的参数允许写全名、通配符、正则表达式。匹配顺序参考官方文档,略……server { listen 80; server_name *.argor.cn; }
默认主机的:带了 default_server 参数的 listen 指令,或者没有指定时,位于 nginx.conf 第一个 server 就是。server { listen 80 default_server; # xixi }
- nginx 有本事把流量转发给不同的后台代理,亦或为不同的 URI 响应不一样的 本地文件。这一切都全靠 server 中的 location 指令。
location 的本事是把特定的请求发送到相应的后台代理,发送其他请求到该去……,响应该交付的本地文件。
location 可以完全解读【请求头】信息。该指令有两类参数:pathname、正则表达式。location /data/ { # pathname... } location ~ .html? { # re }
匹配优先级参与官文。
在 location 指令块中,可以定义如何解读一个 request(是响应本地静态资源,还是转发请求到后台代理)。server { # 静态资源本地处理,采用 pathname 的方式,有个暗语:start with。 location /images/ { root /data; } # ……转发后台代理 location / { proxy_pass http://www1.argor.cn; } }
root 指令,指定文件系统路径 /data/images 来响应静态资源。
proxy_pass 指令,转发 location 匹配的请求到后台代理,并且指明后台代理如何匹配。
使用 return 指令,可以立即返回错误代码、或者重定型信息。server { location /error/ { return 403; } location /baidu/ { return 301 https://baidu.com; } }
- 请求地址重写 rewrite 指令,该指令允许在【location 中】,或【server 中】多次出现。
rewrite 包含一个选项两个参数。头一个参数为正则匹配,后一个参数是替换。选项作为第三个参数,表示动作【放弃处理、继续重写、转发】。 - HTTP响应重写 sub_filter 指令。
location / { sub_filter 'href="http://127.0.0.1:8080/' 'href="https://$host/'; sub_filter 'img src="http://127.0.0.1:8080/' 'href="https://$host/'; sub_filter_once on; #连续处理 sub_filter }
把 http 响应修改为 https,私网地址修改为 hostname。
相同的处理项目,不会被后续配置覆盖。 - 异常处理 error_page
Serving Static Content
- 根指令 root,允许出现在 http{ }、server{ }、location{ } 指令块。
在 root 没有被覆盖设定的情况下,逐级继承。#以继承的视角,理解下这个配置 server { root /data/www; location / { } location /images/ { } location ~ .(mp3|mp4)$ { root /www/media; } }
该虚拟主机,以 /images/ 开头的 URI 继承了 server 的 root 指令参数。
而以 .mp3 或 .mp4 结尾的 URI 重写了 root 的指令参数。 - 索引指令 index,定义索引文件名,默认 index.html。
# 首页索引文件 location / { index main.html; } # 目录浏览 location /iso { root /data/; autoindex on; }
index 指令允许指定多个参数,Nginx 对多个索引名逐一搜索检查是否存在。把最先找到的 index 参数追加到 URI 进行内部重定向。
内部重定向,有可能导致结果发生断崖式逆转。location / { root /data; index index.html index.php; } location ~ .php { fastcgi_pass localhost:8000; #... }
当 index.html 不存在时,却找到了 index.php,这个时候的内部重定向,会导致本次请求的 URI 被转发出去。
- try_files 指令,可以检查是否存在某个指定的文件或目录。
存在,内部重定向。不存在,返回状态码。
Nginx Reverse Proxy
- Passing a Request to a Proxied Server
在 location 中使用 proxy_pass 指令,转发请求到 HTTP 后台代理。#转发http时,可以附带 uri location /php { proxy_pass http://www1.argor.cn/link/; } #还可以附带 端口 location /java { proxy_pass http://argor.top:8080; }
代理转发时带有 uri,请求 http://localhost:80/php/getList 被转发到 http://www1.argor.cn/link/getList。
没有 uri,转发完整的 uri,不会发生替换。
转发非http时,使用 **_pass 指令。
proxy_pass 还可以指向一个后台代理服务器组。 - Passing Request Headers
默认情况下,Nginx 会重写两个请求头参数:Host、Connection。并且,剪除空值参数。
代理会把 connection 关闭。
代理会重写 Host 为代理自己的信息。通常需要阻止一下:location /some/path/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; #proxy_pass .....; }
因为代理的默认行为,要是需要不传递某个请求头参数时,就可以选择性置空。
location /some/path/ { proxy_set_header Accept-Encoding ""; #proxy_pass http://...... }
- Choosing an Outgoing IP Address
location /app1/ { proxy_bind 127.0.0.1; proxy_pass http://example.com/app1/; } location /app2/ { proxy_bind 127.0.0.2; proxy_pass http://example.com/app2/; } location /app3/ { proxy_bind $server_addr; proxy_pass http://example.com/app3/; }
Nginx SSL
- HTTPS
在 server 的 listen 指令附加 ssl 参数,并且使用 ssl_certificate、ssl_certificate_key 指定证书名称和密钥名称(相对路径为nginx配置的root)。server { listen 443 ssl; server_name www.example.com; ssl_certificate www.example.com.crt; ssl_certificate_key www.example.com.key;
# 下边两项为 nginx 默认值。 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; #... } - SSL 会消耗额外的 cpu 资源。存在大量的客户端时,会伴随大量的 SSL 握手过程。
worker_processes auto; http { # 加缓存、延长超时
# 1m的缓存,大概可容纳 4000 个会话。 ssl_session_cache shared:SSL:10m;
# 如果配置超时 4h,大概需要 20MB 缓存。 ssl_session_timeout 10m; server { listen 443 ssl; server_name www.argor.cn; keepalive_timeout 70;
# 握手超时默认 60s。太长会导致失败等待过久,太短会导致握手失败。
ssl_handshake_timeout 10s; ssl_certificate www.argor.cn.crt; ssl_certificate_key www.argor.cn.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; #... } } -
接受 tcp 连接的负载均衡 ssl
stream { upstream stream_backend { server backend1.example.com:12345; server backend2.example.com:12345; server backend3.example.com:12345; } server { listen 443 ssl; proxy_pass stream_backend; ssl_certificate /etc/ssl/certs/server.crt; ssl_certificate_key /etc/ssl/certs/server.key; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; ssl_session_cache shared:SSL:20m; ssl_session_timeout 4h; ssl_handshake_timeout 30s; #... } }
高可用
- 基于 Keepalived 实现 Nginx 的高可用。
- 有些长,请移步...