首页 存档 技术 查看内容

Nginx负载均衡与反向代理《亿级流量网站架构核心技术》

2018-3-30 13:00 |来自: 互联网 445 0

摘要: 本篇摘自《亿级流量网站架构核心技术》第二章 Nginx负载均衡与反向代理 部分内容。 当我们的应用单实例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台、几十台、几百台。然而,用户访问时是通过如htt ...

本篇摘自《亿级流量网站架构核心技术》第二章 Nginx负载均衡与反向代理 部分内容。


当我们的应用单实例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台、几十台、几百台。然而,用户访问时是通过如http://www.jd.com的方式访问,在请求时,浏览器首先会查询DNS服务器获取对应的IP,然后通过此IP访问对应的服务。


因此,一种方式是www.jd.com域名映射多个IP,但是,存在一个最简单的问题,假设某台服务器重启或者出现故障,DNS会有一定的缓存时间,故障后切换时间长,而且没有对后端服务进行心跳检查和失败重试的机制。


因此,外网DNS应该用来实现用GSLB(全局负载均衡)进行流量调度,如将用户分配到离他最近的服务器上以提升体验。而且当某一区域的机房出现问题时(如被挖断了光缆),可以通过DNS指向其他区域的IP来使服务可用。

可以在站长之家使用“DNS查询”,查询c.3.cn可以看到类似如下的结果。

即不同的运营商返回的公网IP是不一样的。


对于内网DNS,可以实现简单的轮询负载均衡。但是,还是那句话,会有一定的缓存时间并且没有失败重试机制。因此,我们可以考虑选择如HaProxy和Nginx。


而对于一般应用来说,有Nginx就可以了。但Nginx一般用于七层负载均衡,其吞吐量是有一定限制的。为了提升整体吞吐量,会在DNS和Nginx之间引入接入层,如使用LVS(软件负载均衡器)、F5(硬负载均衡器)可以做四层负载均衡,即首先DNS解析到LVS/F5,然后LVS/F5转发给Nginx,再由Nginx转发给后端Real Server。


对于一般业务开发人员来说,我们只需要关心到Nginx层面就够了,LVS/F5一般由系统/运维工程师来维护。Nginx目前提供了HTTP(ngx_http_upstream_module)七层负载均衡,而1.9.0版本也开始支持TCP(ngx_stream_upstream_module)四层负载均衡。


此处再澄清几个概念。二层负载均衡是通过改写报文的目标MAC地址为上游服务器MAC地址,源IP地址和目标IP地址是没有变的,负载均衡服务器和真实服务器共享同一个VIP,如LVS DR工作模式。四层负载均衡是根据端口将报文转发到上游服务器(不同的IP地址 端口),如LVS NAT模式、HaProxy,七层负载均衡是根据端口号和应用层协议如HTTP协议的主机名、URL,转发报文到上游服务器(不同的IP地址 端口),如HaProxy、Nginx。


这里再介绍一下LVS DR工作模式,其工作在数据链路层,LVS和上游服务器共享同一个VIP,通过改写报文的目标MAC地址为上游服务器MAC地址实现负载均衡,上游服务器直接响应报文到客户端,不经过LVS,从而提升性能。但因为LVS和上游服务器必须在同一个子网,为了解决跨子网问题而又不影响负载性能,可以选择在LVS后边挂HaProxy,通过四到七层负载均衡器HaProxy集群来解决跨网和性能问题。这两个“半成品”的东西相互取长补短,组合起来就变成了一个“完整”的负载均衡器。现在Nginx的stream也支持TCP,所以Nginx也算是一个四到七层的负载均衡器,一般场景下可以用Nginx取代HaProxy。


在继续讲解之前,首先统一几个术语。接入层、反向代理服务器、负载均衡服务器,在本文中如无特殊说明则指的是Nginx。upstream server即上游服务器,指Nginx负载均衡到的处理业务的服务器,也可以称之为real server,即真实处理业务的服务器。


对于负载均衡我们要关心的几个方面如下。

上游服务器配置:使用upstream server配置上游服务器。

负载均衡算法:配置多个上游服务器时的负载均衡机制。

失败重试机制:配置当超时或上游服务器不存活时,是否需要重试其他上游服务器。

服务器心跳检查:上游服务器的健康检查/心跳检查。


Nginx提供的负载均衡可以实现上游服务器的负载均衡、故障转移、失败重试、容错、健康检查等,当某些上游服务器出现问题时可以将请求转到其他上游服务器以保障高可用,并可以通过OpenResty实现更智能的负载均衡,如将热点与非热点流量分离、正常流量与爬虫流量分离等。Nginx负载均衡器本身也是一台反向代理服务器,将用户请求通过Nginx代理到内网中的某台上游服务器处理,反向代理服务器可以对响应结果进行缓存、压缩等处理以提升性能。Nginx作为负载均衡器/反向代理服务器如下图所示。


本章首先会讲解Nginx HTTP负载均衡,最后会讲解使用Nginx实现四层负载均衡。

2.1 upstream配置

第一步我们需要给Nginx配置上游服务器,即负载均衡到的真实处理业务的服务器,通过在http指令下配置upstream即可。

upstream backend {

server 192.168.61.1:9080 weight=1;

server 192.168.61.1:9090 weight=2;

}

upstream server主要配置。

IP地址和端口:配置上游服务器的IP地址和端口。

权重:weight用来配置权重,默认都是1,权重越高分配给这台服务器的请求就越多(如上配置为每三次请求中一个请求转发给9080,其余两个请求转发给9090),需要根据服务器的实际处理能力设置权重(比如,物理服务器和虚拟机就需要不同的权重)。


然后,我们可以配置如下proxy_pass来处理用户请求。

location / {

proxy_pass http://backend;

}

当访问Nginx时,会将请求反向代理到backend配置的Upstream Server。接下来我们看一下负载均衡算法。

2.2 负载均衡算法

负载均衡用来解决用户请求到来时如何选择Upstream Server进行处理,默认采用的是round-robin(轮询),同时支持其他几种算法。


round-robin:轮询,默认负载均衡算法,即以轮询的方式将请求转发到上游服务器,通过配合weight配置可以实现基于权重的轮询。


ip_hash:根据客户IP进行负载均衡,即相同的IP将负载均衡到同一个Upstream Server。

upstream backend {

ip_hash;

server 192.168.61.1:9080 weight=1;

server 192.168.61.1:9090 weight=2;

}

hash key [consistent]:对某一个key进行哈希或者使用一致性哈希算法进行负载均衡。使用Hash算法存在的问题是,当添加/删除一台服务器时,将导致很多key被重新负载均衡到不同的服务器(从而导致后端可能出现问题);因此,建议考虑使用一致性哈希算法,这样当添加/删除一台服务器时,只有少数key将被重新负载均衡到不同的服务器。


哈希算法:此处是根据请求uri进行负载均衡,可以使用Nginx变量,因此,可以实现复杂的算法。

upstream backend {

hash $uri;

server 192.168.61.1:9080 weight=1;

server 192.168.61.1:9090 weight=2;

}

一致性哈希算法:consistent_key动态指定。

upstream nginx_local_server {

hash $consistent_key consistent;

server 192.168.61.1:9080 weight=1;

server 192.168.61.1:9090 weight=2;

}

如下location指定了一致性哈希key,此处会优先考虑求参数cat(类目),如果没有,则再根据请求uri进行负载均衡。

location / {

set $consistent_key $arg_cat;

if($consistent_key = "") {

set $consistent_key $request_uri;

}

}

而实际我们是通过lua设置一致性哈希key。

set_by_lua_file $consistent_key"lua_balancing.lua";

lua_balancing.lua代码。

local consistent_key = args.cat

if not consistent_key or consistent_key == '' then

consistent_key = ngx_var.request_uri

end

local value = balancing_cache:get(consistent_key)

if not value then

success,err = balancing_cache:set(consistent_key, 1, 60)

else

newval,err = balancing_cache:incr(consistent_key, 1)

end

如果某一个分类请求量太大,上游服务器可能处理不了这么多的请求,此时可以在一致性哈希key后加上递增的计数以实现类似轮询的算法。

if newval

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部