12cd.com 开发分享--跨域问题,用户在线统计,跟踪
12cd使用了很多的二级域名,类似javaeye的频道栏目。在tomcat6.0下跨域会造成session丢失。当时也没找到tomcat哪里可以设置session cookies地方。
所以就自己设计了一套解决方案。
12cd目前前端使用的是Apache2,应用服务器是tomcat6.0. Apache2 主要提供虚拟主机以及负载均衡的作用,通讯使用的是AJP.
下面介绍一下实现步骤:
1 建立一张onlineusers内存表
CREATE TABLE `onlineusers` (
`id` bigint(20) NOT NULL, `operations` varchar(600) DEFAULT NULL, `last_active_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `login_time` timestamp NULL DEFAULT NULL, `s_sessionId` varchar(80) DEFAULT NULL, `s_ramdon` varchar(80) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MEMORY DEFAULT CHARSET=gbk CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC
id 存的使用户表id
last_active_time 记录用户最后一次操作时间
s_ramdon 这个存储是随机产生的32位字符串。后面会有用途。
2 当用户进行登录操作时
验证完成后写入一个cookie,内容包括用户ID,用户名,用户密码,以及一个随机产生的32位字符串A,用一定的形式组织后加密。
接着往onlineusers表插入相应的记录。其中s_ramdon 保存的刚才那个字符串A。
3 提供一个filter
当用户在做操作的时候,比如访问用户中心的时候,filter会做一下工作:
- filter检查用户的cookie以及onlineusers,如果缺少两个中的任何一个记录,我们就判定用户没有登录,清空相关记录,删除session中uid属性。
- 假设存在相关cookie和onlineusers表的记录,对他们进行比对。
- 对比不一致(比如有人篡改cookie等) 清除cookie以及onlineusers相关记录,删除session中uid属性
- 符合条件后,我们判断用户的session是否有uid属性,如果没有我们为他设置uid属性,并更新onlinusers 的last_active_time 字段。
- 之后所有的流程不变,根据session中是否包含uid判断用户是否登录以及是否允许相关操作
4 后台提供一个必要的定时器
我们后台有个定时器,定期清除onlineusers表中超过半小时内没有任何更新的记录,并且删除用户相应的cookie,清空session.
这就相当与用户session失效登出
Ok 工作就这么多。看看这种方案给我们带来了那些好处
- 已经可以做到跨二级域名了。因为我们cookie的domain是设置到根域下的.12cd.com
- 轻松统计在线用户 只要简单查询 onlinusers表即可。我们网站有个功能就是可以查看到到空间留言的人的性别和是否现在在线就是通过查询onlineusers表实现的
- 还有一个比较有趣的增值功能是实现了集群和无中断更新部署。这个我们在下一篇文章中会提到
另外javaeye提供了用户正在做什么的功能。12cd 也有类似的功能。曾经咨询过robbin javaeye是如何实现,robbin 说是通过内存表记录用户的url来进行判断的。12cd则主要是通过Hibenrate的interceptor回调来实现。比如对日记有 保存操作,那就说明用户正在写日记。这个是题外话了