一个项目的成功与否,往往是由用户的多少来计算,随着访问量的上升,如何提高效率、保障系统的可用性就成了必须要解决的问题。
不论是面试,还是公众号里的文章,集群、负载均衡、分布式,这三个词的出现频率总是很高。
栗子
从集群、负载均衡、分布式的定义来看,乍听上去都是为了解决高并发的,无法很直观的发现它们的区别与联系。下面我们通过一个栗子,看看它们到底是做什么的。
- 二蛋是个心怀天下的吃货,为了让更多的人吃上好吃的,于是开了个饭馆儿,处于对自己的充分信任,一个员工都没有,惨状如下图:
- 终于有一天,二蛋受不了了,决定雇两个像自己一样厉害的同志,立志做个甩手掌柜的,嚣张状如下图:
二蛋的两个手下所形成的,就是集群,部署两套完全一样的,执行相同任务的项目,就像多个 tomcat 下都部署同一个项目。那么二蛋就完全没有事了吗?不是的,分配工作的任务由他负责,负载均衡就是在这里。
- 在上边的结构里,二蛋轻松了不少,可两个手下很快就提出了抗议,从头忙到尾不说,还要干些不擅长的工作,于是二蛋狠了狠心,又招来几批人,痛心状如下图:
根据业务分组,每组人马就只负责自己擅长的,就是分布式。而且今天记账的同志请假了,并不影响整个饭馆儿的运营,最多只是账晚点再计嘛。每种业务只招一个人的风险还是很大,因为如果厨子病倒了,饭馆儿照样不能营业。所以分布式中往往附带着集群,那么有了集群,怎么分发请求呢,还是会用到负载均衡。
总结
- 集群:运行多个做同样工作的程序,相当于把现有的项目部署到多个服务器上。
- 负载均衡:分发请求给集群中的某一台服务器。
- 分布式:根据业务拆分出独立的服务,可以拥有自己的数据库,服务之间互不影响。
- 关系:为了使服务更加灵活,我们希望每种业务都有自己独立的服务,可供任何项目调用,所以用到了分布式;想要使服务高可用,就需要再以集群的方式部署,那么管理请求时,自然会用到负载均衡。
负载均衡
常用的负载均衡工具有 nginx,zookeeper,eureka 等,我们需要配置集群中的各台服务器信息,还可以指定分发请求的方式。
分发算法
- 轮询:轮流访问。(默认)
- 加权轮询:在轮流访问的基础上,可以给每台服务器配置加权值。
- 随机:就是随机访问。
- 最小连接数:把请求发送给当前连接最少的服务器上。
- IP 哈希算法:根据客户端的 IP 计算,可保证一个客户端总访问到一个服务器上,避免了 session 不同步的问题。
- URL 散列:可保证同一 URL 总访问同一个服务器。
配置方法
upstream{
ip_hash
server 192.168.0.1 weight=1 max_fails=1 fail_timeout=30s;
server 192.268.0.2 weight=2 backup;
}
ip_hash:IP 哈希算法。
weight:权重。
max_fails:最大失败次数,超过时会返回 proxy_next_upstream 模块定义的错误。
fail_timeout:max_fails 次失败后,暂停的时间。
backup:这台服务器的压力最小,只有其它非 backup 服务器挂了,或是忙的时候,才会被调用。