session失效怎么解决(session失败)
App偶尔丢失session
App偶尔丢失session的话,当刷新间隔超过session.gc_maxlifetime指定的时间间隔(秒)时,session失效就是正常的事情。
我们经常会做到的一个功能,将登录用户信息保存到session中,在页面上显示登录用户名。但是,如果很短时间内甚至几秒没有刷新这个页面的话,这个用户名就消失了,其实就是session中保存的用户数据丢失了。找到问题所在,那怎么解决呢?答案就是可以将Session存储在进程外。
StateServer模式:
这种模式下Session会被保存在Asp.Net进程之外的aspnet_state.exe进程中,这个进程不受asp.net进程回收的影响。但要注意:aspnet_state是以windows服务形式运行的,所以请先确保127.0.0.1对应的机器上该服务已经启动(ASP.NETStateService服务)。另外如果tcpip=127.0.0.1:42424中的IP地址指定为另外一台服务器,意味着可以将session保存在web服务器以外的机器上
机器Session总是过期 怎么解决?
希望以下方法能帮到你:
问题存在的可能性:
第一,如果客户端不允许cookie操作,session将失效。因为session是依赖于cookie的。
第二,session有失效时间的设定。缺省的设置是20分钟。你可以这样修改它:Web
directory
-
Properties
-
Virtual
directory
-
Application
settings
-
Configuration
-
App
Options
-
Session
timeout
或者在ASP中,写上这样的代码:Session.timeout=60
。
第三,session是和具体的Web
Application相关的。如果用户从/products/default.asp浏览到/jobs/default.asp,也可能造成session的重新创建。
怎么清除一个不再需要的session变量但不使session失效?
在ASP3.0中:
Session.Contents.Remove
"变量名"
可以清除一个变量。
在ASP2.0中:
set
session("变量名")=NULL
可以清除变量。
在ASP3.0中,
Session.Contents.RemoveAll
可以清除所有的session变量和session.abandon不同,上面的方法都不会使目前的session过期或者无效。
redisson-tomcat会话共享之session失效BUG排查
使用redisson-tomcat很简单,只需要两个步骤:
在tomcat/conf/context.xml增加配置:
(rv表示redisson的版本号,tv表示tomcat的版本号)
参考
运维伙伴配置好负载均衡后(集群环境,一台一台发布,发布前剔除负载,发布后加入负载),我便开始测试。
一开始正常,但多次调试后,偶尔会出现session失效的问题,再次多次尝试后找到了session失效的触发条件:
第一次切换负载时,能正常访问,但第二次切换负载时,session会失效。
由于tomcat上层有slb做负载均衡、nginx做反向代理,首先得排查是不是它们引起的问题。
但这很难,于是我换了个思路,绕过上层直接访问tomcat,查看是否有问题。
排查流程:
tomcat返回Set-Cookie响应头,说明session已经失效,并重新创建了一个新的session。
所以,问题不是出在slb和nginx上。
考虑一番,打算直接从数据上查看是否有异样,重复上述步骤:
查看redis,一切正常:
查看redis,发现问题:
什么???
session的isValid变成false了,意味着session在第一次切负载的时候就已经失效了!
响应头依然有Set-Cookie,表示session的确失效了。
此时基本上确定问题是出在redisson-tomcat了。
在第一次getSession的时候,会调用sessionManager的createSession方法。
在切换负载的时候,会携带session id去访问另外一台tomcat,调用sessionManager的findSession方法:
乍眼一看,没有问题呀。
关键在于session.setId,调用了sessionManager的add(session)方法:
但是,到这一步也没问题。
问题在于,RedissonTomcat重写了sessionManager的add方法:
它调用了RedissonSession的自定义方法save
Redisson的save方法将所有字段同步到redis:
回过头看findSession,在还没有loadAttr的时候,就调用了setId方法,将一大堆还没有初始化好的值同步到了redis,导致session的isValid被置为false:
查看redisson的release记录,在最新版本已经修复了:
我们看一下,redisson是怎么修复的,仅仅是交换了setId和load(attrs)的顺序:
redisson 3.x版本最低要求jdk1.8,然而我们项目用的是jdk1.7。
于是我使用updateMode=AFTER_REQUEST模式暂时解决了这个问题。
AFTER_REQUEST原理是在tomcat容器的pipeline增加了一个Valve:
UpdateValve在请求结束后,同步所有字段到redis:
浏览器session已失效怎么解决
如果用户不点击网站的“退出”链接,而直接关闭浏览器(或者强制关闭浏览器进程、死机等),服务器无法处理用户退出网站的请求,解决方式如下:
方式1:在每个页面中加入隐藏的IFrame,以异步刷新的方式定期刷新iframe页面,如每隔10S刷新一次,当服务器在一定的时间内未收到用户的刷新请求,则认为用户已经退出
优点:能在短时间内判断出用户是否已经退出 缺点:增加用户请求次数,所消耗的服务器资源较大
方式2:使用cookie保存用户登录信息,不要设置cookie的过期时间,当关闭浏览器时,cookie会自动过期
优点:处理方便 缺点:用户浏览器不一定支持cookie,也就无法实现该方式
方式3:在页面中添加onunload事件,当关闭浏览器时,自动跳转到“退出”页面(loginout.action)
优点:退出时,能及时进行处理 缺点:当用户打开多个页面时,关闭任何一个页面都有可能导致用户的退出
方式4:记录用户的每次操作时间(包括页面刷新、提交表单等),在数据库中用作业每隔一段时间检查上次的操作时间,当操作时间大于一定的数值时,就认为该用户已经退出
优点:无论哪种非正常退出,都能够进行处理 缺点:进行检查的时间间隔不容易确定,如果用户在线,当长时间未操作,也会认为用户已经退出
方式5:等待session失效
优点:你可以不用做任何工作 缺点:用户可以在你等待的这段时间内重新登录