最近在开发过程中遇到一个不明白的问题, 查了很久没有思路, 想请教各位大佬.
公司这边使用PHP的session的存储介质是memcached, 架构是php-fpm和nginx.
场景描述:
当用户一个请求执行很慢且使用了session_start()并且没有释放session资源的情况下, 如果此时该用户下一个请求又发送过来, 由于session独占锁的原因, 该用户的第二次请求将会等到第一次请求将session释放后才能执行或者脚本等待导致超时被fpm的master进程kill掉.
那么问题来了, 我发现在上述这种情况下, 用户的第二个请求并不会一直等待上一个请求释放session, 而是经过几秒后, 代码里$_SESSION['name']会返回null.
诡异bug
这种情况就很容易让我想到日常浏览网页会出现一个诡异bug: 假设我的某个操作会执行较久, 而在该请求完成前我又发起多个请求, 如果网站需要通过session验证我的身份, 那么后面的几次请求很可能被判断为我未登陆 (原因 : 前一个请求未完成, session被占用, 后面的请求获取session中信息的时候,session返回为null) 而拒绝请求.这不是很严重的一件事情吗? 但是日常中好像并没有遇到谁家的网站出现过这种问题.
请教大家
我想请教大家, 这个独占锁是否真的会导致后面的请求获取不到session(返回为null值)?
我如何判断是用户真的没登陆还是由于用户上一个请求占用着session资源导致的返回null?
事实上并不像网上说的那样脚本会一直等待之前的请求释放session, 而是经过某段时间就返回null, 那么有哪些参数可以控制这个独占锁超时, 如果超时就返回null?(是否将这个超时时间设置无限大就可以避免刚才提到的日常浏览网页的诡异bug?)
如果你正在使用PHP的memcached扩展,你可以将memcached.sess_locking设置为“off”,来避免session锁。
文件的话参考手册:
memcached扩展的锁实现: