状态管理系统设计文档
一、用户登录流程
状态管理示意图
说明:
1. 浏览器提交登陆请求Form到登陆服务器( login.cnblogs.com )
2. 登陆成功后,login.cnblogs.com结果页面将设置cnblogs.com域的cookies,并跳转到应用指定的页面
3. 随后应用系统可以根据cookies,去状态服务器获得当前用户的登陆状态
二、状态管理系统的必要性和此系统优点
1. 整站一次登陆,规范清晰安全;
2. 无Web服务器状态,极大方便负载均衡实施;
3. 硬件设置要支持服务器sticky总是比较麻烦,而且带来性能损失。有了独立的登陆系统后,所有WebServer都是一致的可以方便的做均衡;
4. 提供标准接口给各应用系统,方便各应用系统开发目前没有登陆规范,靠明码cookies来跨系统实现登陆,极其不安全!各系统开发也复杂;
5. 状态服务器很容易扩充通过自己算法,可以把状态保存到多个不同服务器来分担负载,而且即使某台服务器出问题,只要立刻有备份机也不会造成太大影响。
三、提供给应用系统的接口
1、Asp函数接口
1、1 文件
a) ILogin.asp
asp状态管理接口类clsStateManager的定义,包含接口函数SetSessionValue(name,value)和GetSessionValue(name),此函数基本上完全对应原先的Session操作,这样可以直接很方便地替换原先的Session。
b) ILogin_Config.asp
是状态管理接口的配置文件,包含是数据库的连接字符串的配置。
1、2 函数
a) Function SetSessionValue(name,value)
功 能: | 设置当前登陆用户某个状态字段的值 |
参数说明: | name 键值名 value 对应的值,支持以下四种,Integer、Long、String、Boolean类型 |
返 回 值: | 0 ---- 设置成功 -1 ---- 设置的值,超出了该字段规定的长度 -2 ----- 更新失败 -3 ----- 主键不能更新 -4 ---- 用户没有登录 -5 ---- 该value的类型不支持 |
注 意: | 使用该函数,必须判断返回值,已确定是否成功设置,或者得到相应的错误信息,已供处理。目前value的类型支持以下四种,Integer、Long、String、Boolean Name和value 不要使用冒号(:)和逗号(,) |
用 法: | 1、需要返回值 Dim result Result = glbFunc.SetSessionValue(name,value) 2、不需要返回值 Call glbFunc.SetSessionValue(name,value) 或者 glbFunc.SetSessionValue name, value |
b) Function GetSessionValue(name)
功 能: | 获得当前登陆用户某个状态字段的值 |
参数说明: | Name 键值名称 |
返 回 值: | 该键值名对应的值 |
注 意: | 如果输入的name在该Cookie对应的数据库没有,则返回Empty |
用 法: | Dim sessionValue sessionValue = glbFunc.GetSessionValue(name) |
2、.NET 接口
2、1 文件
CnBlogs.StateManager.dll动态库文件。该dll包含了StateManager类,主要的接口包含SetSessionValue、GetSessionValue和RemoveSession。
注意:
必须在call该dll的应用程序的web.config文件中定义StateManagerConnectionString为Key的状态管理数据库的连接字符串。
如:
<configuration>
<!-- application specific settings -->
<appSettings>
<add key="StateManagerConnectionString" value="database=SessionDB;server=192.168.0.29;Integrated Security=false;User ID=sa;Password=;" />
</appSettings>
</configuration>
引用方法:using CnBlogs.StateManager;
StateManager sm = new StateManager();
2、2 函数
a) SetSessionValue(string name, object value)
功 能: | 设置当前登陆用户某个状态字段的值 |
参数说明: | name 键值名,string类型 value 对应的值,object类型 支持以下四种,Integer、Long、String、Boolean类型 |
返 回 值: | 0 ---- 设置成功 -1 ---- 设置的值,超出了该字段规定的长度 -2 ----- 更新失败 -3 ----- 主键不能更新 -4 ---- 用户没有登录 -5 ---- 该value的类型不支持 |
注 意: | 使用该函数,必须判断返回值,已确定是否成功设置,或者得到相应的错误信息,已供处理。目前value的类型支持以下四种,Integer、Long、String、Boolean Name和value 不要使用冒号(:)和逗号(,) |
用 法: | 1、需要返回值 int result = null; Result = sm.SetSessionValue(name,value); 2、不需要返回值 Sm.SetSessionValue(name, value); |
b) GetSessionValue(string name)
功 能: | 获得当前登陆用户某个状态字段的值 |
参数说明: | Name 键值名称 |
返 回 值: | 该键值名对应的值 |
注 意: | 如果输入的name在该Cookie对应的数据库没有,则返回null |
用 法: | Object sessionValue = null; sessionValue = sm.GetSessionValue(name) |
四、实现细节
状态管理示意图是状态服务器在生产环境中基本结构。所有的存取用户状态信息,都通过主状态服务器,有他的存储过程p_getlinkstr根据登陆的ID来负载均衡地分配具体信息存取在哪台从状态服务器。
所有状态服务器上存储过程包含主从两套,一旦主服务器崩了,则可以通过修改配置文件指定到任何一台从服务器上,把她作为主服务器,并且修改p_getlinkstr存储过程,即能恢复。
万一从服务器崩了,只需修改一下主服务器中的p_getlinkstr存储过程,把崩掉的从服务器连接字符串禁用,指向该机器的余数分配到其他任何一台服务器即可。
如果,各服务器压力很大,可以通过增加从服务器数量的方式或者改善主服务器的性能来减轻。
1、Cookies
随机生成一个整数,加上登陆用户的整数ID作为唯一的key
Cookies格式:
内容:Cnblogssession=NNNN,MMMM
过期:自动登陆时,设过期时间为1月;否则不设置过期时间
domain=cnblogs.com
如果当前请求域名为cnblogs.com后缀,否则不设置域,这样保证直接用IP也可登陆
其中NNNN为用户整数ID,MMMM为随机key
提供给前台JS使用的登陆信息
这样方便前台显示,但此部分信息不作为后台凭证。
包括:用户登陆名,呢称,默认blogname,当前登陆状态
2、表结构设计
表名称:U_Session
字段名 | 名称 | 类型 | 说明 |
UserId | 用户整数ID | Int | 主键 |
RId | 随机整数ID | Int | 主键 |
LastUpdateDate | 最后访问时间 | Datatime | |
IsAutoLogin | 是否自动登陆 | Char(1) | 记住该浏览器 |
UId | 注册ID | Nvarchar(100) | |
NickName | 用户昵称 | Nvarchar(100) | |
LoveSex | 性别 | Char(1) | |
CurrentBlogname | 默认的blogname | Nvarchar(50) | |
CurrentBlogId | 默认的blogid | int | |
OtherParams | 其他字符参数 | Varchar(1000) | 需要保存到session中的 建议轻易不要使用 |
3、存储过程
3、1 用户登录
P_UserLogin @LoginName varchar(100), @LoginPWD varchar(50), @LoginIP varchar(15), @Password varchar(50)
功能:用户登陆,包括检查用户合法性,设置默认的用户状态属性
参数: LoginName 登陆名
LoginPWD MD5后的密码
LoginIP 登陆时,用户IP
Password 用户输入的密码
返回值:0 成功
-1 用户被锁定
-2 密码不符
-3 用户不存在
注意:成功返回后,选择出需要设置的Cookie,供登陆函数设置。
3、2 设置状态
P_SetSessionState @UserId int, @RId int, @ParamName varchar(50), @ParamValue varchar(1000), @ParamType varchar(10), @ReturnValue int output
功能:设置用户状态值
参数: UserId 用户ID
RId 随机八位数字 –
ParamName 状态名称
ParamValue 状态对应的值
ParamType 状态值对应的类型
ReturnValue 返回值
返回值: 0 -- 成功更新
-1 -- 超出字段最大长度
-2 -- 失败
-3 -- 主健或者保留字段不能更新
3、3 获得状态
P_GetSessionState @UserId int,@RId int
功能:获取用户状态值
参数: UserId 用户ID
RId 随机八位数字
返回值:用户所有的状态值
3、4 得到连接字符串
p_getlinkstr @UserID int, @returnstr nvarchar(50) output
功能:获取用户连接字符串
参数: UserId 用户ID
返回值:用户对应的连接字符串
注意:该存储过程需要配置,状态数据库的负载均衡就是在此进行分配。
4、数据库定时Job
ClearOverdueStateSession
功能:定时清除U_Session表中过期的Session记录。