nginx负载均衡服务器集群
你有没有遇到过自己写的程序因为请求量访问量越来越多了,导致服务器承受不了高负载的压力,程序越来越卡了,响应越来越慢。这种情况下怎么进行优化,负载均衡,分布式部署,代码优化,cdn加速,mysql主从,redis主从,缓存技术等等...
今天主要讲一下Nginx负载均衡服务器集群,从一个服务器转为多个服务器处理业务逻辑,并且响应返回,这样多个服务器都做同样的事情,一起分担了用户的请求。
这时候可以分为两种服务器:
- 负载均衡服务器
- 处理业务的服务器(每个服务器的业务代码逻辑都必须一模一样)
负载均衡服务器负责接收客户端的请求,经过一些算法(轮询,权重,哈希),把请求分发到处理业务的服务器,这么说来负载均衡服务器就像一个中介。
怎么配置?
现在我有三个服务器
服务器S 49.135.45.8
服务器A 49.135.45.9
服务器B 49.135.45.10
我要把服务器S作为负载均衡服务器,服务器A和服务器B作为处理业务的程序服务器,服务器S把请求分发到服务器A和服务器B中
这里只描述服务器S的nginx配置,以我的博客www.huangzhongxin.cn
为例,负载服务器收到域名为www.huangzhongxin.cn
的请求分发到我定义的多个服务器
upstream huangzhongxin {
server 49.135.45.9:80;
server 49.135.45.10:80;
}
server {
listen 80;
server_name www.huangzhongxin.cn
location / {
proxy_pass http://huangzhongxin; #请求转向huangzhongxin所定义的服务器列表
}
}
上面的配置中的算法是轮询,nginx默认就是轮询其权重都默认为1,上面的配置中服务器处理请求的顺序:ABABABABAB....
如果我的服务器B配置高很多,我想把更多的请求分发到服务器B怎么办?
upstream huangzhongxin {
server 49.135.45.9:80 weight=1;
server 49.135.45.10:80 weight=2;
}
加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。服务器的请求顺序为:ABBABBABBABBABB....
如果我只想服务器A运行,当服务器A挂掉时,我想服务器B启动代替服务器A怎么办?
upstream huangzhongxin {
server 49.135.45.9:80;
server 49.135.45.10:80 backup;
}
热备:当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB.....
如果我想一台设备第一次请求了A服务器,下面的请求都想请求到服务器A怎么办?
upstream huangzhongxin {
server 49.135.45.9:80;
server 49.135.45.10:80;
ip_hash;
}
ip_hash: nginx会让相同的客户端ip请求到相同的服务器
nginx负载均衡配置的几个状态参数:
- down,表示当前的server暂时不参与负载均衡
- backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻
- max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误
- fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用
注意事项
集群的服务器业务逻辑处理必须一模一样,这样涉及到很多问题,在代码设计架构的时候要先考虑好
- 数据的问题,mysql和redis这些只能统一部署在另一个服务器或者第三方购买
- 图片放哪里?不可能说上传到哪个服务器就保存到哪个服务器,获取资源时请求到另外一个服务器时那就获取不到了。图片可以统一存放在另一个资源服务器或者cdn,这其实就涉及到分布式了
- 用户登录的问题,session存在哪里?可以改一下记录用户登录的机制,可以不使用session,或者存数据库之类的,比如token我存mysql或redis服务器,每个机器读到都是一样的。(网站的话使用ip_hash算法的,其实可以解决session的问题)
说明
以上就是简单的负载均衡的实现。准确的来说,这些属于:HTTP重定向实现负载均衡。它有一个比较大的缺点,由于不同用户的访问时间、访问页面深度有所不同,从而每个用户对各自的后端服务器所造成的压力也不同。而调度服务器在调度时,无法知道当前用户将会对服务器造成多大的压力,因此这种方式无法实现真正意义上的负载均衡,只不过是把请求次数平均分配给每台服务器罢了。
如果你想实现更智能算法更好的负载均衡,可以向第三方购买负载均衡服务,第三方的负载均衡服务提供了更加智能,更加符合场景的算法。