应用服务器采用集群之后, 需要使用应用服务的无状态特性, 即应用服务器不能保存上下文信息, 包括session。 本文将简单介绍下 session 管理方案。
目前, session管理,有四种方法
1. session复制
需要专门的同步进程, 同步集群中的应用服务器对象。
这种方法比较简单, 从本地读取session也比较快,但是集群较大时, 会占用较多服务器和网络资源。
2. session绑定
通过负载均衡的源地址hash算法, 将源ip的请求,总是发送到固定的应用服务器。
但是, 这种方法不能满足系统高可用, 如果一台应用服务器宕机之后, 用户转发到其它应用服务器时, 其session将丢失。
3. cookie记录session
cookie方式将session信息保存在客户端,这种方式虽然简单易用且能降低应用服务器负载,但是缺点较多:受cookie大小限制;需要客户端浏览器支持cookie;每次请求需要传递cookie,增加网络负担;安全性问题。
4. session服务器
采用独立服务器, 使用文件、数据库或缓存系统来管理session, 实现session在应用服务器间的共享。 这种方式满足可伸缩(可集群化)、高可用(建立session服务器集群),性能也不错。
作者项目采用redis集群来做session服务器, 改造工作也很简单。
1. 运维搭建redis集群 (这个就不作讲解了)
2. 应用服务代码改造
php层面
两种方式,一是通过代码实现session数据的 redis 读和写; 另一种是通过php原生支持实现,不需要改动代码,其方法是
在php.ini中添加配置:
session.save_handler = redis
session.save_path = "tcp://redis.xxx.com:6379"
或者,在php代码使用session时, 加两行代码:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://redis.xxx.com:6379');
asp层面
和php类似, 有两种方式,一是通过代码实现session数据的 redis 读和写; 另一种是通过asp的sessionState实现,辅助组件:https://github.com/TheCloudlessSky/Harbour.RedisSessionStateStore
可见这种session集中管理的方案是简单易行的。
附 session 管理方案网络结构简图: