负载均衡可以分为硬件负载均衡和软件负载均衡,前者一样平常是专用的软件和硬件相结合的设备,设备商会供应完全成熟的办理方案,常日也会更加昂贵。
软件的繁芜均衡以Nginx霸占绝大多数。

一、基本简介

负载均衡涉及到以下的根本知识。

(1) 负载均衡算法

phpcurl负载均衡详解 nginx负载平衡道理 Python

a. Round Robin: 对所有的backend轮训发送要求,算是最大略的办法了,也是默认的分配办法;

b. Least Connections(least_conn): 跟踪和backend当前的生动连接数目,最少的连接数目解释这个backend负载最轻,将要求分配给他,这种办法会考虑到配置中给每个upstream分配的weight权重信息;

c. Least Time(least_time): 要求会分配给相应最快和生动连接数最少的backend;

d. IP Hash(ip_hash): 对要求来源IP地址打算hash值,IPv4会考虑前3个octet,IPv6会考虑所有的地址位,然后根据得到的hash值通过某种映射分配到backend;

e. Generic Hash(hash): 以用户自定义资源(比如URL)的办法打算hash值完身分派,其可选consistent关键字支持同等性hash特性;

(2) 会话同等性

用户(浏览器)在和做事端交互的时候,常日会在本地保存一些信息,而全体过程叫做一个会话(Session)并用唯一的Session ID进行标识。
会话的观点不仅用于购物车这种常见情形,由于HTTP协议是无状态的,以是任何必要逻辑高下文的环境都必须利用会话机制,此外HTTP客户端也会额外缓存一些数据在本地,这样就可以减少要求提高性能了。
如果负载均衡可能将这个会话的要求分配到不同的后台做事端上,这肯定是不得当的,必须通过多个backend共享这些数据,效率肯定会很低下,最大略的情形是担保会话同等性——相同的会话每次要求都会被分配到同一个backend上去。

(3) 后台做事真个动态配置

出问题的backend要能被及时探测并剔除出分配群,而当业务增长的时候可以灵巧的添加backend数目。
此外当前风靡的Elastic Compute云打算做事,做事商也应该根据当前负载自动添加和减少backend主机。

(4) 基于DNS的负载均衡

常日当代的网络做事者一个域名会相干到多个主机,在进行DNS查询的时候,默认情形下DNS做事器会以round-robin形式以不同的顺序返回IP地址列表,因此天然将客户要求分配到不同的主机上去。
不过这种办法含有固有的毛病:DNS不会检讨主机和IP地址的可访问性,以是分配给客户真个IP不确保是可用的(Google 404);DNS的解析结果会在客户端、多个中间DNS做事器不断的缓存,以是backend的分配不会那么的空想。

二、Nginx中的负载均衡

Nginx中的负载均衡配置在 手册 中描述的极为细致,此处就不流水帐了。
对付常用的HTTP负载均衡,紧张先定义一个upstream作为backend group,然后通过proxy_pass/fastcgi_pass等办法进行转发操作,个中fastcgi_pass险些算是Nginx+PHP站点的标配了。

2.1 会话同等性

Nginx中的会话同等性是通过sticky开启的,会话同等性和之前的负载均衡算法之间并不冲突,只是须要在第一次分配之后,该会话的所有要求都分配到那个相同的backend上面。
目前支持三种模式的会话同等性:

(1). Cookie Insertion

在backend第一次response之后,会在其头部添加一个session cookie,之后客户端接下来的要求都会带有这个cookie值,Nginx可以根据这个cookie判断须要转发给哪个backend了。

sticky cookie srv_id expires=1h domain=.example.com path=/;

上面的srv_id代表了cookie的名字,而后面的参数expires、domain、path都是可选的。

(2). Sticky Routes

也是在backend第一次response之后,会产生一个route信息,route信息常日会从cookie/URI信息中提取。

sticky route $route_cookie $route_uri;

这样Nginx会按照顺序搜索$route_cookie、$route_uri参数并选择第一个非空的参数用作route,而如果所有的参数都是空的,就利用上面默认的负载均衡算法决定要求分发给哪个backend。

(3). Learn

较为的繁芜也较为的智能,Nginx会自动监测request和response中的session信息,而且常日须要回话同等性的要求、应答中都会带有session信息,这和第一种办法比较是不用增加cookie,而是动态学习已有的session。

这种办法须要利用到zone构造,在Nginx中zone都是共享内存,可以在多个worker process中共享数据用的。
(不过其他的会话同等性怎么没用到共享内存区域呢?)

sticky learn create=$upstream_cookie_examplecookie lookup=$cookie_examplecookie zone=client_sessions:1m timeout=1h;

2.2 Session Draining

紧张是有须要关闭某些backend以便掩护或者升级,这些关键性的做事都讲求gracefully处理的:便是新的要求不会发送到这个backend上面,而之前分配到这个backend的会话的后续要求还会连续发送给他,直到这个会话终极完成。

让某个backend进入draining的状态,既可以直接修正配置文件,然后按照之前的办法通过向master process发送旗子暗记重新加载配置,也可以采取Nginx的on-the-fly配置办法。

$ curl http://localhost/upstream_conf?upstream=backend$ curl http://localhost/upstream_conf?upstream=backend\&id=1\&drain=1

通过上面的办法,先列出各个bacnkend的ID号,然后drain指定ID的backend。
通过在线不雅观测backend的所有session都完成后,该backend就可以下线了。

2.3 backend康健监测

backend出错会涉及到两个参数,max_fails=1 fail_timeout=10s;意味着只要Nginx向backend发送一个要求失落败或者没有收到一个相应,就认为该backend在接下来的10s是不可用的状态。

通过周期性地向backend发送分外的要求,并期盼收到分外的相应,可以用以确认backend是康健可用的状态。
通过health_check可以做出这个配置。

match server_ok { status 200-399; header Content-Type = text/html; body !~ \"大众maintenance mode\"大众;}server { location / { proxy_pass http://backend; health_check interval=10 fails=3 passes=2 match=server_ok; }}

上面的health_check是必须的,后面的参数都是可选的。
尤其是后面的match参数,可以自定义做事器康健的条件,包括返回状态码、头部信息、返回body等,这些条件是&&与关系。
默认情形下Nginx会相隔interval的间隔向backend group发送一个”/“的要求,如果超时或者返回非2xx/3xx的相应码,则认为对应的backend是unhealthy的,那么Nginx会停滞向其发送request直到下次改backend再次通过检讨。

在利用了health)check功能的时候,一样平常都须要在backend group开辟一个zone,在共享backend group配置的同时,所有backend的状态就可以在所有的worker process所共享了,否则每个worker process独立保存自己的状态检讨计数和结果,两种情形会有很大的差异哦。

2.4 通过DNS设置HTTP负载均衡

Nginx的backend group中的主机可以配置成域名的形式,如果在域名的后面添加resolve参数,那么Nginx会周期性的解析这个域名,当域名解析的结果发生变革的时候会自动生效而不用重启。

http { resolver 10.0.0.1 valid=300s ipv6=off; resolver_timeout 10s; server { location / { proxy_pass http://backend; } } upstream backend { zone backend 32k; least_conn; ... server backend1.example.com resolve; server backend2.example.com resolve; }}

如果域名解析的结果含有多个IP地址,这些IP地址都会保存到配置文件中去,并且这些IP都参与到自动负载均衡。

2.5 TCP/UDP流量的负载均衡

除了专长的HTTP负载均衡,Nginx还支持TCP和UDP流量的负载均衡,适用于LDAP/MySQL/RTMP和DNS/syslog/RADIUS各种运用处景。
这类情形的负载均衡利用stream来配置,Nginx编译的时候须要支持–with-stream选项。
查看 手册 ,其配置事理和参数和HTTP负载均衡差不多。

由于TCP、UDP的负载均衡都是针对通用程序的,以是之前HTTP协议支持的match条件(status、header、body)是没法利用的。
TCP和UDP的程序可以根据特定的程序,采取send、expect的办法来进行动态康健检测。

match http { send \"大众GET / HTTP/1.0\r\nHost: localhost\r\n\r\n\"大众; expect ~ \"大众200 OK\"大众;}

2.6 其他特性

slow_start=30s:防止新添加/规复的主机被溘然增加的要求所压垮,通过这个参数可以让该主机的weight从0开始逐步增加到设定值,让其负载有一个缓慢增加的过程。

max_conns=30:可以设置backend的最大连接数目,当超过这个数目的时候会被放到queue行列步队中,同时行列步队的大小和超时参数也可以设置,当行列步队中的要求数大于设定值,或者超过了timeout但是backend还不能处理要求,则客户端将会收到一个缺点返回。
常日来说这还是一个比较主要的参数,由于Nginx作为反向代理的时候,常日便是用于抗住并发量的,如果给backend过多的并发要求,很可能会占用后端过多的资源(比如线程、进程非事宜驱动),终极反而会影响backend的处理能力。

后面会分享更多关于devops方面的内容,感兴趣的朋友可以关注下!