2020-03-29 Nginx反向代理与动静分离集群架构应用实践(三)

1. Nginx负载均衡核心组件介绍

1.1 Nginx upstream模块

1.1.1 upstream模块介绍

Nginx负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等,新版Nginx软件支持的方式有所增加。这里主要针对proxy_pass代理方式进行讲解。
ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应upstream组上,具体写法为“proxy_pass http://www_pools”,其中www_pools就是一个upstream节点服务器组的名字。ngx_http_upstream_module模块官方地址:http://nginx.org/en/docs/http/ngx_http_upstream_module.html

1.1.2 upstream模块语法

范例1:基本的upstream配置案例

upstream www_pools {    ---upstream关键字必须要有,www_pools为一个upstream集群组名字,可以自己起名
  server 192.168.9.7:80 weight=5;
  server 192.168.9.9:80 weight=10;
  server 192.168.9.10:80 weight=15;
---server关键字时固定的,后面可以接域名(门户会员)或IP。如果不指定端口,默认是80端口。weight代表权重,数值越大被分配的请求越多,注意结尾有分号
}

范例2:较完整的upstream配置案例

upstream blog_pools {
  server 192.168.9.7;    ---这一行标签和下一行是等价的
  server 192.168.9.9:80 weight=1 max_fails=1 fail_timeout=10s;    ---这一行标签是和上一行是等价的,此行多余的部分就是默认配置,不写也可以
  server 192.168.9.10:80 weight=1 max_fails=2 fail_timeout=20s backup;
  server 192.168.9.11:80 weight=1 max_fails=2 fail_timeout=20s backup;
}

范例3:使用域名及socket的upstream配置案例

upstream backend {
  server backend1.example.com weight=5;
  server backend2.example.com:8080;    ---域名加端口。转发到后端的指定端口上
  server unix:/tmp/backend3;    ---指定socket文件
# 提示:server后面如果接域名,需要内网有DNS服务器或者在负载均衡器的hosts文件做域名解析
  server backup1.example.com:8080  backup;
# 结尾backup表示备份服务器,其他指定服务器都不可访问时启用,backup的用法和Haproxy中用法一样
  server backup2.example.com:8080  backup;
}

如果是两台Web服务器做高可用,常规方案就需要Keepalived配合,那么这里使用Nginx的backup参数通过负载均衡功能就可以实现Web服务器集群了,对于企业应用来说,能做集群就不做高可用。

1.1.3 upstream模块相关说明

upstream模块的内容应放于nginx.conf配置的http{}标签内,其默认调度节点算法是wrr(权重轮询,weighted round-robin)。下表所示为upstream模块内部server标签部分参数说明。

upstream模块内部server标签参数说明1
upstream模块内部server标签参数说明2
upstream模块内部server标签参数说明3

来看个示例:

upstream backend {
  server backend1.example.com  weight=5;    ---如果就是单个Server,没必要设置权重
  server 127.0.0.1:8000  max_fails=5 fail_timeout=10s;
---当检测次数等于5的时候,5次连续检测失败后,间隔10s再重新检测,这个参数和proxy/fastcgi/memcached_next_upstream相关
  server unix:/tmp/backend3;
  server backup1.example.com:8080 backup;    ---热备机器设置
}

需要特别说明的是,如果是Nginx代理cache服务,可能需要使用hash算法,此时若宕机,可通过设置down参数确保客户端用户按照当前的hash算法访问,这点很重要。示例配置如下:

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

下面是Haproxy负载均衡器server标签的配置示例。

# 开启对后端服务器的健康检测,通过GET /test/index.php来判断后端服务器的健康情况。
  server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
  server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
  server php_server_b 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup

上述命令的说明如下:

  • weight:调节服务器的请求分配权重。
  • check:开启对该服务器健康检查。
  • inter:设置连续两次的健康检查间隔时间,单位毫秒,默认值为2000。
  • rise:指定多少次连续成功的健康检查后,即可认定该服务器处于可用状态。
  • fall:指定多少次不成功的健康检查后,即认为服务器为宕机状态,默认值为3。
  • maxconn:指定可并发发送到该服务器的最大并发连接数。

1.1.4 upstream模块调度算法

调度算法一般分为以下两类:
第一类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器情况。例如:rr、wrr、ip_hash都属于静态调度算法。
第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求。例如:连接数少的优先获得请求,响应时间短的优先获得请求,least_conn、fair等都属于动态调度算法。
下面介绍一下常见的调度算法。
(1)rr轮询(默认调度算法,静态调度算法)
按客户端请求顺序把客户端的请求注逐一分配到不同的后端节点服务器,这相当于LVS中的rr算法,如果后端节点服务器宕机(默认情况下Nginx只检测80端口),宕机的服务器会被自动从节点服务器池中剔除,以使客户端的用户访问不受影响。新的请求会分配给正常的服务器。
(2)wrr(权重轮询,静态调度算法)
在rr轮询算法的基础上加上权重,即为权重轮询算法,当使用该算法时,权重和用户访问成正比,权重值越大,都转发的请求也就越多。可以根据服务器的配置和性能指定权重值大小,从而有效解决新旧服务器性能不均带来的请求分配问题。
举个例子:
后端服务器192.168.1.2的配置为:E5520*2 CPU,8GB内存。
后端服务器192.168.1.3的配置为:Xeon(TM)2.80GHz * 2,4GB内存。
假设希望当有30个请求到达前端时,其中20个请求交给192.168.1.3处理,剩余10个请求交给192.168.1.2处理,可做如下配置:

upstream oldboy_lb {
  server 192.168.1.2 weight=1;
  server 192.168.1.3 weight=2;
}

(3)ip_hash(静态调度算法)
每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以,这些客户端都会被分配到同一节点服务器,从而导致请求分配不均。LVS负载均衡的-p参数、Keepalived配置里的persistence_timeout 50参数都类似这个Nginx里的ip_hash参数,其功能均为解决动态网页的session共享问题。
同样来看一个示例:

upstream oldboy_lb {
  ip_hash;
  server 192.168.1.2:80;
  server 192.168.1.3:8080;
}
upstream backend {
  ip_hash;
  server backend1.example.com;
  server backend2.example.com;
  server backend3.example.com down;
  server backend4.example.com;
}

注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能写入weight和backup两个参数,即使有也不会生效。
(4)fair(动态调度算法)
此算法会根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配。这是更加智能的调度算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair调度算法的,如果需要使用这种调度算法,必须下载Nginx的相关模块upstream_fair。
示例如下:

upstream oldboy_lb {
  fair;
  server 192.168.1.2;
  server 192.168.1.3;
}

(5)least_conn(动态调度算法)
least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发给哪个节点。
(6)url_hash算法(动态调度算法)
和ip_hash类似,这里是根据访问URL的hash结果来分配请求的,让每个URL定向到同一个后端服务器,后端服务器为缓存服务器时效果显著。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method使用的是hash算法。
url_hash按访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率命中率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx的hash模块软件包。
url_hash(Web缓存节点)和ip_hash(会话保持)类似。示例配置如下:

upstream oldboy_lb {
  server squid1:3128;
  server squid2:3128;
  hash $request_uri;
  hash_method crc32;
}

(7)一致性hash算法(动态调度算法)
一致性hash算法一般用于代理后端业务为缓存服务(Squid、Memcached)的场景,通过将用户请求的URI或者指定字符串进行计算,然后调度到后端的服务器上,此后任何用户查找同一个URI或者指定字符串都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的,一致性hash算法可以使后端某个或几个节点宕机后缓存的数据动荡的最小。

http {
  upstream test {
    consistent_hash $request_uri;
    server 127.0.0.1:9001 id=1001 weight=3;
    server 127.0.0.1:9002 id=1002 weight=10;
    server 127.0.0.1:9003 id=1003 weight=20;
  }
}

虽然Nginx本身不支持一致性hash算法,但Nginx的分支tengine支持。

1.2 http_proxy_module模块

1.2.1 proxy_pass指令介绍

proxy_pass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器,在实际的反向代理工作中,会通过location功能匹配指定的URI,然后把接收到的符合匹配URI的请求通过proxy_pass抛给定义好的upstream节点池。
下面是proxy_pass的使用案例。
1)将匹配URI为name的请求抛给http://127.0.0.1/remote/

location /name/ {
  proxy_pass http://127.0.0.1/remote/;
}

2)将匹配URI为some/path的请求抛给http://127.0.0.1。

location /some/path/ {
  proxy_pass http://127.0.0.1;
}

3)将匹配URI为name的请求应用指定的rewrite规则,然后抛给http://127.0.0.1。

location /name/ {
  rewrite  /name/([^/]+) /users?name=$1 break;
  proxy_pass http://127.0.0.1;
}
1.2.2 http_proxy_module相关参数

Nginx反向代理功能主要是通过http proxy模块来实现的。默认在安装Nginx时已经安装了http proxy模块,因此可直接使用。下面详细解释模块中每个选项代表的含义。

http proxy模块相关参数
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,192评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,858评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,517评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,148评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,162评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,905评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,537评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,439评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,956评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,083评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,218评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,899评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,565评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,093评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,201评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,539评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,215评论 2 358

推荐阅读更多精彩内容