Skip to content

Commit 8a9dd8d

Browse files
committed
update session management in laravel
1 parent 9e58aa3 commit 8a9dd8d

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

laravel/why-session-management--in-laravel-is-better.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
对于可以并行执行的 ajax 请求,我们可以在 js 中同时触发这些请求,并期望这些 ajax 请求在后端也被并行执行。但是,如果我们打开浏览器开发工具中的 network 面板,我们会发现,这些 ajax 请求虽然是同时触发并同时到达后端的,但是只有某个一个 ajax 请求处理完成之后,另一个 ajax 请求才会真正开始被处理。
1212

13-
https://demo.ma.ttias.be/demo-php-blocking-sessions/
13+
你可以打开这个网站,在 F12 模式下观察 xhr 的时间顺序: https://demo.ma.ttias.be/demo-php-blocking-sessions/
1414

1515
### 1.2 如何重现这个问题
1616

@@ -189,22 +189,23 @@ class FileSessionHandler implements SessionHandlerInterface
189189

190190
相同点:
191191

192-
- 模式相同,都使用了中间变量: 打开存储器 -> 挂载到中间变量 -> 读写中间变量 -> 将中间变量写入存储器
193-
- 对于传统模式来说,该中间变量是 $_SESSION, 对于 laravel 来说,该中间变量是
192+
- 模式相同,都使用了中间变量: 打开存储器 -> 挂载到变量 -> 读写变量 -> 将变量持久化到存储器
193+
- 对于传统模式来说,该变量是 $_SESSION,
194+
- 对于 laravel 来说,该变量是 Illuminicate\Session\Store 对象上的 attributes 属性
194195

195196
不同点:
196197

197198
- 传统方式只要读写 $_SESSION 变量即可,剩下的 session 过期判断,回收,读取,持久化,以及在响应的 Header 中设置相关的响应头等都是由 php 内置的 session 模块自动完成的
198199
- 在 larave 中,上述的每一步都是在框架层由 StartSession 中间件实现的。
199-
- 传统方式,当你输出了 header ,或/及 body 之后,再尝试读写session 时,会产生一个 Warning
200-
- laravel 方式,当你输出了 Header ,或/及 body 之后,再尝试读写session 时,不产生任何 Warning
200+
- 传统方式,当你输出了 header ,或/及 body 之后,再尝试读写session 时,会产生一个 'headers alreay sent' 的 Warning
201+
- laravel 方式,由于 $_SESSION 变量并不存在,因此,当你输出了 Header ,或/及 body 之后,再尝试读写 session 时,并不会产生任何 Warning
201202

202203

203204
- laravel 的打开存储器不加锁,
204205
- 传统方式打开存储器时默认会加锁,并且是事务锁,其他进程不可读,更不可写
205206

206207
- 同一个请求中,传统方式下,在一对 `session_start()` -> `session_commit()` 之间,如果出现了重复的 `session_start()`,那么这些多余的 `session_start()` 并不会重新打开存储器,而是直接被忽略。
207-
- 同一个请求中,laravel 机制下,在一对 `Session::start()` -> `Session::save()` 之间,如果出现了重复的 `Session::start()` ,那么每次 `Session::start()` 时,内存中的 session 数据都会与存储器中的最新数据进行合并. 因此,laravel 中的 `Session::start()` 方法可以理解成 `Session::mergeWithLatestStore()`
208+
- 同一个请求中,laravel 机制下,在一对 `Session::start()` -> `Session::save()` 之间,如果出现了重复的 `Session::start()` ,那么每次 `Session::start()` 时,内存中的 session 数据都会与存储器中的最新数据进行合并. 因此,laravel 中的 `Session::start()` 方法可以理解成 `Session::mergeAttributesWithLatestStore()`
208209

209210
- laravel 的 session 更方便测试
210211
- laravel 的 sessionHandler 选项更多,包含 database / apc / array / cookie
@@ -216,26 +217,26 @@ class FileSessionHandler implements SessionHandlerInterface
216217

217218
### 4.1 重新认识session
218219

219-
session 这个词翻译成中文叫做“会话”,现实中,两个人之间进行会话时,正常的形式都是你问我答,再问再答,如果你使用了分身术,一下子同时问好几个问题,我可以选择也选择使用分身术,然后每个我同时各自回答你的问题,也可以选择只有我一个人,挨个回答问题。
220+
session 这个词翻译成中文叫做“会话”,现实中,两个人之间进行会话时,正常的形式都是你问我答,再问再答,如果你使用了分身术,一下子同时问好几个问题,我可以选择也使用分身术,然后每个我同时各自回答你的问题,也可以选择只有我一个人,挨个回答问题。
220221

221222
### 4.2 session racing problem ?
222223
如果对于同一个 sessionId 存在多个并发请求,那么这些并发的请求可能会并发地修改 session 中的数据,这样会可能导致最终的存储器中的数据被互相覆盖.
223224

224225

225-
### 4.3 session racing problem should a fake problem
226+
### 4.3 session racing problem should be a fake problem
226227

227228
session 的核心目的是区分当前http请求的访问者是哪一个用户/哪一个游客。
228229

229230
session 存储方式从大的思路上可以分为两类:
230231
- 一类是将 session 数据保存在用户的浏览器端,
231232
- 一类是将 session 数据保存在服务器端,如 file,redis,memcache 等
232-
不管是哪一类,session 数据中至少会保存该访问者的用户 id
233-
对于前一类,session 数据的解析和存储都只涉及到响应头,服务器无需任何存储器,因此先不讨论.
234-
而对于后一类,由于连接并打开存储器,从而获取其中的用户id 这一步是不可避免的,因此,各种应用中,除了在存储器中保存用户id之外,还会保存一些其他的热点数据作为缓存,从而节省一次查询.
233+
不管是哪一类,session 数据中至少会保存该访问者的用户 id
234+
对于前一类,session 数据的解析和存储都只涉及到响应头,服务器无需任何存储器,因此先不讨论.
235+
而对于后一类,由于连接并打开存储器,从而获取其中的用户id 这一步是不可避免的,因此,各种实践中,除了在存储器中保存用户id之外,还会保存一些其他的热点数据作为缓存,从而节省一次查询.
235236

236-
因此,避免 session racing problem, 实际上也就是避免 cache racing problem.
237-
我们知道,缓存中不应该存储变更特别频繁,或者实时性很重要的数据,这个原则对于 session 来说也是一样的.
238-
相反,对于表单验证提示,菜单权限等数据就比较适合保存到 session 中. 这些场景并不会产生 session racing problem
237+
因此,避免 session racing problem, 实际上也就是避免 cache racing problem.
238+
我们知道,缓存中不应该存储变更特别频繁,或者实时性很重要的数据,这个原则对于 session 来说也是一样的.
239+
相反,对于表单验证提示,菜单权限等数据就比较适合保存到 session 中. 这些场景并不会产生 session racing problem
239240

240241
### 4.4 access_token or session_cookie ?
241242

0 commit comments

Comments
 (0)