1.什么是负载均衡
负载均衡(Load Balance)是高可用架构的一个关键组件,主要是为了提高系统的性能和可用性。既然提到均衡,那么它的服务对象就是多服务的场景。
2.为什么要有负载均衡
小洛新开了一家门店,每天从头忙到晚,本着诚实守信的原则,生意是越做越好,开分店是势在必行。可是问题来了,怎么把用户分到不同的店面去呢?负载均衡的应用就在这里。
3.负载均衡的实现方式
负载均衡的实现方式大致分为三种:硬件负载均衡,软件负载均衡,DNS负载均衡。硬件负载均衡这里先不介绍,主要记录下软件负载和DNS负载。
3.1 DNS负载均衡
现在分店已经开起来了,但店的名字还没变(一改名字用户流失了),用户在网上搜索我们的店铺,我们应该告诉他去哪家店呢?首先我们将我们的店铺地址和店名关系存储在一张表里,当用户搜索的时候,我们根据自己定义的规则,给他推荐相应的那家店。 这个就是DNS负载均衡的原理,听着好像也没啥,那它有什么优点呢? 1.简单,将负载均衡的工作交给DNS,省去了网站管理维护负载均衡服务器的麻烦 2.技术实现比较灵活、方便,简单易行,成本低,使用于大多数TCP/IP应用 3.DNS还支持基于地理位置的域名解析,即会将域名解析成距离用户地理最近的一个服务器地址,这样就可以加速用户访问,改善性能。试想,你能给用户推荐离他最近的那家店,是不是体验会很好? 凡事有利有弊,那DNS负载均衡有哪些缺点呢? 1.实时性差,因为DNS的缓存机制,假设你的一家店地址换了,但要使修改生效,也需要一段时间,那在这段时间内,解析出的结果就不对了 2.负载均衡算法采取简单的轮训算法,不够智能,假设你的一家店已经满员了,但它还在不停的给你推客人,是不是很火大? 3.扩展能力差,可能会造成额外的网络问题。
3.2 软件负载均衡
软件负载均衡是我们最常接触到的一种负载方式,通过负载均衡功能的软件来实现负载均衡,常见的软件有LVS、Nginx、HAProxy。我主要记录下nginx
一、Nginx 负载均衡及相关策略介绍
负载均衡技术少不了相关的均衡策略,Nginx 中提供了 4 种均衡策略,我们可以根据具体的业务场景选择合适的均衡策略。下面分别介绍这 4 中均衡策略:
1、基于轮询的均衡策略:
轮询嘛,就是说对进到nginx的request按照遍历的方式进行分发,如果request 1 分发到 Server A,那么request 2将被分发到 Server B,......以此循环类推
2、基于最少连接数的均衡策略:
最少连接,也就是说nginx会判断后端集群服务器中哪个Server当前的 Active Connection 数是最少的,那么对于每个新进来的request,nginx将该request分发给对应的Server.
3、基于ip-hash的均衡策略:
我们都知道,每个请求的客户端都有相应的ip地址,该均衡策略中,nginx将会根据相应的hash函数,对每个请求的ip作为关键字,得到的hash值将会决定将请求分发给相应Server进行处理
4、基于加权轮询的均衡策略:
加权轮询,很显然这个策略跟我们开题引入的场景是一样的,nginx会给Server配置相应的权重,权重越大,接收的request数将会越多
上面的均衡策略其实都非常很好理解,但是如果想了解其实现原理,可以看源代码,但是小编就算了,我是看不懂C、C++的。
二、Nginx 不同均衡策略的配置介绍
1、基于轮询的均衡策略:
这个是Nginx默认的均衡算法,如果你不进行相关的配置,默认会执行该策略,配置如下:
http { upstream myapp1 { server srv1.example.com; server srv2.example.com; server srv3.example.com; } server { listen 80; location / { proxy_pass http://myapp1; } } }
复制代码可以看出,nginx负载均衡使用到的指令不多,其中比较重要的两个是upstream和proxy_pass,upstream块定义一个后端小集群,里边配置相关的Server组成这个集群,同时upstream为这个集群起个相应的名字,本实例叫myapp1.proxy_pass处于location块中,表示对于所有符合/的request,将会交给哪个集群进行处理,本实例为http://myapp1。
但又一点我们需要注意,上面http://myapp1中myapp1必须是upstream起的名字,对于协议是使用http还是https,都无所谓,如果你的协议使用https,则将http直接改成https即可。另外,如果你在upstream中的server指令中指定了协议名,那么在proxy_pass指令中就不需要加上协议名称了。
nginx负载均衡使用反向代理实现,也就是我们上面使用到的proxy_pass指令,支持的协议不止是http和https,同时还支持FastCGI、uwsgi、SCGI、memcached、gRPC,如果你需要使用除了http、https外的其他协议,我们不能使用proxy_pass指令了,应该转而使用相应的指令,如fastcgi_pass、uwsgi_pass、scgi_pass、memcached_pass、grpc_pass。
该策略处理负载,小编认为还是有缺陷的,不能防止某台Server出现负载过高的情况。因为如果有些请求执行时间过长,而系统的并发量却非常大,那么就可能导致某台Server出现request堆积,负载过高,snowslide is possible~
2、基于最少连接数的均衡策略:
该策略主要使用了least_conn指令,具体配置如下:
upstream myapp1 { least_conn; server srv1.example.com; server srv2.example.com; server srv3.example.com; }
复制代码该策略还是比较人性化的,可以按照机器的实际情况进行刚需分配。
3、基于ip-hash的均衡策略:
当然了,如果我们想实现这样一个功能,我们想让对于相同客户端的请求每次都被分发到同一个Server进行处理,上面两种策略都是不做到。此策略可确保来自同一客户端的请求始终定向到同一服务器,但此服务器不可用时除外。相关配置如下:
upstream myapp1 { ip_hash; server srv1.example.com; server srv2.example.com; server srv3.example.com; }
复制代码既然相同客户端的请求能被同一台Server进行处理,那么相同客户端的会话Session就可以实现持久化了。
4、基于加权轮询的均衡策略:
基于加权轮询的策略就不需要过多讲解了,就是在轮询的基础上加上个权重信息
upstream myapp1 { server srv1.example.com weight=3; server srv2.example.com; server srv3.example.com; }
复制代码这种策略适合Server机器处理能力有区别的情况。
三、nginx 负载均衡更多高级特性及配置
1、健康检查
不仅人需要体检,机器也是需要体检的,那么就当nginx就是那位体检医生吧!nginx健康检查是什么呢?当我们一个request进来被分发到相应的Server进行处理后,nginx会检查该request执行是否超时,是否执行失败了等情况,然后做出相应的处理---比如说当nginx检查出Server A执行某request时报出502错误了,那么下次nginx负载均衡时就会在upstream块中将Server A排除掉,不分发请求给到Server A了。 对于健康检查的功能,nginx提供了基本两个指令,即max_fails和fail_timeout,也就是说当nginx检查到某Server发生错误的request数达到max_fails或者执行某request执行时间超过fail_timeout了,如果发生超时了,nginx将开始使用实时请求优雅地探测Server,如果有响应,则认为对应的Server还是活着的,没有毛病的。
2、更多配置
针对上面upstream块中的server指令,其格式为:server address [parameters];,里边的parameters可以有很多的参数类型,比如说指定某台Server不参与负载均衡等。具体配置详见官网链接,点击此处传送门。
4.总结
上面介绍了几种常见的负载均衡策略,首先是区分概念吧,从硬件和软件方面,我们接触最多的是软件负载均衡,以nginx为代表,主要要了解负载的策略,按需配置,nginx除了可以负载均衡外,在解决跨域的问题时也有自己的应用,这个后面再做记录。
参考资料
[2]DNS负载均衡