Nginx 的负载均衡模式有哪些?它的实现原理是什么?

Stella981
• 阅读 425

Nginx 的负载均衡模式有哪些?它的实现原理是什么?

文章来源:https://kaiwu.lagou.com/course/courseInfo.htm?courseId=59#/detail/pc?id=1793
作者: 拉勾教育

Nginx 是后端工程师和运维工程师,以及前端工程师必须要掌握的必备技能,尤其在分布式系统应用越来越广泛的今天,Nginx 已经占据了 Web 服务器的大壁江山,并且还在不断地增长,比如国内的 BATJ、网易、新浪等公司都可以看到它的身影。

我们本章主要内容是,Nginx 的负载均衡模式有哪些?它的实现原理是什么?

典型回答

在正式开始之前,我们先来了解一下什么是 Nginx?

Nginx 是一款开源的高性能轻量级 「Web 服务器」(也叫 「HTTP 服务器」),它主要提供的功能是:「反向代理、负载均衡」「HTTP 缓存」。它于 2004 年首次公开发布,2011 年成立同名公司以提供支持,2019 年 3 月被 F5 Networks 以 6.7 亿美元收购。

之所以需要使用负载均衡是因为,如果我们使用的是一台服务器,那么在高峰期时很多用户就需要排队等待系统响应,因为一台服务器能处理的并发数是固定的。例如,一个 Tomcat 在默认情况下只能开启 150 个线程(Tomcat 8.5.x 版本)来处理并发任务,如果并发数超过了最大线程数,那么新来的请求就只能排队等待处理了,如下图所示:

Nginx 的负载均衡模式有哪些?它的实现原理是什么?

然而如果有负载均衡的话,我们就可以将所有的请求分配到不同的服务器上。假如 1 台服务器可以处理 2000 个请求,那么 5 台服务器就可以处理 10000 个请求了,这样就大大提高了系统处理业务的能力,如下图所示:

Nginx 的负载均衡模式有哪些?它的实现原理是什么?

知道了负载均衡的好处之后,我们来看下 Nginx 负载均衡的功能。

Nginx 主要的负载均衡策略(内置的负载均衡)有以下四种:

  • 轮询策略(默认负载均衡策略)

  • 最少连接数负载均衡策略

  • ip-hash 负载均衡策略

  • 权重负载均衡策略

1. 轮询策略

轮询负载策略是指每次将请求按顺序轮流发送至相应的服务器上,它的配置示例如下所示:

http {     upstream myapp1 {         server srv1.example.com;         server srv2.example.com;         server srv3.example.com;     }     server {         listen 80;         location / {             proxy_pass http://myapp1;         }     } }

在以上实例中,当我们使用“ip:80/”访问时,请求就会轮询的发送至上面配置的三台服务器上。Nginx 可以实现 HTTP、HTTPS、FastCGI、uwsgi、SCGI、memcached 和 gRPC 的负载均衡。

2. 最少连接数负载均衡

此策略是指每次将请求分发到当前连接数最少的服务器上,也就是 Nginx 会将请求试图转发给相对空闲的服务器以实现负载平衡,它的配置示例如下:

upstream myapp1 {     least_conn;     server srv1.example.com;     server srv2.example.com;     server srv3.example.com; }

3. 加权负载均衡

此配置方式是指每次会按照服务器配置的权重进行请求分发,权重高的服务器会收到更多的请求,这就相当于给 Nginx 在请求分发时加了一个参考的权重选项,并且这个权重值是可以人工配置的。因此我们就可以将硬件配置高,以及并发能力强的服务器的权重设置高一点,以更合理地利用服务器的资源,它配置示例如下:

upstream myapp1 {     server srv1.example.com weight=3;     server srv2.example.com;     server srv3.example.com; }

以上配置表示,5 次请求中有 3 次请求会分发给 srv1,1 次请求会分发给 srv2,另外 1 次请求会分发给 srv3。

4. ip-hash 负载均衡

以上三种负载均衡的配置策略都不能保证将每个客户端的请求固定的分配到一台服务器上。假如用户的登录信息是保存在单台服务器上的,而不是保存在类似于 Redis 这样的第三方中间件上时,如果不能将每个客户端的请求固定的分配到一台服务器上,就会导致用户的登录信息丢失。因此用户在每次请求服务器时都需要进行登录验证,这样显然是不合理的,也是不能被用户所接受的,所以在特殊情况下我们就需要使用 ip-hash 的负载均衡策略。

ip-hash 负载均衡策略可以根据客户端的 IP,将其固定的分配到相应的服务器上,它的配置示例如下:

upstream myapp1 {     ip_hash;     server srv1.example.com;     server srv2.example.com;     server srv3.example.com; }

Nginx 的实现原理是,首先客户端通过访问域名地址发出 HTTP 请求,访问的域名会被 DNS 服务器解析为 Nginx 的 IP 地址,然后将请求转发至 Nginx 服务器,Nginx 接收到请求之后会通过 URL 地址和负载均衡的配置,匹配到配置的代理服务器,然后将请求转发给代理服务器,代理服务器拿到请求之后将处理结果返回给 Nginx,Nginx 再将结果返回给客户端,这样就完成了一次正常的 HTTP 交互。

考点分析

负载均衡和缓存功能是 Nginx 最常用的两个功能,这两个功能都属于高性能的调优手段,也和后端人员的关系比较密切,只有了解并会使用它们才能更好地调试和运行自己的项目,因此 Nginx 的相关知识几乎是面试中都会出现。

和此知识点相关的面试题还有以下这些:

  • 如果代理的服务器宕机了 Nginx 会如何处理?

  • Nginx 的缓存功能是如何使用的?

知识扩展

健康检测

被代理的服务器出现宕机的情况,如果被 Nginx 发现,那么 Nginx 就会将其自动标识为不可用,并且在一段时间内会禁止入站的请求访问到该服务器上。

而这个发现服务器宕机的过程就是健康检测的功能了。Nginx 的健康检测分为两种类型,「主动检测和被动检测」,默认的非商用 Nginx 采用的是被动检测。

所谓的被动检测是指只有访问了该服务器之后发现服务器不可用了,才会将其标识为不可用,并且在一定时间内禁止请求分发到该服务器上,而不是主动以一定的频率去检查服务器是否可用。

健康检测有两个重要参数 「max_fails」「fail_timeout」

fail_timeout 定义了健康检查的执行时长,而 max_fails 表示服务不可用的最大尝试次数,当一定时间内(此时间由 fail_timeout 定义),发生了一定次数的服务器不响应的事件(此次数由 max_fails 定义),那么 Nginx 就会将该服务器标识为不可用的服务器,并且在一定时间内禁止请求分发到该服务器。默认情况下 max_fails 设置为 1,当它设置为 0 时表示禁用此服务器的运行状况检查,它的配置示例如下:

upstream cluster{     server srv1.example.com max_fails=2 fail_timeout=10s;     server srv2.example.com max_fails=2 fail_timeout=10s; }

以上配置表示,如果 10s 内发生了两次服务不可用的情况就会将该服务器标识为不可用的状态。当服务器被标识为不可用时,只有达到了 fail_timeout 定义的时间后,才会进行再一次的健康请求检测。

而主动健康检测的实现方案有两种,一种是使用商用的 Nginx Plus 来配置主动健康检测,另一种是使用开源的第三方模块 nginx_upstream_check_module 来实现主动健康检测。

Nginx Plus 和 nginx_upstream_check_module 模块的主动健康检查配置大体都是一样的,它的配置示例如下:

upstream backend {     server srv1.example.com;     server srv2.example.com;     check interval=3000 rise=1 fall=3 timeout=2000 type=http;     check_http_send "HEAD /status HTTP/1.0\r\n\r\n";     check_http_expect_alive http_2xx http_3xx; }

其中,check_http_send 表示发送请求的内容,而 check_http_expect_alive 是服务器正常情况下的响应状态码,如果后端服务器的响应状态包含在此配置中,则说明是健康的状态。

Nginx 缓存

我们可以开启 Nginx 的静态资源缓存,将一些不变的静态文件,比如图片、CSS、JS 等文件进行缓存,这样在客户端访问这些资源时就不用去访问服务器了,因此响应的速度就可以大幅提升,并且节省了宝贵的服务器资源。

Nginx 开启缓存需要在 http 节点中配置 proxy_cache_path 信息,以及 server 节点中配置要缓存资源的后缀名,它的配置示例如下:

http {   // 忽略其他的配置信息......   proxy_cache_path  /data/cache levels=1:2 keys_zone=nuget-cache:20m max_size=50g inactive=1d;   include nginx_proxy.conf;   server {     listen  80;     server_name  srv1.example.com;       location ~ .*\.(gif|jpg|png|css|js)(.*) { # 要缓存的文件的后缀       access_log off;       add_header Cache-Control "public,max-age=24*3600";       proxy_pass http://localhost:8080;     }   } }

其中,proxy_cache_path 配置的是缓存的目录信息,以及缓存的保存时间 inactive,还有缓存的大小等信息;而“access_log off”表示关闭日志功能,proxy_pass 表示当第一次没有缓存时的请求地址,之后便会将访问到的资源缓存起来。

小结

本课时我们介绍了 Nginx,并讲了 Nginx 的四种内置负载均衡的执行策略:轮询策略(默认负载均衡策略)、最少连接数负载均衡策略、ip-hash 负载均衡策略和权重负载均衡策略,其中 ip-hash 的负载均衡策略会将客户端的请求固定分发到一台服务器上。

后面我们还介绍了 Nginx 的健康检测:主动健康检测和被动健康检测;最后我们还讲了 Nginx 的缓存功能,它可以帮我们更快的访问到静态资源。

学完本课时后,相信你对 Nginx 已经有了一个大体的认识,其中面试中被问到最多的知识点是 Nginx 的四种负载均衡以及健康检查的相关内容。

如果本文对你有帮助,

别忘记给我个三连:

点赞,转发,评论

咱们下期见!

收藏 等于白嫖点赞 才是真情!

End

干货分享

这里为大家准备了一份小小的礼物,关注公众号,输入如下代码,即可获得百度网盘地址,无套路领取!

001:《程序员必读书籍》
002:《从无到有搭建中小型互联网公司后台服务架构与运维架构》
003:《互联网企业高并发解决方案》
004:《互联网架构教学视频》
006:《SpringBoot实现点餐系统》
007:《SpringSecurity实战视频》
008:《Hadoop实战教学视频》
009:《腾讯2019Techo开发者大会PPT》

010: 微信交流群

近期热文top

1、关于JWT Token 自动续期的解决方案

2、还不了解ETL,看看这篇文章?

3、为什么微服务需要api网关

4、架构师之路-微服务技术选型

5、RocketMQ进阶 - 事务消息

Nginx 的负载均衡模式有哪些?它的实现原理是什么?

我就知道你“在看”

Nginx 的负载均衡模式有哪些?它的实现原理是什么?

本文分享自微信公众号 - JAVA日知录(javadaily)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这