在顶部的班级评论中PersistentValve https://github.com/apache/tomcat/blob/TOMCAT_9_0_14/java/org/apache/catalina/valves/PersistentValve.java有一个使用限制:
/**
...
* <b>USAGE CONSTRAINT</b>: To work correctly it assumes only one request exists
* per session at any one time.
...
*/
为什么这个约束在这里?仔细阅读代码我发现三个原因:
- 不同 Tomcat 实例上对同一会话的并发请求可能会受到“最后写入获胜”的影响,从而可能会丢失会话数据。
- 在同一个 Tomcat 实例上对同一会话的并发请求可能会导致 NPE,因为session.recycle() https://github.com/apache/tomcat/blob/TOMCAT_9_0_14/java/org/apache/catalina/valves/PersistentValve.java将管理器设置为空共享会话对象 https://github.com/apache/tomcat/blob/TOMCAT_9_0_14/java/org/apache/catalina/session/StandardSession.java#L955和另一个请求取消引用管理器时尝试将会话保存到存储中 https://github.com/apache/tomcat/blob/TOMCAT_9_0_14/java/org/apache/catalina/session/StandardSession.java#L1641.
- 性能低效(例如,冗余的持久性存储访问等)。
还有其他原因吗?
在进行 SVN-Blame 时,我发现此评论是在 2008 年 5 月 1 日添加到 svn 修订版 652662 中的修复错误 43343 https://bz.apache.org/bugzilla/show_bug.cgi?id=43343使用提交评论:.
该错误的上下文强烈指出了您建议的原因 (1),即它与数据丢失有关。在最初的错误描述中,OP 说:
...我看到其他问题的唯一地方是:
java/org/apache/catalina/valves/PersistentValve.java
它错误地从 PersistentManager 获取存储并且
直接使用它而不是使用管理器 API。对我来说这很糟糕
因为经理不能成为经理,而其他逻辑
正在直接访问商店,并且永远不应该发生......除非它是
仅在测试用例等中使用。
所以这里被认为是Managers
' 使用会话的唯一任务Store
用于存储、加载和删除会话。但是PersistentValve
做同样的事情,可能很容易干扰经理的工作。
在错误修复提交期间除了修改PersistentManager
,仅将相关评论添加到PersistentValve.java
再加上一个未使用的变量被删除:
- StandardHost host = (StandardHost) getContainer();
虽然我不知道删除这一行的目的或过去存在的情况,但我认为提交者 Mark Thomas 在代码审查和补丁过程中认识到,当任何时候每个会话最多只有一个活动请求时,PersistentValve 只能保证一致的会话写入及时。否则可能会发生丢失写入的情况。
我不会判断这有多实用,只是考虑每个网页印象并行加载的大量资源(主要 HTML、CSS、JS、图像)。
我仍然不确定使用单个 Tomcat 实例这是否会成为问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)