《分布式登录系统逐步实现》系列文章,有兴趣可以持续关注。
转发请说明来源。
单服务器会话
此模式应该是最常见的会话模式了,只有一台机器进行服务。大多数服务语言都有自带的基础Session服务库,提供本机器内的 Session 读写。
PHP Session
这里用PHP Session Functions做为例子,此模块封装了一系列对会话信息处理的流程,默认以文件作为 Session 会话信息的存储载体。里面最具有代表性就是函数就是:session_start。此函数用作初始化当前会话信息。
session_start 原理(文件方式)
字段简述:
- PHPSESSID 为 PHP 默认 cookie 标识会话的键名。
- SESS_ 为 PHP Session 信息存储文件默认前缀。
- R 为随机字符串
- $_SESSION 为Session信息全局变量
相关流程:
- 读取名为 PHPSESSID 的 cookie 值,假使为 X
- 若读取到 PHPSESSID 这个 COOKIE,创建 $_SESSION 变量,并从相应的目录中(目录可配置)读取 SESS_X 文件,将字符装在入 $_SESSION 变量中;
- 若没有读取到 PHPSESSID 这个 COOKIE,也会创建 $_SESSION 变量,同时创建一个 SESS_R 的session文件,同时将 SESS_R 作为 PHPSESSID 的cookie 值返回给浏览器端。
这个流程具有通用性,可以根据不用的业务需求采用不同的 Session 读写策略,包括使用更加安全更加少冲突的 session_id 和 读写性能更高的存储服务(如:redis、memcached)。
跨服务器会话
当整体系统业务开始繁忙,单服务器已经满足不了当前的整体系统业务,需要用多台机器部署同一份代码提供服务。
此时,不能再用上面本机存储 Session 信息的解决方案。
这是由于:
同一套整体系统代码部署多机器的时候,由于每台机器自己的会话信息是相互独立的,用户在 机器A 登录之后,在机器B 通过 Cookie 中的 session_id 读取不到相应 Session 信息,所以会产生需要用户多次登录的异常情况。
此时需要寻求一个更好的方法。
共用 Session 存储服务
由于不同服务器的之间存储空间在逻辑上是独立的,所以需要有一个共用的存储会话信息的服务器去对会话信息进行读写。
此处可以根据业务需求,选用不同的会话存储服务如:
性能低、高可用:mysql
性能高、低可用:memcached、memcache
性能高、高可用:codis、couchbase
由于 Session 读写非常频繁,而且要求读性能比较高,所以基本不会用 mysql 用作会话信息存储服务。
但本系列后续会根据 mysql 作为存储服务,完全用 PHP 实现一个简单的 Session 模块。
memcached(举个例子)
在 PHP 当中可以把 session 的存储处理从默认的文件读写模式转为 memcached 读写。从而实现会话服务共享。
当然,需要安装 memcached 服务。
案例配置如下(php.ini):
session.save_handler = memcached
session.save_path = "10.1.1.1:11211"
跨业务会话
当一个系统大到一定程度的时候,很自然的会产生业务拆分。例如淘宝,会拆分成,支付业务,订单业务,商品业务,用户登录业务等等。
此时跟跨机器会话类似,会有一个多机器共享的会话存储服务。但是对于会话信息的读写权限针对于业务的不同会有所不同。
用户登录业务:
拥有读写权限,专门处理用户登录账号密码验证模块,成功则写入公用会话信息。
其他业务:
一般只拥有只读权限,根据 cookie 从会话服务读取当前账号登陆会话信息,去进行一些操作。