概述:将学习Nginx服务器的重要功能--代理服务。
本章涉及内容:
正向代理与反向代理的基本概念
在正向代理服务器中,我们的角色是客户端,目的是访问外网的资源。在反向代理服务器中,我们的角色是站点,目的是把站点的资源发布出去让其他客户端能够访问到。
该指令用于指定DNS服务器的IP地址。DNS服务器的主要工作室进行域名解析,将域名映射为对应的IP地址
语法:resolver address ... [valid=time];
address , DNS服务器的IP地址,不指定端口,默认值53端口
time 设置数据包在网络中的有效时间 (数据包来不及传输)
例如:
resolver 127.0.0.1 [::1]:5353 valid=30s
该指令用于设置DNS服务器域名解析超时时间。
resolver_timeout time;
该指令用于设置代理服务器的协议地址。它不仅仅是用于Nginx服务器的代理服务,更主要是应用于反向代理服务
proxy_pass URL;
URL即为设置的代理服务器协议和地址
例如:proxy_pass http://$http_host$request_uri;
$http_host:主机 request_uri URI的变量
...
server
{
resolver 8.8.8.8;
listen 82;
location/{
proxy_pass http://$http_host$request_uri;
}
}
.....
Nginx服务器提供的反向代理服务也是比较高效的,它能够同时接收的客户端连接有worker_processes指令和worker_connections指令决定,计算方法为worker_processes*worker_connections/4
指令主要由ngx_http_proxy_module模块进行解析和处理,该模块是Nginx服务器的标准的HTTP模块
该指令用来设置被代理服务器的地址,可以是主机名称、IP地址+端口等形式
语法: proxy_pass URL;
URL: 设置的被代理服务器的地址,包含传输协议,主机名称或IP地址+端口号、URI等要素,传输协议通常是“http” "https://” 或者unix
例如:
proxy_pass http://www.myweb.name/rui;
proxy_pass http://localhost:8000/uri/;
proxy_pass http://unix:/tmp/backend.socket:/uri/;
如果是配置一组服务器的话,可以使用upstream指令配置后端服务器组
...
upstream proxy_svrs #配置后端服务器组
{
server http://192.168.1.1:8001/uri/;
server http://192.168.1.1:8002/uri/;
server http://192.168.1.1:8003/uri/;
}
server
{
...
listen 80;
server_name www.myweb.name;
location /
{
proxy_pass proxy_svrs; #使用服务器组的名称
}
}
那么 proxy_pass proxy_svrs; 改为proxy_pass http://proxy_svrs;
注意:URL中是否包含有URI,Nginx服务器的处理方式不同的。如果URL不包含URI,Nginx服务器不会改变原地址的URI;如果包含URI,Nginx服务器将会使用新的URI替代原来的URI
例如:
...
server
{
...
listen 80;
server_name www.myweb.name;
location /server/
{
...
proxy_pass http:192.168.1.1;
}
}
包含URI变量
...
server
{
...
listen 80;
server_name www.myweb.name;
location /server/
{
...
proxy_pass http:192.168.1.1/loc/;
}
}
proxy_pass 包含了URI “/loc/” 。如果客户端仍然使用"http://www.myweb.name/server/"发起请求。Nginx服务器地址将会"http://192.168.1.1/loc/"。
简单来说,就是以proxy_pass设置URI为主,没有才用请求的URI
讨论proxy_pass指令的URL变量末尾是否加斜杠"/"问题
例如:
#配置1 : proxy_pass http://192.168.1.1;
#配置2: proxy_pass http://192.168.1.1/;
加了"/"被称为有URI,没有加“/”没有URI
...
server
{
...
listen 80;
server_name www.myweb.name;
location /
{
...
#配置 1 proxy_pass http:192.168.1.1;
#配置 2 proxy_pass http:192.168.1.1/;
}
}
客户端请求URL为"http://www.myweb.name/index.html"
两个配置都会转到 "http://192.168.1.1/index.html".
...
server
{
...
listen 80;
server_name www.myweb.name;
location /server/ #注意location的uri变量
{
...
#配置 1 proxy_pass http:192.168.1.1;
#配置 2 proxy_pass http:192.168.1.1/;
}
}
客户端请求URL为"http://www.myweb.name/index.html"
配置1:“http://192.168.1.1/server/index.html”
配置2:"http://192.168.1.1/index.html"
总结:如果location有uri变量,代理uri变量同时存在,只留代理uri
该指令用于设置Nginx服务器在发送HTTP响应时,隐藏一些头域信息
proxy_hide_header field;
其中 field为需要隐藏的头域。可以http块、server、location块中进行配置。
默认情况下,Nginx服务器在发送响应报文时,报文中不包含“Date” 、“Server” 、“X-Accel”等来自被代理服务的头域信息,该指令可以设置这些头域信息以被发送
语法:proxy_pass_header field;
field 为需要发送的头域
该指令用于配置是否将客户端请求的请求体发送给代理服务器
proxy_pass_request_body on | off;
默认设置为开启(on),可以在http块、server块或location块中配置
该指令用于配置是否将客户端请求的请求头发送给代理服务器
proxy_pass_request_body on | off;
默认值开启(on)
该指令可以更改Nginx 服务器接收到的客户端请求的的请求头信息。然后将新的请求头发送的被代理服务器。
proxy_set header field value;
field , 要更改的信息所在的头域
value 更改的值,支持使用文本、变量或者变量的组合
默认情况下
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
proxy_set_header Host $http_host; #将目前Host头域的值填充成客户端的地址
proxy_set_header Host $host; # 将当前location块的server_name指令填充到Host头域
proxy_set_header Host $host : $proxy_port; #将当前location块的server_name 指令值和 listener指令之一起填充到Host头域
该指令可以更改Nginx服务器接收到客户端请求的请求体信息。然后将新的请求体发送被代理的服务器。
proxy_set_body value;
value 为更改的信息。支持使用文本、变量或者变量的组合
强制将于代理主机的连接绑定到指定的IP地址。
proxy_bind address;
其中address为指定主机IP地址
该指令配置Nginx服务器与后端被代理服务器尝试建立连接的超时时间。
proxy_connect_timeout time;
默认值为60s
该指令配置Nginx服务器后端被代理服务器(组)发出read请求后,等待响应的超时
proxy_read_timeout time;
默认值60s
该指令配置Nginx服务器向后端被代理武器发送write请求后,等待超时的时间
proxy_send_timout time;
该指令用于配置用于Nginx服务器提供代理服务器的HTTP协议版本
proxy_http_version 1.0 | 1.1;
默认设置1.0版本,1.1版本支持upstream服务器组设置keepalive指令。
该指令用于设置Nginx服务器请求被代理服务器时使用的请求的方法一般为POST或GET。
proxy_method method
method的值可以设置为POST或者GET ,注意不要加引号
该指令用于设置在客户端中断网路请求时。Nginx服务器是否中断对被代理服务器的请求。
proxy_ignore_client_abort on | off;
默认设置为off,当客户端中断网络请求时,Nginx服务器中断对被代理服务器的请求。
该指令用于设置一些HTTP响应头中的头域。Nginx服务器接收到被代理服务器的响应数据中,不会处理被设置的头域
proxy_ignore_headers field ...;
其中 field为要设置的HTTP响应头的头域。例如“X-Accel-Redirect”、“X-Accel-Expires”、“”Expires“、“Cache-Control” 或“Set-Cookie”
该指令用于修改被代理服务器返回的响应头中Location头域和“Refresh”头域,与proxy_pass指令配合使用。
1、proxy_redirect redirect replacement;
2、proxy_redirect default;
3、proxy_redirect off; #当前所处{}的proxyredirect的配置失效
redirect 匹配“Location”头域值的字符串。支持变量的使用和正在表达式。
replacement. 用于替换redirect变量内容的字符串,支持变量使用。
对于第一个结构
Location:http://localhost:8081/proxy/some/uri/
指令设置:
proxy_redirect http://localhost:8081/proxy/ http://myweb/frontend/;
修改:
Location: http://myweb/frontend/some/uri/ #域名地址改变了
配置1和配置2效果一样
#配置1
location /server/
{
proxy_pass http://proxyserver/source/;
proxy_redirect default;
}
#配置2
location /server/
{
proxy_pass http://proxyserver/source/;
proxy_redirect http://proxyserver/source/ /server/;
}
该指令用于配置一个状态是开启还关闭。在开启该状态时,如果被代理的服务器返回的HTTP状态代码为400或者大于400,则Nginx服务器使用自己定义的错误页(使用error_page指令);如果是关闭状态,Nginx服务器直接将被代理服务器返回的HTTP状态返回给客户端。
proxy_intercept_errors on | off;
该指令用于配置存放HTTP报文头的哈希表的容量。
proxy_headers_hash_max_size size;
size 为HTTP报文头哈希表的容量上限,默认为512字符
proxy_headers_hash_max_size 512;
Nginx服务器为了能够快速检索HTTP报文头中的各项信息。
该指令用于设置Nginx服务器申请存放HTTP报文头的哈希表容量的单位大小。
proxy_headers_hash_bucket_size size;
其中size为设置的容量,默认为64个字符
配置Nginx服务器反向代理功能时,轮询代理服务器组规则
proxy_next_upstream status ...;
status 为设置服务器返回状态,可以是一个或多个
error 在建立连接,向被代理的服务器发送请求或读取响应头时服务器发生连接错误。
timeout 在建立连接、向被代理的服务器发送请求或读取响应头时服务器连接超时。
invalid_header 被代理的服务器返回的响应头为空或者无效
off 无法将请求发送给被代理的服务器。
该指令用于配置是否使用基于SSL安全协议的会话连接(“https://”)被代理的服务器。
proxy_ssl_session_reuse on | off;
默认设置为开启(on)状态,如果我们在错误日志中发现“SSL3_GET_FINISHED:digest check failed”的情况。可以将指令配置为关闭off状态。
该指令用于配置是否启用或关闭Proxy Buffer
proxy_buffering on | off;
默认设置为开启状态。
开启和关闭Proxy Buffer还可以还可以在HTTP响应头部的"X-Accel-Buffering"头域设置“yes”或者“no”来实现。但Nginx配置中proxy_ignore_headers指令的设置可能导致该头域设置失效。
该指令用于配置接收一次被代理服务器响应数据的Proxy Buffer个数和每个Buffer的大小。
proxy_buffers number size;
number Proxy Buffer的个数
size 每个Buffer的大小,一般设置为内存页的大小。一般为4k或者8kb
proxy_buffers 8 4k|8k;
该指令用于配置从被代理服务器获取的第一部分响应数据的大小。该数据中一般包含了HTTP响应头,Nginx服务器通过他来获取响应数据和被代理服务器的一些必要的信息
proxy_buffer_size size;
size 为设置的缓存大小, 默认设置为4KB或者8KB
该指令用于限制同时处于BUSY状态的Proxy Buffer的总大小
proxy_busy_buffers_size size;
size为设置的处于BUSY状态的缓存区总大小,默认值为8KB或16KB
该指令用于配置磁盘上的一个文件路径该文件用于临时存放代理服务器的大体积响应数据。如果ProxyBuffer被装满后,响应数据仍然没有被Nginx服务器完全接收。响应数据将会被临时存放在该文件中。
proxy_temp_path path [level1][level2][level3]
path 设置磁盘上存放临时文件的路径
levelN 设置在path变量设置的路径下第几级hash目录中存放临时文件。
proxy_temp_path /nginx/proxy_web/spool/proxy_temp 1 2;
/nginx/proxy_web/spool/proxy_temp/1/10/000000010101 可能路径
该指令用于配置所有临时文件的总体积大小,存放在磁盘上的临时文件大小不能超过该配置值。
proxy_max_temp_file_size size
默认值为1024MB
该指令用于配置同时写入临时文件的数据量的总大小。合理的设置可以避免磁盘IO负载过重导致系统性能下降的问题
proxy_temp_file_write_size size;
size为设置的数据量总大小上限值,默认值设置根据平台的不同,可以为8KB或16KB
Buffer 和 Cache区别。“缓冲”和“缓存”,
Buffer,主要用于传输效率不同步或者优先级别不相同的设备之间传递数据,一般通过对一方数据进行临时存放,在统一发送的办法传递给另一方,以降低进程之间的等待时间,保证速度较快的进程不发生间断,临时存放的数据一旦传送给另一方,这些数据本身也就没有用了;
Cache, 主要用于将硬盘上已有的数据在内存中建立缓存数据。提高数据的访问效率,对于国企不用的缓存可以随时销毁,但不会销毁硬盘上的数据。
在Nginx服务器中。Proxy Buffer和ProxyCache都与代理服务器相关,主要用来提供客户端与被代理服务器之间的交互效率。ProxyBuffer实现了被代理服务器响应数据的异步传输,,Proxy Cache则主要实现Nginx服务器对客户端数据请求的快速响应。Nginx服务器在接收到被代理服务器的响应数据之后,一方面通过Proxy Buffer机制将数据传输给客户端。另一方面根据Proxy Cache的配置将这些数据缓存到本地磁盘上。当客户端下次要访问相同的数据时,Nginx服务器直接从硬盘检索到响应的数据返回给用户。从而减少被代服务器交互的时间。
特别需要说明是,Proxy Cache 机制依赖于Proxy Buffer机制。只有在Proxy Buffer机制开启情况下Proxy Cache的配置才发挥作用。
Proxy Store 与Proxy Cache的区别是。它对来自被代理服务器的响应数据。尤其是静态数据只进行简单的缓存。不支持缓存过期更新、内存索引建立等功能。但支持设置用户或用户组对缓存数据的访问权限。
该指令用于配置一块公用的内存区域的名称。该区域可以存放缓存的索引数据
proxy_cache zone | off;
zone, 设置的用于存放缓存索引的内存区域的名称
off, 关闭proxy_cache功能,是默认的设置。
该指令用于配置Nginx服务器向客户端响应数据时,不从缓存中获取的条件。
proxy_cache_bypass string ...;
string 为条件变量,支持设置多个,当至少一个字符串指令不为空或者不等于0时,响应数据不从缓存中获取
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment $http_pragma $http_authorization;
该指令用于设置Nginx服务器在内存中为缓存数据建立索引时使用的关键字。
proxy_cache_key string;
string 为设置关键字,支持变量
希望缓存数据包含服务器主机名称等关键字
proxy_cache_key "$scheme$host$request_uri";
该指令用于设置是否开启缓存的锁功能。在缓存中,某些数据项可以同时被多个请求返回的响应数据填充。开启之后,智能一个请求获取缓存中的数据项。
proxy_cache_lock on | off;
默认值是关闭
该指令用于设置缓存的锁功能开启以后锁的超时时间。
proxy_cache_lock_timeout time;
默认值为5s
该指令用于设置客户端请求发送的次数。 当客户端向被代理服务器发送相同请求达到该指令设置的次数之后,Nginx服务器才对该请求的响应数据做缓存。
proxy_cache_min_uses number;
number为设置的次数 默认值为1.
该指令用设置Nginx服务器存储缓存数据的路径以及和缓存索引相关的内容
proxy_cache_path path [levels=levels] keys_zone =name:size1[inactive=time1] [max_size=size2] [loader_files=number] [loader_sleep=time2][loader_threshold=time3]
path 设置缓存存放的根路径。该路径应该是预先存在于磁盘上。
levels 设置在相对于path指定目录的第几级hash目录中缓存数据。levels=1.表示一级hash目录。levels=1:2表示两级 ,依次类推
name:size1 Nginx 服务器的缓存索引重建进程在内存中为缓存数据建立索引,这一对变量用于设置存放缓存索引的内存区域的名称和大小
time1 设置强制更新缓存数据的时间。当硬盘上缓存数据在设定的时间没有被访问时,Nginx服务器就强制从硬盘上将其删除。默认值为10s
siz2 : 设置硬盘中缓存数据的大小限制。内存就这个大,它会将很少用到的缓存进行删除
number 设置缓存索引重建进程每次加载的数据元素的数量上限。该值限制了每次遍历中同时加载的数据元素的数量,默认值为100.
time2 设置缓存索引重建进程在一次遍历结束、下次遍历开始之间的暂停时长。默认值为50ms
time3 设置遍历一次磁盘缓存数据的时间上限。默认值设置为200ms
简单配置例子:
proxy_cache_path /nginx/cache/a levels =1 keys_zone=a:10m;
proxy_cache_path /nginx/cache/b levels=2:2 keys_zone=b:100m;
proxy_cache_path /nginx/cache/c levels=1:1:2 keys_zone=c:1000m;
该指令只能放在http块中。
采用历史数据进行响应。Nginx服务器的该功能在一定程度上能够为客户端提供不间断访问。
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504|http_404 | off ...;
该指令可以支持的状态,将采用使用缓存数据。
该指令可以针对不同的HTTP响应的状态设置不同的缓存的时间。
proxy_cache_valid [code ...] time;
code 设置HTTP响应的状态代码 可选 默认值只会为200 301 302 的响应数据做缓存。可以使用“any”表示缓存所有该指令中未设置的其他相应数据
time 设置缓存时间。
proxy_cache_valid 200 302 10m; #返回状态为200和302的响应数据缓存10分钟
proxy_cache_valid 301 1h; # 返回为301的响应数据缓存1小时
proxy_cache_valid any 1m; # 返回为非200/302、和301的响应数据缓存1分钟
该指令用于配置在什么情况下不使用cache功能
proxy_no_cache string ...
string 可以是一个或多个变量。当string的值不为空或者不为“0”时,不启用cache功能
该指令配置是否在本地磁盘缓存来自被代理服务器的响应数据。它不提供缓存过期更新。内存索引建立等功能,不占用内存空间。对静态数据的效果比较好
proxy_store on | off | string;
on | off, 设置是否开启proxy Store功能。如果使用使用变量on,功能开启。缓存文件会存放到alias指令或root指令设置的本地路径下。默认值为off。
string 自定义缓存文件的存放路径。
该指令用于设置用户或用户组对proxy store缓存的数据访问权限。
proxy_store_access users:permissions ...;
users 可以设置为user、group或all。
permissions 设置权限
location /images/
{
root /data/www;
error_page 404=/fetch$uri; #定义了404错误的请求页面
}
location /fetch/ #匹配404错误时的请求
{
proxy_pass http://backend;
proxy_store on; #开启Proxy Store 方法
proxy_store_access user:rw group:rw all:r; #用户访问proxy_store权限控制
root /data/www; #缓存数据的路径
}
网络负载均衡(Load Balancing)
网络负载均衡技术的大致原理是利用一定的分配策略将网络负载平衡地分摊到网络集群的各个操作单元上。
...
upstream backend
{
server 192.168.1.2:80;
server 192.168.1.3:80;
server 192.168.1.4:80;
}
server
{
listen 80;
server_name www.myweb.name;
index index.html index.htm;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
...
}
...
}
...
upstream backend
{
server 192.168.1.2:80 weight=5;
server 192.168.1.3:80 weight=3;
server 192.168.1.4:80; # 默认weight=1
}
server
{
listen 80;
server_name www.myweb.name;
index index.html index.htm;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
...
}
...
}
...
upstream videobackend
{
server 192.168.1.2:80;
server 192.168.1.3:80;
server 192.168.1.4:80; # 默认weight=1
}
upstream filebackend
{
server 192.168.1.5:80;
server 192.168.1.6:80;
server 192.168.1.7:80; # 默认weight=1
}
server
{
listen 80;
server_name www.myweb.name;
index index.html index.htm;
location /video/ {
proxy_pass http://videobackend; #使用后端服务器组videobackend;
proxy_set_header Host $host;
...
}
location /file/ {
proxy_pass http://filebackend; #使用后端服务器组filebackend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...
}
...
}
两组后端服务器组中一台服务器server192.168.1.4:80是公用、在该服务器上需要部署两个域名下的所有资源才能保证客户端请求不会出现问题
...
upstream bbsbackend
{
server 192.168.1.2:80 weight=2;
server 192.168.1.3:80 weight=2;
server 192.168.1.4:80; # 默认weight=1
}
upstream homebackend
{
server 192.168.1.4:80;
server 192.168.1.5:80;
server 192.168.1.6:80; # 默认weight=1
}
server
{
listen 80;
server_name home.myweb.name;
index index.html index.htm;
location / {
proxy_pass http://homebackend; #使用后端服务器组homebackend;
proxy_set_header Host $host;
...
}
}
server
{
listen 81;
server_name bbs.myweb.name;
index index.html index.htm;
location / {
proxy_pass http://bssbackend; #使用后端服务器组bbsbackend;
proxy_set_header Host $host;
...
}
}
...
upstream backend
{
server 192.168.1.4:80;
server 192.168.1.5:80;
server 192.168.1.6:80; # 默认weight=1
}
server
{
listen 80;
server_name www.myweb.name;
index index.html index.htm;
location /file/ {
rewrite ^(/file/.*)/media/(.*)\.*$ $1/mp3/$2.mp3 last;
}
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
...
}
}
...
例如客户端的请求URL
"http://www.myweb.name/file/download/media/1.mp3"
重写: "http://www.myweb.name/file/download/mp3/1.mp3"