Nginx之代理和负载均衡

来源:互联网 发布:linux ping网络不可达 编辑:程序博客网 时间:2024/05/21 22:36

一 正向代理和反向代理

1.1 正向代理

正向代理:一般是考虑到内部网络安全,局域网内的客户端无法直接访问互联网上其他的站点,如果想访问外部互联网网站,可以在局域网内设置一台主机可以访问互联网,而其他的客户端则通过这个可以访问外部互联网的主机去访问外部。然后将结果返回给具体的客户端。

 

基于安全考虑,这个代理服务器可以拒绝某些客户端的请求,比如信息敏感或者非法的请求时,相当于起到了一部分防火墙的功能。

 

1.2 反向代理

反向代理:当服务器接收外部互联网请求的时候,并不是自己来处理这些请求,而是将这些请求转发给内部网络上服务器,并从内部网络服务器上获取结果然后返回给internet上请求的客户端。



二 Nginx服务器的正向代理服务

2.1 正向代理指令

一般情况,正向代理比较少使用。也比较简单,这些指令原则上可以出现在http块,server块,或者location块。但是一般在搭建Nginx服务器中单独配置一个server块用来设置代理服务。

# resolver 指令

用于指定DNS服务器的IP地址

resolver address …[valid=time]

address: DNS服务器的IP地址,如果不指定端口号,默认就是53端口

time: 设置数据包在网络中有效时间。

# resolver_timeout指令

用于设置DNS服务器域名解析超时时间

resolver_timeout time

 

# proxy_pass

该指令用于设置代理服务器的协议和地址,他不仅仅用于Nginx服务器的代理服务,更主要是应用于反向代理服务

proxy_pass URL

URL即为设置的代理服务器协议和地址

 

2.2 正向代理服务的使用

server {

      resolver8.8.8.8;

      listen 82;

      location/ {

           proxy_passhttp://$http_host$request_uri

      }

}

 

三 Nginx服务器的反向代理服务

3.1 反向代理服务的指令

3.1.1 proxy_pass

语法格式:proxy_pass URL

用来设置被代理服务器的URL地址,包括传输协议,主机名或者IP:PORT等

proxy_pass http://www.example.com/uri;

proxy_pass 192.168.3.100:8080/uri;

 

# 如果被代理服务器是一组服务器的话,可以使用upstream指令配置后端服务器组

upstream proxy_svrs {

      serverhttp://192.168.3.200:8080/uri/;

      serverhttp://192.168.3.201:8080/uri/;

      serverhttp://192.168.3.202:8080/uri/;

}

 

server {

      listen80;

      server_namewww.example.com;

      location/ {

           proxy_passproxy_svrs;

      }

}

 

# 如果服务器组没有提供传输协议,比如这样:

proxy_pass 就需要加上http:// 或者http://

upstream proxy_svrs {

      server192.168.3.200:8080/uri/;

      server192.168.3.201:8080/uri/;

      server192.168.3.202:8080/uri/;

}

server {

      listen80;

      server_namewww.example.com;

      location/ {

           proxy_passhttp://proxy_svrs;

      }

}

 

# URL中是否包含有uri,Nginx的处理方式是不一样的

如果URL不包含uri,Nginx不会改变原地址的URI,否则如果包含了URI,则Nginx服务器将会使用新的URI替代原来的URI

示例一:

server {

      listen80;

      server_namewww.example.com;

      location/service/ {

           .....

           proxy_passhttp://192.168.3.100;

      }

}

若客户端使用http://www.example.com/service发请请求,该请求匹配location,交给这个location处理,

由于proxy_pass指令的URL不包含URI,所以转向的地址是http://192.168.3.100/service

 

示例二:

server {

      listen80;

      server_namewww.example.com;

      location/service/ {

           .....

           proxy_passhttp://192.168.3.100/loc/;

      }

}

若客户端使用http://www.example.com/service发请请求,该请求匹配location,交给这个location处理,

由于proxy_pass指令的URL包含URI "/loc",所以转向的地址是http://192.168.3.100/loc/

 

# proxy_pass末尾加/斜杠的问题

观察以下2个配置:

配置1:proxy_pass http://192.168.3.100  # 没有uri

配置2:proxy_pass http://192.168.3.100/ # 有uri,uri是/

 

示例一

server {

      listen80;

      server_namewww.example.com;

      location/ {

           .....

           proxy_passhttp://192.168.3.100;

      }

}

针对配置1,由于proxy_pass不包含uri,那么转发的请求就是源地址的uri,即http://192.168.3.100

针对配置2, 由于proxy_pass包含uri,那么转发的地址就是,即proxy_pass指定地址,即http://192.168.3.100/

 

示例二

server {

      listen80;

      server_namewww.example.com;

      location/service/ {

           .....

           proxy_passhttp://192.168.3.100;

      }

}

当访问http://www.example.com/service/的时候,

我们配置1的转发地址是:http://192.168.3.100/service/

我们配置2的转发地址是:http://192.168.3.100/

 

3.1.2proxy_hide_header

语法结构:proxy_hide_headerfield

用于设置Nginx服务器在发送HTTP响应时,隐藏一些header域。该指令可以在http,server和location块上进行配置

 

 

3.1.3proxy_pass_header

语法结构:proxy_pass_headerfield

一般情况下,Nginx服务器在响应的时候,报文不会包含Date,server,X-Accel等来自被代理服务器的header域的信息。该指令可以设置这些头域信息被发送。该指令可以在http,server和location块上进行配置

 

 

3.1.4proxy_pass_request_body

语法结构:proxy_pass_request_bodyon | off,默认为on

用于是否将客户端的请求体发送给代理服务器。该指令可以在http,server和location块上进行配置

 

 

3.1.5proxy_pass_request_header

语法结构:proxy_pass_request_headeron | off

用于是否将客户端的请求头发送给代理服务器。该指令可以在http,server和location块上进行配置

 

 

3.1.6proxy_set_header

语法结构:proxy_set_headerfield value

可以用于更改Nginx服务器接收到的客户端的请求头信息,然后将新的请求头信息发送给被代理服务器。默认情况下该指令设置为:

proxy_set_header Host $proxy_host;

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指令值和listner指令值一起填充到Host头域

proxy_set_header Connection close;

 

 

3.1.7proxy_set_body

语法结构:proxy_set_bodyvalue

可以用于更改Nginx服务器接受到的客户端请求体信息,然后将新的请求体信息发送给代理服务器。

 

 

3.1.8proxy_bind

语法结构:proxy_bindaddress

强制将与代理主机的连接绑定到指定的IP上。

 

 

3.1.9proxy_connect_timeout

语法结构:proxy_connect_timeouttime

用于配置Nginx服务器与后端被代理服务器尝试建立连接的超时时间,默认60s

 

 

3.1.10proxy_read_timeout

语法结构:proxy_read_timeouttime

用于配置Nginx服务器向后端服务器(组)发出read请求之后,等待响应超时时间

 

 

3.1.11proxy_send_timeout time

语法结构:proxy_send_timeouttime

用于配置Nginx服务器向后端服务器(组)发出write请求之后,等待响应超时时间

 

 

3.1.12proxy_http_version

语法结构:proxy_http_version1.0 | 1.1

用于指定Nginx服务器提供代理服务的HTTP协议版本

 

 

3.1.13proxy_method

语法结构:proxy_methodmethod

用于指定Nginx服务器请求被代理服务器时使用的请求方法,一般为POST或者GET,设置了该指令,客户端的请求方法将会被忽略

 

 

3.1.14proxy_ignore_client_abort

语法结构:proxy_ignore_client_aborton | off

用于配置客户端中断请求网络时,Nginx服务器是否是否中断对被代理的服务器的请求

 

 

3.1.15proxy_ignore_headers

语法结构:proxy_ignore_headers field ...

Nginx服务器接受到被代理服务器的响应数据后,不会处理在这里设置的头域。

 

 

3.1.16proxy_redirect

语法结构:proxy_redirect redirect replacement 或者 proxy_redirect default 或者 proxy_redirect off

redirect: 匹配Location头域中的字符串,支持变量使用和正则表达式

replacement:用于替换redirect变量内容的字符串,支持变量的使用

该指令用于修改被代理服务器返回的响应头中的Location头域和Refresh头域,与proxy_pass结合使用。比如Nginx服务器通过proxy_pass指令将客户端的请求地址重写为被代理服务器的地址,那么Nginx服务器返回给客户端响应头中Location头域显示的地址就该和客户端发起请求的地址相对应,而不是代理服务器直接返回的地址信息,否则就会出问题。

举个例子:

Location: http://localhost:8081/proxy/some/uri

该指令设置为

proxy_redirect http://localhost:8081/proxy/http://www.exmaple.com/

 

Nginx则会将 Location头域信息更改为http://www.example.com/some/uri/

 

语法结构:proxy_redirect default

代表使用location块的uri变量作为replacement,并使用proxy_pass变量作为redirect

举个例子,下面两段配置效果是等同的

配置1:

location /server/ {

      proxy_passhttp://192.168.3.100/source/;

      proxy_redirectdefault;

}

配置2:

location /server/ {

      proxy_passhttp://192.168.3.100/source/;

      proxy_redirecthttp://192.168.3.100/source/ /server/;

}

 

语法结构:proxy_redirect none

当前作用域下所有配置的proxy_redirect无效

 

 

3.1.17proxy_intercept_errors

语法结构:proxy_intercept_errors on | off

被代理服务器返回的HTTP状态码味400或者大于400的时候你,则Nginx服务器使用自己定义的错误页,如果是关闭的,则直接返回被代理服务器返回的HTTP状态给客户端

 

 

3.1.18proxy_headers_hash_max_size

语法结构:proxy_headers_hash_max_size size

用于存放HTTP报文头的哈希表的容量,Nginx服务器为了能够快速检索HTTP报文头各项信息,比如服务器名称,MIME类型,请求头名称等,使用哈希表存储这些信息。Nginx服务器申请存放HTTP报文头的空间时,通常以固定大小为单位申请,大小由proxy_headers_hash_bucket_size配置。

 

 

3.1.19proxy_headers_hash_bucket_size

语法结构:proxy_headers_hash_bucket_size size

用于配置Nginx服务器申请存放HTTP报文头哈希表容量的单位大小,默认64个字符。

 

 

3.1.20proxy_next_upstream

语法结构:proxy_next_upstream status ...

status: 服务器返回状态,可以一个或者多个,这些状态包括error,timeout,invliad_header,http_500|http_502|http_503|http_404,off(无法将请求发送给被代理服务器)

 

 

配置反向代理的时候,如果使用upstream指定了一组服务器作为被代理服务器,服务器组中个服务器访问规则默认遵循轮询的规则,同时可以使用该指令配置在发生异常的情况下,将请求顺次交由下一个组组内服务器处理。

 

 

3.1.21proxy_ssl_session_reuse

语法结构:proxy_ssl_session_reuse on | off

是否使用基于SSL安全协议的会话连接(http://)被代理的服务器

 

 

 

3.2proxy_buffer配置的指令

Nginx服务器会异步的从被代理服务器获取响应数据,然后传递给客户端。如果不弃用proxy buffer, Nginx服务器只能接收响应数据同步传递给客户端。如果启用了Proxy Buffer,Nginx从被代理服务器获取的数据,首先放在proxy buffer中,proxy buffer是有大小限制的,取决于proxy_buffer_size和proxy_buffers。如果发现buffer一次性不能放下所有的获取的数据,那么Nginx服务器会将部分接收到的数据临时存放在磁盘空间的临时文件中,临时文件路径取决于proxy_temp_path,临时文件大小取决于proxy_max_temp_file_size和

proxy_temp_file_write_size。

每一个proxy buffer装满数据以后,在从开始向客户端发送一直到proxy buffer数据全部传输完成,他都处于BUSY状态,期间对它进行其他操作都会失败,处于busy状态的proxy buffer总大小由proxy_busy_buffers_size指令限制,不能超过该指令设置的大小。

 

 

3.2.1proxy_buffering

语法结构:proxy_buffering on | off

启用或者关闭proxy_buffer

 

3.2.2proxy_buffers

语法结构: proxy_buffersnumber size

number: buffer的个数

size: 每一个buffer的大小,一般是设置为内存页大小,根据平台不同可能为4k或者8k

用于指定Nginx服务器接收被代理服务器响应数据的proxy buffer个数和每一个buffer的大小

 

 

3.2.3  proxy_buffer_size

语法结构:proxy_buffer_size size

用于设置从被代理服务器获取的第一部分响应数据的大小,该数据一般包含了HTTP响应头,Nginx服务器通过它来获取响应数据和被代理服务器的一些必要信息

 

3.2.4proxy_busy_buffers_size

语法结构:proxy_busy_buffers_size

用于限制同时处于BUSY状态的proxy buffer的总大小

 

 

3.2.5  proxy_temp_path

语法结构:proxy_temp_path path [level1 [level2 [level3]]]

path: 设置在磁盘上的临时文件存放路径

levelN: 设置path变量设置的路径下第几级hash目录中存放临时文件

比如:proxy_temp_path /opt/app/nginx/proxy_web/proxy_temp 1 2; 配置临时文件存放在/opt/app/nginx/proxy_web/proxy_temp路径下第二级目录中。

/opt/app/nginx/proxy_web/proxy_temp/1/10/0000110201

 

 

3.2.6proxy_max_temp_file_size

语法结构:proxy_max_temp_file_size size

指定所有临时文件总体积大小,存放在磁盘上的临时文件大小不能超过该配置值,避免了响应数据过大造成磁盘空间不足的问题。

 

 

3.2.7proxy_temp_file_write_size

语法结构:proxy_temp_file_write_size size

指定同时写入临时文件数据量总大小,合理设置可以避免磁盘I/O负载过重导致系统性能下降问题。

 

 

3.3proxy_cache配置的指令

Proxy Buffer实现了被代理服务器的响应数据的异步传输,Proxy Cache则主要实现了Nginx服务器对客户端的数据请求的快速响应。

Nginx服务器在接受到被代理服务器的响应数据之后,一方面通过Porxy Buffer机制将数据传递给客户端,另一方面Proxy Cache将这些数据缓存到本地硬盘上。当客户端下次要访问相同的数据的时候,Nginx直接从硬盘检索到对应的数据返回给用户,从而减少和被代理服务器之间的交互时间。

 

另外proxy cache依赖于proxy buffer,只有在proxy buffer开启的情况下,proxy cache才有用。

 

还有一种Proxy Store,也会对被代理服务器的数据进行本地缓存但是和Proxy Cache区别在于:不支持缓存过期更新,内存索引的建立等

 

 

3.3.1proxy_cache

语法结构: proxy_cachezone | off

zone: 设置的用于存放缓存索引的内存区域的名称

off: 关闭proxy_cache,默认的

配置一块公用的内存区域的名称,该区域可以存放缓存的索引数据。这些数据在Nginx服务器启动的时候由缓存索引重建进程负责建立,在Nginx整个运行过程中,由缓存管理进程负责定时检查过期数据,检索等管理工作。

 

 

3.3.2proxy_cache_bypass

语法结构:proxy_cache_bypass string.....

string:条件变量

配置Nginx服务器向客户端发送响应数据时候,不从缓存中获取的条件。

比如:proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment$http_authorization

 

 

3.3.3proxy_cache_key

语法结构:proxy_cache_key string

string: 关键字

设置Nginx服务器在内存为缓存数据建立索引时使用的关键字

 

 

3.3.4proxy_cache_lock

语法结构:proxy_cache_lock on | off

设置是否开启缓存的锁功能。在缓存中,某些数据项开一同时被多个请求返回的响应数据填充,开启该功能之后,Nginx服务器只能同时有一个请求填充缓存中的某一项数据

 

 

3.3.5proxy_cache_lock_timeout

语法结构: proxy_cache_lock_timeouttime

设置锁的超时时间

 

 

3.3.6proxy_cache_min_uses

语法结构:proxy_cache_min_uses number

设置客户端请求发送的次数,当客户端向被代理服务器发送相同请求达到该值后,Nginx才会对该请求的响应数据缓存,合理设置该值可以有效降低磁盘上缓存的数据量。

 

 

3.3.7proxy_cache_path

语法结构:proxy_cache_path path [levels = levels] key_zone = name:zone1 [inactive=time1][max_size = size2] [loader_files = number]

设置Nginx服务器存储缓存数据的路径以及和缓存索引相关的内容

 

 

3.3.8proxy_cache_use_stale

语法结构:proxy_cache_use_stale error|timeout|invalid_user|updating

|http_500|http_404...off

如果Nginx在访问被代理服务器过程中出现被代理服务器无法反问或者访问错误等现象,服务器可以使用历史缓存响应客户端的请求。

 

 

3.3.9proxy_cache_valid

语法结构:proxy_cache_valid [code ....] time

针对不同的HTTP响应状态设置不同的 缓存时间

 

 

3.3.10proxy_no_cache

语法结构:proxy_no_cache string ......

string: 可以是一个或者多个变量

配置在什么情况下不使用cache

 

 

3.3.11proxy_store

语法结构: proxy_storeon | off | string

on|off : 是否开启proxy store

string: 自定义缓存文件的存放路径

 

 

3.3.12proxy_store_access

语法结构:proxy_store_access users:permissions ....

users: 可以设置user,group,或者all

permissions: 设置权限

设置用户或者用户组对Proxy Store缓存的数据的访问权限

 

location /images/ {

      root/data/www;

      error_page404 = /fetch$uri;

}

 

location /fetch/ {

      proxy_passhttp://backend

      proxy_storeon;

      proxy_store_accessuser:rw group:rw all:r;

      root/data/www

}

 

四 Nginx服务器的负载均衡

Nginx服务器的反向代理的重要作用就是实现负载均衡。负载均衡就是指根据一定的分配策略,将网络负载均衡分摊到网络集群的各个节点上。

负载均衡算法一般分为2大类:

# 静态负载均衡算法:轮询算法,基于比率的加权轮询算法以及基于优先级的加权轮询算法

# 动态负载均衡算法:基于任务量的最少连接优先算法,基于性能的最快响应优先算法,预测算法以及动态性能分配算法等

 

4.1 所有请求进行一般轮询负载均衡配置

默认weight=1

upstream backend {

      server192.168.3.2:80;

      server192.168.3.3:80;

      server192.168.3.4:80;

}

 

server {

      listen80;

      server_namewww.example.com;

      indexindex.html index.htm;

      location/ {

           proxy_passhttp://backend;

           proxy_set_headerHost $host;

           ......

      }

}

 

4.2 所有请求进行加权轮询负载均衡配置

upstream backend {

      server192.168.3.2:80 weight=5;

      server192.168.3.3:80 weight=2;

      server192.168.3.4:80;

}

server {

      listen80;

      server_namewww.example.com;

      indexindex.html index.htm;

      location/ {

           proxy_passhttp://backend;

           proxy_set_headerHost $host;

           ......

      }

}

 

4.3 对特定资源实现负载均衡

 

upstream videobackend {

      serverhttp://192.168.3.100;

      serverhttp://192.168.3.101;

      serverhttp://192.168.3.102;

}

upstream filebackend {

      serverhttp://192.168.3.90;

      serverhttp://192.168.3.91;

      serverhttp://192.168.3.92;

}

server {

      listen80;

      server_namewww.example.com;

      location/video/ {

           proxy_passvideobackend;

           proxy_set_headerHost $host;

           ......

      }

      location/file/ {

           proxy_passvideobackend;

           proxy_set_headerHost $host;

           proxy_set_headerX-Real-IP $remote_addr;

           proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;

      }

}

 

4.4 对不同域名实现负载均衡

upstream bbsbackend {

      serverhttp://192.168.3.100 weight 2;

      serverhttp://192.168.3.101 weight 2;

      serverhttp://192.168.3.102;

}

upstream homebackend {

      serverhttp://192.168.3.90;

      serverhttp://192.168.3.91;

      server http://192.168.3.92;

}

 

server {

      listem80;

      server_namehome.local.com

      indexindex.html index.htm;

      location/ {

           proxy_passhomebackend;

           proxy_set_headersHost $host;

      }

}

 

server {

      listem81;

      server_namebbs.local.com

      indexindex.html index.htm;

      location/ {

           proxy_passbbsbackend;

           proxy_set_headersHost $host;

      }

}

 

 

4.5 带有URL重写的负载均衡

upstream backend {

      server192.168.3.2:80;

      server192.168.3.3:80;

      server192.168.3.4:80;

}

 

server {

      listen80;

      server_namewww.example.com;

      index index.htmlindex.htm;

      location/file/ {

           rewrite^(/file/.*)/media/(.*)\.*$ $1/mp3/$2.mp3 last;

      }

 

      location/ {

           proxy_passhttp://backend;

           proxy_set_headersHost $host;

           ......

      }

}