@cdmonkey
2016-12-13T22:32:48.000000Z
字数 8821
阅读 1362
Nginx
http://waringid.blog.51cto.com/65148/1606122
http://freeloda.blog.51cto.com/2033581/1288553
Nginx实现反向代理其实就是使用了“upstream”模块。
[root@LB-N1 ~]# mkdir /application/nginx/conf/extra
[root@LB-N1 ~]# cd /application/nginx/conf/extra/
[root@LB-N1 extra]# vim upstream.conf
#添加下面的模块内容:
upstream backend {
server 172.16.1.10:80 weught=1 max_fails=3 fail_timeout=30s;
server 172.16.1.12:80 weught=1 max_fails=3 fail_timeout=30s;
}
#反向代理模块中也要创建与后端Web服务器对应的虚拟主机,这些虚拟主机首先截获请求,然后抛给后端的服务器。
server {
listen 80;
server_name bbs.etiantian.org;
index index.php index.html index.htm;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /data0/www/cms;
}
}
--------------------
#当然,还要在主配置文件中加载该反向代理配置文件:
[root@LB-N1 ~]# vim /application/nginx/conf/nginx.conf
include extra/upstream.conf;
#检查配置文件语法并重新加载:
[root@LB-N1 ~]# /application/nginx/sbin/nginx -t
nginx: the configuration file /application/nginx1.6.2/conf/nginx.conf syntax is ok
nginx: configuration file /application/nginx1.6.2/conf/nginx.conf test is successful
[root@LB-N1 ~]# /application/nginx/sbin/nginx -s reload
至此,如果将域名解析到反向代理服务器LB-N1的IP地址上,就可以通过反向代理服务器访问Web站点了,默认情况下每刷新一次页面会切换到另一台Web服务器上,即默认采用轮询的调度算法。
我们可以使用Keepalived实现两台代理服务器的高可用。
[root@LB-N1 keepalived-1.1.19]# ./configure
Keepalived configuration
------------------------
...
Use IPVS Framework : No
IPVS sync daemon support : No
Use VRRP Framework : Yes
Use Debug flags : No
[root@LB-N1 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
brucemx@qq.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 10.0.0.1
smtp_connect_timeout 30
router_id LB-N1
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 10
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.1.7/24
}
}
如果网站的PV数低于1000~2000万,且业务相对单一的时候,可以直接选用Nginx做反向代理负载均衡,它的缺点就是来自客户端的访问请求来去都要经过代理服务器,但如果是中小型网站是没有问题的,Nginx代理服务器可以工作的很好。如果要增加Nginx代理服务器的数量,那么需要在前面做LVS,而将Nginx代理服务器作为RS节点,这样的话最多可以有128台Nginx代理服务器。
Nginx反向代理负载均衡与LVS的区别。
为什么会分别需要Nginx反向代理服务器和LVS?LVS属于四层(L4)负载均衡,而Nginx属于七层(L7)负载均衡,在实际的生产环境中,往往需要把四层与七层的负载均衡业务进行分离
大并发,简单的转发(基于四层的转发):LVS
大并发,功能要求比较复杂(依据URL进行转发):LVS+Nginx
业务量不大,同时功能要求丰富:Nginx/HAProxy
大公司,根据业务,基本上三个场景都会用到。
Nginx的负载均衡功能依赖于ngx_http_upstream_module
模块,所支持的代理方式有:
proxy_pass:用于反向代理。
fastcgi_pass:用于和动态程序(例如PHP)进行交互。
memcached_pass
官方地址:http://nginx.org/en/docs/http/ngx_http_upstream_module.html
其实叫做反向代理更为确切,而负载均衡只是它的反向代理功能上的一部分。
首先,upstream模块要放置于http模块下面,其默认算法为权重轮询(wrr,weighted round-robin)。
参数 | 说明 |
---|---|
server |
固定的关键字,后面接域名(大网站可能会用域名)或IP,如果不接端口号,则默认为80端口。 |
weight=1 |
设置服务器权重,默认为1。权重越大,分配的请求越多。 |
max_fails=3 |
在一定时间内(这个时间在fail_timeout 参数中设置)检查这个服务器是否可用时产生的最大失败次数,默认为1,将其设置为0可以关闭检查。 |
fail_timeout=10s |
在这个时间内产生了max_fails 所设置大小的失败尝试连接请求后这个服务器可能不可用,同样它指定了服务器不可用的时间(在下一次尝试连接请求发起之前),默认为10秒。 |
backup |
热备功能,如果所有的非备份服务器都宕机或繁忙,则该服务器开始工作。 |
down |
标记服务器处于离线状态,通常和ip_hash 一起使用。 |
参数 | 说明 |
---|---|
proxy_next_upstream |
确定在何种情况下请求将转发到下一个服务器。转发请求只发生在没有数据传递到客户端的过程中。 |
proxy_connect_timeout |
后端服务器连接的超时时间_发起握手等候响应超时时间。 |
proxy_read_timeout |
连接成功后,等候后端服务器响应时间,其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)。 |
proxy_send_timeout |
后端服务器数据回传时间,就是在规定时间之内后端服务器必须传完所有的数据。 |
根据上面的解释,max_fails
默认为1,fail_timeout
默 认为10秒,也就是说,默认情况下后端服务器在10秒钟之内可以容许有一次的失败,如果超过1次则视为该服务器有问题,将该服务器标记为不可用。等待10秒后再将检查请求发给该服务器,以此类推进行后端服务器的健康检查。但是如果我们将max_fails
设置为0,则代表不对后端的服务器进行健康检查,这样的话fail_timeout
参数也就没什么意义了。
另外,对于Nginx代理缓存服务时,可能需要使用hash算法,此时,如果节点服务器出现宕机,可以通过设置down
参数确保客户端用户按照当前的hash算法进行访问,这点很重要。
对于算法的设置需要在upstream
模块中进行。
2.1 轮询(round-robin)算法
该算法是Nginx反向代理的默认算法。按照客户端请求的顺序把这些请求逐一分配到不同的后端节点服务器,这相当于LVS中的“rr”算法。如果节点服务器出现宕机(如果后端报502、503、403、404等错误,还是会直接返回给用户),宕机的服务器会被自动剔除,使后续的用户访问不受影响,而将请求分配给工作正常的服务器。
2.2 权重(weight)
在轮询算法的基础上加上权重,权重越大,被分配的请求也就越多。可以根据服务器的实际配置和性能指定权重值的大小,这样可以有效解决新旧服务器性能不均的问题。
2.3 IP Hash
每个请求按照访问的IP的Hsah结果分配,当新的请求到达时,先将其客户端IP通过哈希算法计算出一个值,在随后的请求中,IP的哈希值只要相同,就会被分配到同一台服务器。该调度算法可以解决动态网页的Session共享问题,但有时也会导致请求分配不均的现象。
注意:如果采用IP Hash算法,那么后端的节点服务器的配置参数不能出现
weight
和backup
。
2.4 Fire(第三方)
按照后端服务器的响应时间来分配请求,响应时间短的优先分配。该算法比上面的算法更加智能的处理负载均衡。该算法可以根据页面大小和加载时间长短智能地进行负载均衡。Nginx默认不支持这种算法,如果要使用,就需要下载upstream_fair
模块。
2.5 URL Hash(第三方)
按访问请求的URL地址的哈希结果来分配请求,使每个URL定向到同一个后端服务器,后端服务器为缓存时比较有效。
顾名思义,location,位置、定位的意思。它的作用是将对应服务器接收到的客户端请求,换句话说,将会对不同的URL请求做不同的处理——将URL请求引导到相应的位置上去。一般来说,一个请求的URL过来,Nginx会将它解析到某一个location来处理。这个解析的过程基本可以分为字符串匹配和正则表达式匹配这两种。
Nginx中的location
指令是用来对URL进行匹配的,可以通过字符串或正则表达式进行匹配。如果是正则表达式,则必须指定前缀。它会根据URI来应用不同的配置,这个指令允许根据不同的URI来应用不同的URL配置。
URI是从虚拟根路径开始的,而URL指的是整个链接。
官方文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#location
Sets configuration depending on a request URI.
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location
location首先对字符串进行匹配查询,最确切的匹配将被使用。然后,正则表达式的匹配查询开始,匹配到第一个结果后会停止搜索,如果没有找到正则表达式,将用字符串的搜索结果,如果字符串和正则都匹配,那么正则的优先级较高。
字符串精确匹配到一个带“=”号前缀的location,则停止,且使用这个location的配置。这表示完全匹配指定的匹配模式,且这里的匹配模式被限制成简单的字符串,也就是说这里不能使用正则表达式。例如:
server {
server_name website.com;
location = /abcd {
[…]
}
}
----------------------
http://website.com/abcd #正好完全匹配。
http://website.com/ABCD #如果运行Nginx服务的系统本身对大小写不敏感,比如视窗,那么也匹配。
http://website.com/abcd?param1¶m2 #忽略后面的查询串参数,可以匹配。
http://website.com/abcd/ #不匹配,因为末尾存在反斜杠,Nginx不认为这种情况是完全匹配。
http://website.com/abcde #不匹配,因为不是完全匹配。
可以不写location modifier,Nginx仍然能去匹配匹配模式。这种情况下,匹配那些以指定的匹配模式开头的URL,注意这里的URL只能是普通字符串,不能使用正则表达式。例如:
server {
server_name website.com;
location /abcd {
[…]
}
}
----------------------
http://website.com/abcd #正好完全匹配。
http://website.com/ABCD #如果运行Nginx服务的系统本身对大小写不敏感,那么也匹配。
http://website.com/abcd?param1¶m2 #忽略后面的查询串参数,可以匹配。
http://website.com/abcd/ #末尾存在反斜杠,也属于匹配范围内。
http://website.com/abcde #仍然匹配,因为URI是以匹配模式开头的。
这个location修饰符对大小写敏感,且匹配模式必须是正则表达式。例如:
server {
server_name website.com;
location ~ ^/abcd$ {
[…]
}
}
----------------------
http://website.com/abcd #完全匹配。
http://website.com/ABCD #不匹配,~对大小写是敏感的。
http://website.com/abcd?param1¶m2 #忽略后面的查询串参数,可以匹配。
http://website.com/abcd/ #不匹配,因为末尾存在反斜杠,并不匹配正则表达式^/abcd$。
http://website.com/abcde #不匹配正则表达式^/abcd$。
#注意:对于一些对大小写不敏感的操作系统,~和~*都是不起作用的,这主要是操作系统的原因。
与“~”类似,但这个location modifier不区分大小写,匹配模式必须是正则表达式。例如:
server {
server_name website.com;
location ~* ^/abcd$ {
[…]
}
}
----------------------
http://website.com/abcd #完全匹配
http://website.com/ABCD #匹配,这就是它不区分大小写的特性。
http://website.com/abcd?param1¶m2 #忽略查询串参数。
http://website.com/abcd/ #不匹配,因为末尾存在反斜杠,并不匹配正则表达式^/abcd$。
http://website.com/abcde #不匹配正则表达式^/abcd$。
匹配情况类似(None)的情况,只匹配字符串,而不匹配正则表达式,以指定匹配模式开头的URL被匹配,不同的是,一旦匹配成功,那么Nginx就停止去寻找其他的location块进行匹配了(与location匹配顺序有关)。
location 的匹配顺序是“先匹配普通,再匹配正则”。
正则location匹配让步普通location的严格精确匹配结果;但覆盖普通location的最大前缀匹配结果。
于决定哪个location
来匹配一个特定的查询时:
普通location
(匹配字符串)的匹配规则是“最大前缀”,因而普通的匹配与location
编辑顺序无关。但是正则的匹配规则是“顺序匹配”,且只要匹配到第一个就停止后面的匹配。
Nginx的代理功能是通过http_proxy_module
模块来实现的。该模块在Nginx安装时默认已被安装,因此可以直接使用。
常用参数:
参数 | 说明 |
---|---|
proxy_set_header |
设置由后端的服务器获取用户的主机名或者真实IP地址,以及代理者的真实IP地址。 |
proxy_connect_timeout |
表示与后端服务器连接的超时时间,即发起握手等候响应的超时时间。 |
proxy_send_timeout |
表示后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则Nginx将断开这个连接。 |
proxy_buffer_size |
设置缓冲区的大小。默认该缓冲区的大小等于指令proxy_buffers 设置的大小。 |
proxy_buffers |
设置缓冲区的数量和大小。Nginx从代理的后端服务器获取的响应信息,会放置到缓冲区中。 |
官方文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html
该指令属于http_proxy_module
模块,此模块可以将请求转发到另一台服务器。
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
常用参数:
参数 | 说明 |
---|---|
proxy_pass http://backend |
用于指定后端反向代理的服务器池。 |
proxy_set_header Host $host |
当后端Web服务器上配置有多个虚拟主机时,需要用该Header来区分反向代理哪个主机名。 |
proxy_set_header X-Forwarded-For $remote_addr |
通过设置该头信息,可以把连接它的客户端的IP加到这个头信息里,这样就能保证网站的web服务器能获取到真实IP。 |
后端真实服务器记录客户端的IP地址:
#nginx.conf:
log_format commonlog '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#httpd.conf:
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
我们可以依据浏览器的类型(user_agent)对业务进行分离。
server {
listen 80;
server_name blog.etiantian.org;
location / {
if ($http_user_agent ~* "MSIE") {
proxy_pass http://dynamic_pools;
}
if ($http_user_agent ~* "Firefox") {
proxy_pass http://static_pools;
}
proxy_pass http://dynamic_pools;
include extra/proxy.conf;
}
access_log off;
}
server {
listen 80;
server_name blog.etiantian.org;
location / {
if ($http_user_agent ~* "android") {
proxy_pass http://dynamic_pools;
}
if ($http_user_agent ~* "iphone") {
proxy_pass http://static_pools;
}
proxy_pass http://dynamic_pools;
include extra/proxy.conf;
}
access_log off;
}
#允许客户端请求的最大的单个文件字节数
client_max_body_size 10m;
#缓冲区代理缓冲用户端请求的最大字节数,可以理解为先保存到本地再传给用户
client_body_buffer_size 128k;
#跟后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_connect_timeout 600;
#连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理
proxy_read_timeout 600;
#后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
proxy_send_timeout 600;
#代理请求缓存区_这个缓存区间会保存用户的头信息以供Nginx进行规则处理_一般只要能保存下头信息即可
proxy_buffer_size 8k;
#同上 告诉Nginx保存单个用的几个Buffer 最大用多大空间
proxy_buffers 4 32k;
#如果系统很忙的时候可以申请更大的proxy_buffers 官方推荐*2
proxy_busy_buffers_size 64k;
#proxy缓存临时文件的大小
proxy_temp_file_write_size 64k;