内容简介:本文长度为
如果这是第二次看到我的文章,欢迎点击上方 ▲蓝字 关注我哟~
本文长度为 3056字 ,预计读完需 1.1MB 流量,建议阅读 8 分钟。
这篇是《分布式关注点系列》中负载均衡相关的内容最后一发了,后续也会继续讲高可用相关的其它主题,主要是限流、降级、熔断之类的吧,具体还没定。文末先附上之前发过的高可用相关文章,供你再温故一下。
下面这个场景不知是否在你面前出现过。
开发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的。
题外话 :nginx是2004年发布的,在nginx-sticky-module出现之前的7年间也是nginx相比竞品HAProxy最大的一个短板,因为HAProxy支持Session保持。
三、Session保持的其它方案
除了cookie之外,还有2种方式也可以最终达到类似的效果。分别被称为「Session复制」、「Session共享」。
01
Session复制
这是最简单粗暴的方式。根据第一节的案例来看,导致问题的原因是节点3没有用户的Session。那么很容易想到,在节点3运行之前把Session相关的Cache数据复制过去呗。并且在多个节点之间持续保证数据的同步,也就是说,每一台节点上都存在每个用户的Session数据。
实现的方案有很多,特别是不同的宿主程序都或多或少提供了一些切入点,甚至是拿来即用的方案,如Tomcat的 Delta Manager和Backup Manager 、Tomcat和IIS的Filter机制等等,这里就不展开了。
此类方案的特点是
-
优点:天然高可用,一部分节点宕机没事。因为每一个节点上存放着所有已连接用户的会话信息。
-
缺点:因为每台计算机的内存是有上限的,仅适用于会话相关的数据大小较小的场景。并且,由于多个节点之间需要同步数据,需要额外解决数据一致性问题。与此同时,随着节点越多,损耗越大(延迟、带宽等),有广播风暴风险。
02
Session共享
我们还可以通过将session信息存放到全局共享的存储介质中来达到一样的效果,如数据库、远程缓存等,这是一种中心化思想的解决方案。
此类方案的特点是
-
优点:不管节点怎么增加和减少,100%不会产生会话丢失。
-
缺点:每次读写请求都需要增加额外共享储存调用,增加了网络I/O、序列化等操作,性能明显下降。另外,用作共享的存储介质除了增加了额外的维护成本外,还需要解决单点问题,以免产生系统性风险。
同之前「Session保持」方案一起对比下各自的优缺点和适用场景。
▲点击图片可查看大图
分别用一句话概括一下这3个方案:
-
Session 保持。原来在哪还是去哪。
-
Session 复制。不管在哪都有一样的数据。
-
Session 共享。所有节点共用一份数据。
越大型的系统,最终都会往「Session共享」这个方案上走,因为只要再对这个共享存储做横向扩展,理论上就可以支撑无穷大的用户了。如 Redis 、一系列的NOSQL以及NEWSQL等。就像下面这样,集「规模大」、「高可用」、「效果好」于一身。
▲点击图片可查看大图
四、结语
现在你应该清楚了Session丢失问题,也知道了如何去应对他。但是,我们还需要明白一个事实: 严格来说「Session保持」本质上是破坏了做「负载均衡」的初衷 。举个极端点的场景:一共有10个会话连在了节点A上,并且都是活动中状态。那么这个时候哪怕增加一个节点B上线,只要没有新的会话进来,节点B上的活动连接数永远是0,并没有起到分担压力的作用。
但是,在系统的起步时期,其实用这样简单的方案也是极好的。
Quesion :
你在工作中有遇到过哪些由于Session丢失产生的奇葩现象呢?欢迎分享给大家一起吐槽和讨论。
相关文章:
- 感谢阅读 -
如果觉得文章有帮助,
送我一个星标鼓励一下吧 。
操作步骤已经给你准备好了,看这里 ↓
喜欢
分享
or
▶ 关于作者:张帆(Zachary)。坚持用心打磨每一篇高质量原创。本文首发于公众号:「 跨界架构师」 (ID:Zachary_ZF)。
如果你有关于软件架构、分布式系统、产品、运营的困惑
可以试试点击「 阅读原文 」
也可以读读这些文章 :point_down:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 分布式系统关注点:弹性架构
- 分布式系统关注点:初识高可用
- 分布式系统关注点:“无状态” 详解
- 分布式系统关注点——“无状态”详解
- 分布式系统关注点:“共识” 的兄弟 “事务”
- 分布式系统关注点:如何去实施负载均衡?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Clojure编程
Chas Emerick、Brian Carper、Christophe Grand / 徐明明、杨寿勋 / 电子工业出版社 / 2013-3-26 / 99.00元
Clojure是一种实用的通用语言,它是传奇语言LISP的方言,可与Ruby、Python等动态语言相媲美,更以无缝Java库、服务,以及拥有JVM系统得天独厚的资源优势而胜出。本书既可以用来熟悉Clojure基础知识与常见例子,也可了解其相关的实践领域与话题,更可以看到这一JVM平台上的LISP如何帮助消除不必要的复杂性,为大家在编程实践中解决最具挑战性的问题开辟新的选择——更具灵活性,更适于W......一起来看看 《Clojure编程》 这本书的介绍吧!
html转js在线工具
html转js在线工具
RGB CMYK 转换工具
RGB CMYK 互转工具