架构师系列-Nginx、OpenResty(三)- 负载均衡配置

news/2024/5/5 7:54:59

Nginx负载均衡

负载均衡用于从“upstream”模块定义的后端服务器列表中选取一台服务器接受用户的请求,一个最基本的upstream模块是这样的,模块内的server是服务器列表:

#动态服务器组
upstream dynamicserver {server 172.16.44.47:9001; #tomcat 1server 172.16.44.47:9002; #tomcat 2server 172.16.44.47:9003; #tomcat 3server 172.16.44.47:9004; #tomcat 4
}

在upstream模块配置完成后,要让指定的访问反向代理到服务器列表

#其他页面反向代理到tomcat容器
location ~.*$ {index index.jsp index.html;proxy_pass http://dynamicserver;
}

这就是最基本的负载均衡实例,但这不足以满足实际需求;目前Nginx服务器的upstream模块支持6种方式的分配。

完整配置文件如下

upstream dynamicserver {server 192.168.64.1:9001; #tomcat 1server 192.168.64.1:9002; #tomcat 2server 192.168.64.1:9003; #tomcat 3server 192.168.64.1:9004; #tomcat 4
}
server {server_name www.itcast.com;default_type text/html;charset   utf-8;location ~ .*$ {index index.jsp index.html;proxy_pass http://dynamicserver;}
}

常用参数

参数描述
server反向服务地址 加端口
weight权重
fail_timeout与max_fails结合使用。
max_fails设置在fail_timeout参数设置的时间内最大失败次数,如果在这个时间内,所有针对该服务器的请求都失败了,那么认为该服务器会被认为是停机了
max_conns允许最大连接数
fail_time服务器会被认为停机的时间长度,默认为10s
backup标记该服务器为备用服务器,当主服务器停止时,请求会被发送到它这里。
down标记服务器永久停机了
slow_start当节点恢复,不立即加入

负载均衡策略 

在这里,只详细说明Nginx自带的负载均衡策略。

负载策略描述
轮询默认方式
weight权重方式
ip_hash依据ip分配方式
least_conn最少连接方式
fair(第三方)响应时间方式
url_hash(第三方)依据URL分配方式

轮询 

最基本的配置方法,上面的例子就是轮询的方式,它是upstream模块默认的负载均衡默认策略,每个请求会按时间顺序逐一分配到不同的后端服务器。

#动态服务器组
upstream dynamicserver {server 192.168.64.1:9001; #tomcat 1server 192.168.64.1:9002; #tomcat 2server 192.168.64.1:9003; #tomcat 3server 192.168.64.1:9004; #tomcat 4
}

 注意

  • 在轮询中,如果服务器down掉了,会自动剔除该服务器。
  • 缺省配置就是轮询策略。
  • 此策略适合服务器配置相当,无状态且短平快的服务使用。

 配置示例

upstream dynamicserver {server 192.168.64.1:9001; #tomcat 1server 192.168.64.1:9002; #tomcat 2server 192.168.64.1:9003; #tomcat 3server 192.168.64.1:9004; #tomcat 4
}server {server_name www.test.com;default_type text/html;charset   utf-8;location ~ .*$ {index index.jsp index.html;proxy_pass http://dynamicserver;}
}

 weight

权重方式,在轮询策略的基础上指定轮询的几率

#动态服务器组
upstream dynamicserver {server 192.168.64.1:9001  weight=2;                   #tomcat 1server 192.168.64.1:9002;                             #tomcat 2server 192.168.64.1:9003;                         #tomcat 3server 192.168.64.1:9004; #tomcat 4
}

weight参数用于指定轮询几率,weight的默认值为1,;weight的数值与访问比率成正比,比如Tomcat 7.0被访问的几率为其他服务器的两倍。

注意

  • 权重越高分配到需要处理的请求越多。
  • 此策略可以与least_conn和ip_hash结合使用。
  • 此策略比较适合服务器的硬件配置差别比较大的情况。

 ip_hash

指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证session会话,这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题

upstream dynamicserver {ip_hash;  #保证每个访客固定访问一个后端服务器server 192.168.64.1:9001  weight=2;                   #tomcat 1server 192.168.64.1:9002;                             #tomcat 2server 192.168.64.1:9003;                         #tomcat 3server 192.168.64.1:9004; #tomcat 4
}

注意

  • 在nginx版本1.3.1之前,不能在ip_hash中使用权重(weight)。
  • ip_hash不能与backup同时使用
  • 此策略适合有状态服务,比如session。
  • 当有服务器需要剔除,必须手动down掉。

least_conn 

把请求转发给连接数较少的后端服务器,轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高,这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。

upstream dynamicserver {least_conn;  #把请求转发给连接数较少的后端服务器server 192.168.64.1:9001  weight=2;                   #tomcat 1server 192.168.64.1:9002;                             #tomcat 2server 192.168.64.1:9003;                         #tomcat 3server 192.168.64.1:9004; #tomcat 4
}
  • 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。

 重试策略

现在对外服务的网站,很少只使用一个服务节点,而是部署多台服务器,上层通过一定机制保证容错和负载均衡。

基础失败重试 

为了方便理解,使用了以下配置进行分析(proxy_next_upstream 没有特殊配置)

upstream dynamicserver {server 192.168.64.1:9001 fail_timeout=60s max_fails=3; #Server Aserver 192.168.64.1:9002 fail_timeout=60s max_fails=3; #Server B
}

配置说明

max_fails=3 fail_timeout=60s代表在60秒内请求某一应用失败3次,认为该应用宕机,后等待60秒,这期间内不会再把新请求发送到宕机应用,而是直接发到正常的那一台,时间到后再有请求进来继续尝试连接宕机应用且仅尝试1次,如果还是失败,则继续等待60秒...以此循环,直到恢复

模拟异常

模拟后端异常的方式是直接将对应服务关闭,造成 connect refused 的情况,对应 error 错误。

在最初始阶段,所有服务器都正常,请求会按照轮询方式依次转发给 AB 两个 Server 处理。假设这时 A 节点服务崩溃,端口不通,则会出现这种情况:

  1. 请求 1 转到 A 异常,再重试到 B 正常处理,A fails +1
  2. 请求 2 转到 B 正常处理
  3. 请求 3 转到 A 异常,再重试到 B 正常处理,A fails +1 达到 max_fails 将被屏蔽 60s
  4. 屏蔽 A 的期间请求都只转给 B 处理,直到屏蔽到期后将 A 恢复重新加入存活列表,再按照这个逻辑执行

如果在 A 的屏蔽期还没结束时,B 节点的服务也崩溃,端口不通,则会出现:

  1. 请求 1 转到 B 异常,此时所有线上节点异常,会出现:

    • AB 节点一次性恢复,都重新加入存活列表
    • 请求转到 A 处理异常,再转到 B 处理异常
    • 触发 no live upstreams 报错,返回 502 错误
    • 所有节点再次一次性恢复,加入存活列表
  2. 请求 2 依次经过 AB 均无法正常处理, 触发 no live upstreams 报错,返回 502 错误

 错误重试

有时候我们系统出现500等异常的情况下,希望nginx能够到其他的服务器进行重试,我们可以配置那些错误码才进行重试。在nginx的配置文件中,proxy_next_upstream项定义了什么情况下进行重试,官网文档中给出的说明如下

Syntax: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...;
Default:    proxy_next_upstream error timeout;
Context:    http, server, location

默认情况下,当请求服务器发生错误或超时时,会尝试到下一台服务器,还有一些其他的配置项如下:

错误状态描述
error与服务器建立连接,向其传递请求或读取响应头时发生错误;
timeout在与服务器建立连接,向其传递请求或读取响应头时发生超时;
invalid_header服务器返回空的或无效的响应;
http_500服务器返回代码为500的响应;
http_502服务器返回代码为502的响应;
http_503服务器返回代码为503的响应;
http_504服务器返回代码504的响应;
http_403服务器返回代码为403的响应;
http_404服务器返回代码为404的响应;
http_429服务器返回代码为429的响应(1.11.13);
non_idempotent通常,请求与 非幂等 方法(POST,LOCK,PATCH)不传递到请求是否已被发送到上游服务器(1.9.13)的下一个服务器; 启用此选项显式允许重试此类请求;
off禁用将请求传递给下一个服务器。

配置说明 

这里面我们配置了500等错误的时候会进行重试

upstream dynamicserver {server 192.168.64.1:9001 fail_timeout=60s max_fails=3; #tomcat 1server 192.168.64.1:9002 fail_timeout=60s max_fails=3; #tomcat 2
}server {server_name www.itcast.com;default_type text/html;charset   utf-8;location ~ .*$ {index index.jsp index.html;proxy_pass http://dynamicserver;#下一节点重试的错误状态proxy_next_upstream error timeout http_500 http_502 http_503 http_504;}
}

模拟异常

在正常的情况下如果500错误会直接出现异常页面,现在我们加入了以上500重试策略,重试错误的流程和上面流程是一样的

 backup 服务器

Nginx 支持设置备用节点,当所有线上节点都异常时启用备用节点,同时备用节点也会影响到失败重试的逻辑,因此单独列出来介绍。

backup 处理逻辑

upstream 的配置中,可以通过 backup 指令来定义备用服务器,其含义如下

  1. 正常情况下,请求不会转到到 backup 服务器,包括失败重试的场景
  2. 当所有正常节点全部不可用时,backup 服务器生效,开始处理请求
  3. 一旦有正常节点恢复,就使用已经恢复的正常节点
  4. backup 服务器生效期间,不会存在所有正常节点一次性恢复的逻辑
  5. 如果全部 backup 服务器也异常,则会将所有节点一次性恢复,加入存活列表
  6. 如果全部节点(包括 backup)都异常了,则 Nginx 返回 502 错误

配置说明 

upstream dynamicserver {server 192.168.64.1:9001 fail_timeout=60s max_fails=3; #Service Aserver 192.168.64.1:9002 fail_timeout=60s max_fails=3; #Server Bserver 192.168.64.1:9003 backup; #backup
}server {server_name www.itcast.com;default_type text/html;charset   utf-8;location ~ .*$ {index index.jsp index.html;proxy_pass http://dynamicserver;#下一节点重试的错误状态proxy_next_upstream error timeout http_500 http_502 http_503 http_504;}
}

在最初始阶段,所有服务器都正常,请求会按照轮询方式依次转发给 AB 两个节点处理。当只有 A 异常的情况下,与上文没有 backup 服务器场景处理方式一致,这里就不重复介绍了。

假设在 A 的屏蔽期还没结束时,B 节点的服务也崩溃,端口不通,则会出现:

  1. 请求 1 转到 B 处理,异常,此时所有线上节点异常,会出现:

    • AB 节点一次性恢复,都重新加入存活列表
    • 请求转到 A 处理异常,再重试到 B 处理异常,两者 fails 都 +1
    • 因 AB 都异常,启用 backup 节点正常处理,并且 AB 节点一次性恢复,加入存活列表
  2. 请求 2 再依次经过 A、B 节点异常,转到 backup 处理,两者 fails 都达到 max_fails:

    • AB 节点都将会被屏蔽 60s,并且不会一次性恢复
    • backup 节点正式生效,接下来所有请求直接转到 backup 处理
    • 直到 AB 节点的屏蔽到期后,重新加入存活列表

假设 AB 的屏蔽期都还没结束时,C 节点的服务也崩溃,端口不通,则会出现

  1. 请求 1 转到 C 异常,此时所有节点(包括 backup)都异常,会出现:

    • ABC 三个节点一次性恢复,加入存活列表
    • 请求转到 A 处理异常,重试到 B 处理异常,最后重试到 C 处理异常
    • 触发 no live upstreams 报错,返回 502 错误
    • 所有节点再次一次性恢复,加入存活列表
  2. 请求 2 依次经过 AB 节点异常,重试到 C 异常,最终结果如上个步骤,返回 502 错误

 限制重试方式

默认配置是没有做重试机制进行限制的,也就是会尽可能去重试直至失败,Nginx 提供了以下两个参数来控制重试次数以及重试超时时间

  • proxy_next_upstream_tries:设置重试次数,默认 0 表示无限制,该参数包含所有请求 upstream server 的次数,包括第一次后之后所有重试之和;
  • proxy_next_upstream_timeout:设置重试最大超时时间,默认 0 表示不限制,该参数指的是第一次连接时间加上后续重试连接时间,不包含连接上节点之后的处理时间
upstream dynamicserver {server 192.168.64.1:9001 fail_timeout=60s max_fails=3; #Server Aserver 192.168.64.1:9002 fail_timeout=60s max_fails=3; #Server B
}server {server_name www.itcast.com;default_type text/html;charset   utf-8;location ~ .*$ {index index.jsp index.html;proxy_pass http://dynamicserver;# 表示重试超时时间是3sproxy_connect_timeout 3s;#表示在 6 秒内允许重试 3 次,只要超过其中任意一个设置,Nginx 会结束重试并返回客户端响应proxy_next_upstream_timeout 6s;proxy_next_upstream_tries 3;}
}

常用案例

代理静态文件

server {listen       10086;server_name  www.test.com;location / {proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_set_header X-NginX-Proxy true;proxy_redirect off;}location /data/ {alias '/usr/local/data/'; #这里是重点,就是代理这个文件夹 expires    7d;}
}

访问 http://localhost:10086/data/下面的资源就是访问/usr/local/data文件夹的资源

反向代理 

server {listen       80;server_name  www.itcast.com;;location / {proxy_pass http://127.0.0.1:8080;index  index.html index.htm .jsp;}
}

跨域配置

server {listen       80;server_name  www.itcast.com;if ( $host ~ (.*).itcast.com){set $domain $1;##记录二级域名值}#是否允许请求带有验证信息add_header Access-Control-Allow-Credentials true;#允许跨域访问的域名,可以是一个域的列表,也可以是通配符*add_header Access-Control-Allow-Origin  *;#允许脚本访问的返回头add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';#允许使用的请求方法,以逗号隔开add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';#允许自定义的头部,以逗号隔开,大小写不敏感add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';#P3P支持跨域cookie操作add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';if ($request_method = 'OPTIONS') {##OPTIONS类的请求,是跨域先验请求return 204;##204代表ok}
}

防盗链

通过Referer实现防盗链比较基础,仅可以简单实现方式资源被盗用,构造Referer的请求很容易实现

场景:由于图片链接可以跨域访问,所以图片链接往往被其他网站盗用,从而增加服务器负担;

解决方案:nginx可以通过valid_referers配置进行防盗链配置

valid_referers 指令

指定合法的来源'referer', 他决定了内置变量$invalid_referer的值,如果referer头部包含在这个合法网址里面,这个变量被设置为0,否则设置为1. 需要注意的是:这里并不区分大小写的.

  • 语法: valid_referers none | blocked | server_names | string …;
  • 配置段: server, location

配置说明

  • none : 允许没有http_refer的请求访问资源;
  • blocked : 允许不是http://开头的,不带协议的请求访问资源;
  • 192.168.0.1 : 只允许指定ip来的请求访问资源;
  • *.google.com:允许*.google.com的域名请求访问资源

 配置代码

# 需要防盗的后缀
location ~* \.(jpg|jpeg|png|gif|bmp|swf|rar|zip|doc|xls|pdf|gz|bz2|mp3|mp4|flv)$#设置过期时间expires     30d;# valid_referers 就是白名单的意思# 支持域名或ip# 允许ip 192.168.0.1 的请求# 允许域名 *.google.com 所有子域名valid_referers none blocked 192.168.0.1 *.google.com;if ($invalid_referer) {# return 403;# 盗链返回的图片,替换盗链网站所有盗链的图片rewrite ^/ https://site.com/403.jpg;}root  /usr/share/nginx/img;
}

 


http://www.mrgr.cn/p/60738131

相关文章

大模型必备 - 中文最佳向量模型 acge_text_embedding

近期,上海合合信息科技股份有限公司发布的文本向量化模型 acge_text_embedding 在中文文本向量化领域取得了重大突破,荣获 Massive Text Embedding Benchmark (MTEB) 中文榜单(C-MTEB)第一名的成绩。这一成就标志着该模型将在大模型领域的应用中发挥更加迅速和广泛的影响。…

高端制造企业生产设备文件管理,怎样保证好用不丢失文件?

高端制造业在市场经济中占据重要角色,在高端制造业企业内部,生产设备又是最关键的一环环,它们不仅负责完成生产任务,同时也会产生大量的文件。这些数据反映了设备的运行状态、生产效率、能源消耗以及产品质量等多个方面,因此做好生产设备文件管理至关重要。 设备运行数据…

使用 Meta Llama 3 构建人工智能的未来

使用 Meta Llama 3 构建人工智能的未来 现在提供 8B 和 70B 预训练和指令调整版本,以支持广泛的应用 使用 Meta AI 体验 Llama 3 我们已将 Llama 3 集成到我们的智能助手 Meta AI 中,它扩展了人们完成工作、创造和与 Meta AI 联系的方式。通过使用 Meta AI 进行编码任务和解…

【后端】PyCharm的安装指引与基础配置

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、PyCharm是什么二、PyCharm安装指引安装PyCharm社区版安装PyCharm专业版 三、配置PyCharm:四、总结 前言 随着开发语言及人工智能工具的普及&am…

可视化智慧工厂

在科技迅猛发展的今天,制造业正迎来一场深刻的变革——智慧工厂的崛起。可视化智慧工厂作为其中的重要一环,以其直观、高效、智能的特点,正成为制造业转型升级的关键所在。 一、什么是可视化智慧工厂? 传统的制造业生产方式往往依赖于人工…

机器学习/算法工程师面试题目与答案-数学基础部分

机器学习/算法工程师面试题目--数学基础部分 一、数学基础1、微积分SGD,Momentum,Adagard,Adam原理L1不可导的时候该怎么办sigmoid函数特性 2、统计学,概率论求 Max(a, b) 期望拿更长的玫瑰花的最好策略最大化工作天数的员工数切比雪夫不等式随机截成三段组成三角形…

详细谈电脑ip、域名、内网、外网、localhost、127.0.0.1、网关等通讯基础知识(易懂)

1. ip地址与域名的定义以及其关系 ip地址的定义: IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。 IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一…

如何查看eclipse版本

进入eclipse文件夹 点击readme 点击readme_eclipse.html 所跳转页面中release后的数字就是eclipse版本了 参考—— https://www.php.cn/faq/420634.html

链式栈————出栈、入栈

链式栈————出栈、入栈以链表作为基础实现栈空间(链式栈) 如果打算实现链式栈,一般是以链表作为基础,一般是把链表头部作为栈顶,方便数据的插入和删除(头插+头删),链式栈相当于是一个单向不循环的链表。链式栈要注意的点:出栈要考虑栈是否为空 入栈要考虑栈中是否有…

半导体晶圆厂内外网数据单向导出,什么样的方案才安全又便捷?

半导体晶圆厂企业为了隔绝外部⽹络有害攻击、保护⽹络和数据安全,通常采⽤物理隔离的⽅式,将企业内⽹与互联⽹隔离。⽹络隔离后,基于业务开展需求,部分重要数据仍需由内⽹导⼊及导出⾄外部⽹络区域。为保障数据的安全合规性,企业需要对⽂件导出导出⾏为进⾏管控。 不少晶圆…

打破国外垄断|暴雨发布纯血国产电脑

要说现在国产手机这边已然进入纯自研模式,但电脑这边却还是仍未打破国外技术垄断。但就在刚刚,暴雨发布自研架构台式机open Station X ,这是纯血鸿蒙系统之后国产又一款纯血产品发布!标志的我们已经彻底打破西方在硬件及软件方面的…

用斐波那契数列感受算法的神奇(21亿耗时0.2毫秒)

目录 一、回顾斐波那契数列 二、简单递归方法 (一)解决思路 (二)代码展示 (三)性能分析 三、采用递归HashMap缓存 (一)解决思路 (二)代码展示 &…

UE5 GAS开发P34 游戏效果理论

GameplayEffects Attributes(属性)和Gameplay Tags(游戏标签)分别代表游戏中实体的特性和标识。 Attributes(属性):Attributes是用来表示游戏中实体的特性或属性的值,例如生命值、…

docker - [10] 容器数据卷

1、什么是容器数据卷?2、容器数据卷的使用将应用和环境打包成一个镜像,然后发布启动就成为一个容器了。 一、什么是容器数据卷容器数据卷(Container Data Volumes)是Docker管理的一种特殊类型的存储区域,它为容器提供了一种持久化数据、共享数据以及与宿主机或其他容器之…

dial tcp 192.168.0.190:443: connect: connection refused

1、场景 用nerdctl登录镜像仓库192.168.0.190(Harbor),报错 ERRO[0006] failed to call tryLoginWithRegHost error"failed to call rh.Client.Do: Get \"https://192.168.0.190/v2/\": dial tcp 192.168.0.190:…

shell脚本文本处理工具

声明: 以下内容为个人笔记,内容不完全正确,请谨慎参考。 文本处理工具 cut: cut 工作是“剪”,具体来说就是在文件中负责剪切数据。cut 命令从文件的每个行剪切字节、字符和字段输出。 1、基本语法: cut [选项参数] filename 说明:默认分隔符是副表符 2、选项参数说明 选…

网络隔离的最小配置

作者:任云康,青云科技研发工程师前言 对于项目下的网络隔离,有用户提出了以下疑问:网络隔离是针对 Pod 的吗? 网络隔离的最小配置是什么?配置后,哪些是可以访问的,哪些是不可以访问的? 通过 Ingress 暴露、LB 类型的 Service 暴露、NodePort 类型的 Service 暴露的流量…

输入‘(’和‘)’判断字符串有效的函数算法

`// 设置一个函数,通过输入键盘中的‘(’和‘)’判断字符串是否有效 // 顺序表中的元素数据类型是char类型 typedef char DataType_t; // 创建顺序栈SequenceStack各项数据(栈底地址 栈容量 栈顶元素下标)的结构体 typedef struct SequenceStack { DataType_t *Bottom;…

ctfshow web41-web50

web41 代码审计 <?php if(isset($_POST[c])){$c $_POST[c]; if(!preg_match(/[0-9]|[a-z]|\^|\|\~|\$|\[|\]|\{|\}|\&|\-/i, $c)){eval("echo($c);");} }else{highlight_file(__FILE__); } ?> 过滤了&#xff1a;[0-9] [a-z] ^ ~ $ [ ] { } & -…

Suno:一键生成原创音乐的AI!还不赶紧体验一下?

最近一两年,AI的发展是飞速的,从AI聊天到AI绘画,再到AI视频,一次一次的刷新我们的认知,最近AI一键生成音乐也出来了。不知道大家有没有刷到过。今天盘哥就来把它分享给大家,你也可以一键生成专属于自己的音乐。01 - Suno(网站) 它就是一个可以一键生成音乐的AI网站,我…