如果有数以千计的并发用户会话,
更新1:
现在,在使用JSF时不再需要保存状态。可以使用高性能的无状态JSF实现。有关详细信息和讨论,请参阅此blog & this question。此外,JSF规范中还包含一个开放的issue,可以选择为JSF提供无状态模式。(附注:如果问题this & this对您有用,请考虑投票支持该功能。)
更新2 (24-02-2013):
一个好消息,mojarra2.1.19发布了无状态模式!
请看这里:
http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255
发布于 2011-03-30 00:09:21
为什么需要在服务器端保存UI组件的状态?
因为HTTP是无状态的,而JSF是有状态的。JSF组件树会受到动态(编程)更改的影响。JSF只需要知道表单显示给最终用户时的确切状态,这样当表单提交回服务器时,它就可以基于原始JSF组件树提供的信息成功地处理整个JSF生命周期。组件树提供有关请求参数名称、必要的转换器/验证器、绑定的托管bean属性和操作方法的信息。
将UI组件的状态保存到服务器端的哪个时间点,以及从服务器内存中删除UI组件的状态信息的确切时间?
这两个问题似乎可以归结为相同的问题。无论如何,这是特定于实现的,还取决于状态是保存在服务器上还是保存在客户端上。一个不错的实现将在它过期或队列已满时将其删除。例如,当state state设置为session时,Mojarra的默认限制为15个逻辑视图。这可以在web.xml
中使用以下上下文参数进行配置
<context-param>
<param-name>com.sun.faces.numberOfLogicalViews</param-name>
<param-value>15</param-value>
</context-param>
有关其他Mojarra特定参数和此相关答案com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews的信息,请参阅Mojarra FAQ
当应用程序上的登录用户在页面中导航时,组件的状态是否会在服务器上不断累积?
从技术上讲,这取决于实现。如果您正在讨论页面到页面导航(只是GET请求),那么Mojarra将不会在会话中保存任何内容。但是,如果它们是POST请求(带有命令链接/按钮的表单),那么Mojarra将保存会话中每个表单的状态,直到达到最大限制。这使最终用户能够在同一会话中的不同浏览器选项卡中打开多个表单。
或者,当状态保存设置为client时,JSF不会在会话中存储任何内容。您可以通过web.xml
中的以下上下文参数来完成此操作
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
然后,它将被序列化为表单名称为javax.faces.ViewState
的隐藏输入字段中的加密字符串。
我不明白将UI组件的状态保留在服务器端有什么好处。直接将验证/转换后的数据传递给托管bean还不够吗?我可以/应该试着避免它吗?
这还不足以确保JSF的完整性和健壮性。JSF是一个具有单一控制点的动态框架。如果没有状态管理,人们将能够以某种方式欺骗/破解HTTP请求(例如,操纵disabled
、readonly
和rendered
属性),让JSF做不同的-and潜在危险的事情。它甚至容易受到CSRF攻击和网络钓鱼。
,如果有数以千计的并发用户会话,这会不会在服务器端消耗太多内存?我有一个应用程序,用户可以在某些主题上发布博客。这些博客的规模相当大。当有回帖或请求查看博客时,较大的博客将被保存为组件状态的一部分。这会消耗太多的内存。这不是一个令人担忧的问题吗?
内存特别便宜。只要给应用服务器足够的内存即可。或者,如果网络带宽对你来说更便宜,只需将状态保存切换到客户端。要找到最佳匹配,只需使用预期的最大并发用户数对您的then应用程序进行压力测试和性能分析,然后为应用程序服务器提供最大测量内存的125% ~ 150%。
请注意,JSF2.0在状态管理方面有了很大改进。可以保存部分状态(例如,只会保存<h:form>
,而不是从<html>
一直保存到最后的全部内容)。例如,Mojarra就是这样做的。一个包含10个输入字段(每个字段都有标签和消息)和2个按钮的平均表单将占用不超过1KB的空间。如果会话中有15个视图,则每个会话的大小不应超过15KB。对于大约1000个并发用户会话,这应该不超过15MB。
您的关注点应该更多地集中在会话或应用程序范围内的真实对象(托管bean和/或甚至DB实体)上。我见过许多代码和项目,它们不必要地将整个数据库表复制到Java内存中,就像会话作用域bean一样,其中使用Java而不是SQL来过滤/分组/排列记录。对于大约1000条记录,每个用户会话很容易超过10MB。
https://stackoverflow.com/questions/5474316
复制相似问题