做了「负载均衡」就可以随便加服务器了吗?

Tom发布于:2022-08-01阅读:0

不知道下面的场景是否出现在你面前:

开发Z哥对运维Y弟喊:“Y弟弟,现在系统好卡了,刚上了一波活动,赶紧帮我加几台机器顶一下。

做了「负载均衡」就可以随便加服务器了吗?

Y弟弟回答说:没问题,分分钟搞定。

然后发现数据库的压力迅速上升,DBA就吼了:“Z哥,你丫做了什么?数据库会被你弄垮。

然后客服那边的接框也爆炸了,越来越多的用户说登录后不久,操作就退出了,然后登录,又退出了,到底还是不做生意。

这些问题背后都有一个原因「Session丢失」问题。

一、什么是Session丢失

相信Session对大部分Coder每个人都应该知道。它的概念是将同一用户的多次访问识别为系统中的同一用户。此外,它还可以少重复DB或远程服务处获取与用户相关的信息,以提高性能。

如果选择的负载策略是,在我们做负载均衡的场景中hash战略,然后就会做到Session一旦用户因某种原因从原始访问服务器,就会产生副作用A成为访问服务器B,会出现登陆状态丢失、缓存穿透等问题。

为什么hash这个策略会出现吗?首先,有必要先了解它hash它是如何进行的。hash策略是下图中的散列函数。在函数不变的情况下,A永远对应01,B对应04,C对应08。

以nginx中的ip_hash以策略为例。因为我们认为用户是正常的ip不会在短时间内改变,所以当我们选择使用它时ip_hash平衡负载的策略意味着同一个用户可以一直访问同一个服务器,如下图所示hash函数是最简单的随子。

这样,我们只需要在这个服务器上缓存与用户相关的信息,就可以发挥非常比。

此时,客户端和服务端之间相当于建立了相互理解的信任。这种信任是「Session」。

然而,当我们添加服务器时,事情发生了变化hash函数是最简单的随子。

在这个时候,我们最初的预期被破坏了。由于用户与序号0节点的链接已经成为与序号3的链接,上述链接已经产生「Session丢失」问题。同时,序号0节点的缓存无效,序号3节点没有与用户相关的缓存,导致下游需要大量数据DB或远程服务办公室获取。要知道,一旦涉及到网络通信,性能必然会明显下降,I/O、序列化是一项耗时的工作。更重要的是,由于后端的原因,一旦大量用户同时发生这种情况DB和远程服务瞬时无法承载激增的高密度请求,可能会导致它挂起。这还没完,如果当前程序没有一些故障隔离或者降级策略,还会进一步产生蝴蝶效应,导致整个大系统响应缓慢。可谓“一颗老鼠屎坏了一锅粥”。

二、Nginx如何解决这个问题?

既然以nginx比如,还是从nginx开始聊天nginx中引入nginx-sticky-module模块可以解决这个问题。整个解决过程如下。

可见,当client第一次进入nginx在匹配节点时,将节点的唯一标志分配给它md5后写入到cookie如果返回,如果下次发起请求时发现有这个cookie值,直接转发到值对应的节点。该机制被专业称为「Session保持」。

虽然可以使用cookie但是cookie如果客户端没有打开,还有一个潜在的问题cookie功能,这个机制就失效了。不过好在目前主流浏览器都是默认打开cookie的。

题外话:nginx2004年发布,在nginx-sticky-module出现前七年也是如此nginx相比竞品HAProxy因为HAProxy支持Session保持。

三、Session其持其他方案

除了cookie此外,还有两种方法最终可以达到类似的效果。分别被称为「Session复制」、「Session共享」。

1、Session复制

这是最简单粗暴的方式。根据第一节的情况,问题的原因是节点3没有用户Session。所以很容易想到,在节点3运行之前Session相关的Cache复制过去的数据。并继续保证多个节点之间数据的同步,即每个用户存在于每个节点Session数据。

有很多方案可以实现,特别是不同的宿主程序或多或少提供了一些切入点,甚至可以使用,比如Tomcat的DeltaManager和BackupManager、Tomcat和IIS的Filter机制等,这里就不展开了。

该方案的特点是:

优点:自然高可用,部分节点停机。因为所有连接用户的会话信息都存储在每个节点上。

缺点:因为每台计算机的内存是有上限的,仅适用于会话相关的数据大小较小的场景。并且,由于多个节点之间需要同步数据,需要额外解决数据一致性问题。与此同时,随着节点越多,损耗越大(延迟、带宽等),有广播风暴风险。

2、Session共享

我们也可以通过将军session将信息存储到全球共享的存储介质中,以达到同样的效果,如数据库、远程缓存等,这是集中思维的解决方案。

这种方案的特点是

优点:无论节点如何增减,100%的会话都不会丢失。

缺点:每次阅读和写作请求都需要增加额外的共享存储增加网络I/O、序列化和其他操作显著降低了性能。此外,除了增加额外的维护成本外,还需要解决单一问题,以避免系统性风险。

同之前「Session保持」比较各自的优缺点和适用场景。


用一句话概括这三个方案:

  • Session保持。去哪里或去哪里。

  • Session复制。无论在哪里同的数据。

  • Session共享。所有节点共享一个数据。

系统越大,最终就会去「Session共享」这个方案,因为只要横向扩展这个共享存储,理论上就能支持无限用户Redis、一系列的NOSQL以及NEWSQL等等。就像下面这样,集「规模大」、「高可用」、「效果好」于一身。

四、结语

现在你应该知道了Session也知道如何处理丢失的问题。但是,我们还需要了解一个事实:严格来说「Session保持」本质上是破坏了「负载均衡」初衷。举个极端场景:节点有10个会话A而且都是活动中的状态。所以即使在这个时候增加一个节点B在线,只要没有新的会话,节点B活动连接总是0,不起分担压力的作用。

然而,在系统的起步阶段,使用用这么简单的方案也是极好的。(作者:Zachary;来源:Java后端技术)

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:shawn.lee@vecloud.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

本站原创内容未经允许不得转载,或转载时需注明出处:https://news.kd010.com/fwqjs/12214.html

TAG标签:负载均衡

上一篇:如何通过高防IP过滤防御DDoS攻击?
下一篇:高防CDN比高防服务器的防护效果好在哪

相关文章

返回顶部