程序员过关斩将--解决分布式session问题

微信搜一搜

架构师修行之路

session

说到 session,我相信每个程序员都不陌生,或多或少在项目中使用过。session 这个词,其实是一个抽象的概念,它不像 Cookie 那样有着明确的定义。当大多数程序员谈论 session 的时候,可能指的是服务端存储数据的 session 对象,例如,用户登录成功之后把用户信息存储在 session 中,类似于这样的程序

 Session["UserName"] = new User();public class User{public int UserId {get ;set ;}public string UserName {get ;set;}}

而在计算机中,尤其是网络应用中,session 被定义为“会话”,可以把它看做客户端和服务端的一条通道连接,同一个用户的请求使用同一个 session 会话。在大多数应用中,主要用于用户的识别,通俗来讲,服务端可以通过 session 来记录每一个用户的状态信息。那我们就以最常用的服务端 session 对象来啰嗦几句

单机 session

session 是存储在服务端的,这是一个很重要的概念。这意味着它需要占用服务器的内存,并且它需要一种释放的机制来保证服务器内存不会被撑爆(例如 LRU)。

在项目初期,为了快速上线,服务器的部署很多情况下只有一台服务器,记录用户的登录状态普遍使用 session 机制。请不要说这样做不合理,至少在项目初期这种做法是最简单而且最快速的方案。随着项目的不断迭代升级,用户量的不断增加,你会发现单机系统成为了项目的最大性能瓶颈,这个时候多数架构师会选择水平扩展方案。

其实说到底,系统性能的提升都围绕着一个“分”字,无论是数据库的分库分表,还是现在兴起的微服务,始终在围绕着一个领域进行切分

当单机的 session 机制进行水平扩展就面临着必须要要解决的问题:session 的亲和性(粘性)要怎么样去解决?

分布式 session

一个单机系统扩展为一个分布式系统,就会面临着分布式 CAP 理论中 AP 和 CP 的选择,具体可以查看之前的文章:

晦涩难懂的 CAP,是否完全正确?

谈到分布式 session 的一致性问题,其实主要是要解决用户 session 的亲和性,同一个用户的请求怎么样才能保证到达正确存储 session 信息的服务器呢?

session 复制

最初的方案是采用 session 复制方案,整体的流程非常简单:假设现在有三台服务器,当一个 session 在其中一台服务器上被创建,则同时把这个 session 复制到其他两台服务器上。这样当用户的请求无论到达哪台服务器,都会有相应的 session 数据。

这种方案的优势在于服务器可以任意水平扩展,每个服务器都保留着所有的 session 信息,当加入一台服务器只需要把所有的 session 信息复制过去即可。但是劣势更加明显

  • 每个服务器上都保存着全部的 session 信息,服务器占用的资源大大增加。

  • session 同步需要占用网络带宽,最重要的是如果采用的异步复制方式,数据会有短暂性的不一致,可能会导致用户访问失败。

session 复制的方案现在已经很少有人使用了

负载均衡方案

当一台服务器扩展为多台服务器,目前最常用的方案是在流量的入口添加负载均衡器,大体的部署图是这样的

image

如果负载均衡器能够利用某种手段来实现 session 的粘性就能实现分布式 session。目前主流的 nginx 可以根据“hash_ip”算法将同一个 IP 的请求固定到某台服务器,这样来自于同一个 ip 的 session 请求总是请求到同样的服务器。

这种方式比 session 同步方式要好很多,每台服务器只存储对应的 session 数据,这大大节省了内存资源,而且服务器之间没有数据同步过程。当有新服务器加入的时候,只需要修改负载均衡器的配置即可,这样很方便就支持了服务器水平扩展。但是,同时也面临着一些不足

  • 服务器重启意味着对应的 session 信息丢失,这在一些重要的业务场景中是不允许的

  • 服务器的水平扩展需要修改负载均衡器的配置,修改之后可能会导致之前的 session 重新分布,这样会导致一部分用户路由不到正确的 session

session 剥离

现在应用更广泛的分布式 session 技术是把 session 数据彻底从业务服务器中剥离,单独存储在其他外部设备中,而这些外部设备可以采用主备或者主从,甚至集群的模式来达到高可用。比如现在最常用的方案是把 session 数据存储在 redis 中,虽然从 redis 读写 session 数据需要花费一定的网络耗时,但是对于一般的应用来说在可以接受范围之内。

这种方案好处是整体架构更加清晰,也更加灵活,应用的服务器整体扩展能力再也不用考虑 session 的影响,而 session 的问题被转移到外部设备,通常可以利用内存性 NOSql 来解决性能问题,而这些外部设备一般都会有对应的分布式集群方案,例如 redis,可以利用主从或者哨兵模式甚至集群来提供更大规模的数据支撑能力。

image
Actor 模型

很少有人会提及 Actor 模型,我在之前的文章中介绍过 actor 模型,大家可以去看一下

分布式高并发下 Actor 模型如此优秀

Actor 模型解决这种用户粘性问题会更加优雅,它天生就自带了对象识别功能,简单来说,同一个 key 的请求,总能到达正确的 actor 实例,这不是我们想要的结果吗?而且 actor 模型下不用加锁就能处理并发问题,为什么没人用呢?而且采用 acotr 模型就可以利用进程内缓存的形式,比请求局域网 redis 的网络延迟要低很多。

写在最后

当然如果只是针对用户登录这个应用场景,session 方案并不是唯一的解决方案,可以参考菜菜之前的文章

程序员过关斩将--更加优雅的 Token 认证方式 JWT

END

●程序员修神之路--为什么我会了SOA,你们还要逼我学微服务?

●程序员过关斩将--数据库的乐观锁和悲观锁并非真实的锁

●程序员修神之路--设计一套RPC框架并非易事

●程序员过关斩将--要想获取我的用户信息,就得按照规矩来

●程序员过关斩将--更加优雅的Token认证方式JWT

●程序员过关斩将--cookie和session的关系其实很简单

●程序员修神之路--用NOSql给高并发系统加速

●程序员修神之路--高并发系统设计负载均衡架构

●程序员过关斩将--你为什么还在用存储过程?

●程序员修神之路--问世间异步为何物?

●程序员修神之路--提高网站的吞吐

长按添加菜菜好友

关注后回复:“大礼包”和“福利”,领取惊喜

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何将nodejs项目程序部署到阿里云服务器上

将nodejs项目程序部署到阿里云服务器上一、概述二、具体步骤1、拥有自己的服务器2、下载Xshell3、 oneinstack配置web环境4、 XShell连接远程主机5、更新系统软件6、在服务器上安装node环境7、部署项目到服务器上8、安装pm2并启动nodejs项目三、快捷指令1、linux的常用命令2、p…

101. 对称二叉树023(BFS)

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullpt…

中移动完成透镜天线远距覆盖和降本增效试点

日前,中国移动研究院在官微上正式发布了《新型透镜天线进行首次高铁覆盖实验》一文。中国移动研究院、中国移动甘肃公司与西安海天天线科技股份有限公司联合开展的人工介质圆柱透镜天线在高铁、高速等线状纵深领域的长距覆盖取得突破性进展。两年以来,铁…

基于PHPEnv的本地环境搭建—PHP第一个项目:HelloWorld(从安装到运行)

1、安装软件 编程工具:Notepad 运行环境:phpEnv 2、用phpEnv建立本地运行环境 (1)官方下载phpEnv,运行phpEnv,启动服务。服务启动之后,apache和mysql变绿。如下图所示: &#xff0…

在idae中为什么用Module创建一个新的Maven项目的时候会被卡死

一:问题描述 然后就会卡死, 二:问题解决 我们会发现这里的路径是有问题的,idea自带的maven会卡死我们,因为下载jar包的速度慢的惊人 将其改为我们自己maven路径,下载速度会很快,便不会出现卡死的现象&a…

ASP.NET Core Blazor Webassembly 之 数据绑定

上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件)。这次继续学习Blazor的数据绑定相关的知识。当代前端框架都离不开数据绑定技术。数据绑定技术以数据为主导来驱动UI界面,用户对数据的修改会实时提现在UI上&a…

PHP做二次开发:本机安装ThinkCMF系统

使用工具:phpEnv、TortoiseGit 具体步骤: 1.获取thinkcmf源代码 2.修改Hosts文件设置虚拟域名指向本机 3.配置apache建立本地站点 4.建立数据库 5.访问本地站点开始安装 第一步:获取thinkcmf源代码 1.打开浏览器访问gitee.com,搜…

107. 二叉树的层序遍历 II and 102. 二叉树的层序遍历 023(BFS模板题打两道)

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullpt…

PHP做二次开发:ThinkCMF门户应用安装

使用工具:phpEnv 具体步骤: 1.获取门户应用portal源码 2.安装portal代码 3.执行portal数据库文件 4.安装并启用前台模板 5.导入后台管理菜单 第一步:获取门户应用portal源码 1.打开官方网站http://kancloud.cn/thinkcmf/faq/1005840&#xf…

vector的逆序输出(神奇的vector)

一&#xff1a;直接上代码&#xff08;逆序输出&#xff09; #include<bits/stdc.h> using namespace std; int main(){vector<int> v;for(int i 0; i < 5; i){v.push_back(i); }reverse(v.begin(),v.end());for(int i 0; i < 5; i){cout << v[i] &…

初识ABP vNext(6):vue+ABP实现国际化

点击上方蓝字"小黑在哪里"关注我吧语言选项语言切换注意前言上一篇介绍了ABP扩展实体&#xff0c;并且在前端部分新增了身份认证管理和租户管理的菜单&#xff0c;在实现这两个功能模块前&#xff0c;先来解决一下界面文字国际化的问题。开始国际化&#xff08;简称 …

『软件工程1』详解软件是什么

软件基本概念一、什么是产品二、软件的双重角色三、软件的涵义及特征四、软件应用五、软件危机六、软件神话一、什么是产品 1、从用户的角度 产品实际上就是信息&#xff0c;以某种方式使得用户世界更加美好 2、从软件工程师的角度 产品实际上就是软件 二、软件的双重角色 1…

200. 岛屿数量025(BFS详解)

二&#xff1a;思路 1.这里我们使用的是BFS(广度优先搜索遍历) 2.当我们遇到一个岛屿&#xff08;‘1’&#xff09;的时候&#xff0c;我们就对其的左右四边进行广度遍历 并且标记已经访问过的结点。 3.那么我们每次遇到一个1开始广度遍历那就证明我们发现了一个岛 三:上码 …

进击吧! Blazor 第一期

Blazor 是一个 Web UI 框架&#xff0c;可通过 WebAssembly 在任意浏览器中运行 .Net 。Blazor 旨在简化快速的单页面 .Net 浏览器应用的构建过程&#xff0c;它虽然使用了诸如 CSS 和 HTML 之类的 Web 技术&#xff0c;但它使用 C&#xff03;语言和 Razor 语法代替 JavaScrip…

『软件工程2』详解软件工程和软件过程模型

文章目录一、软件工程的定义1、Fritz Bauer在NATO上给出的定义2、Barry Boehm3、IEEE在软件工程术语汇编中的定义二、软件工程的层次1、软件工程三个要素2、软件工程的层次——图解3、软件工程的层次——逐一分析三、软件过程的三个阶段1、定义阶段——“做什么”2、开发阶段—…

利用vector实现一对一(pair<int,int>)

一&#xff1a;前言 我们知道有一对一的STL容器有map容器&#xff0c;但是map容器中的按键值排序和不允许由重复的元素&#xff0c;现在&#xff0c;我们可以利用 vector<pair<int,int> >来实现一对一&#xff0c;但其没有排序可以允许有重复的元素 二&#xff1…

没有docker,谈什么微服务架构?

新的互联网技术时代已经来临了&#xff0c;容器、Kubernetes、DevOps、微服务、云原生代表着技术前进的方向&#xff0c;.NET Core微服务Docker&#xff0c;亦是当下最优解决方案(低调点&#xff0c;几乎没有之一)&#xff01;有点自夸&#xff1f;作为专注于.NET领域十多年的老…

『软件工程3』你应该知道的三种原型实现模型:抛弃式、演化式、增量式

三种原型实现模型一、抛弃式原型开发二、演化式原型开发三、增量式原型开发一、抛弃式原型开发 1、定义&#xff1a;验证和澄清系统的需求描述&#xff0c;重新构造系统。 2、流程图 3、典型例子 开发者与客户进行沟通交流&#xff0c;之后获取到客户的需求&#xff0c;于是…

『软件工程4』一文了解软件项目管理中的4P

软件项目管理中的4P一、项目管理的重要性和定义1、重要性&#xff08;两个阶段&#xff09;2、软件项目管理的定义二、管理四要素4P1、管理的四要素(4P)2、软件项目中影响最终结果的要素3、项目管理关心的问题三、项目参与者类型(people)四、项目小组结构(people)1、项目的三种…

8-1 回溯法实验报告 (15 分)(思路+详解)

一&#xff1a;题目 给定k个正整数&#xff0c;用算术运算符&#xff0c;-&#xff0c;&#xff0c;/ 将这k个正整数连接起来&#xff0c;是最终的得数恰为m。 如果有多组满足要求的表达式&#xff0c;只要输出一组&#xff0c;每一步算式用分号隔开。 如果无法得到m&#xff…