【问题标题】:JSF - Extensive Read-Write to Application-Scoped BeanJSF - 对应用程序范围 Bean 的广泛读写
【发布时间】:2012-07-29 17:18:07
【问题描述】:

在我的 XPages Web 应用程序(Xpages 是一种基于 JSF 的 Lotus Notes 技术)中,我需要一个动态映射来存储会话 ID 和上次访问时间(以毫秒为单位)。这在应用程序范围的 bean 中实现为 TreeMap。对应用程序的每次初始访问都会将当前会话注册到此 bean 中的 TreeMap。此映射只允许有限数量的会话条目,并且不注册多余的会话。地图也会不时从旧会话条目中清除,以便可以注册新会话。 我需要知道这是否是可接受的方法/应用程序 bean 的使用。 我知道我可以将会话条目临时存储在外部数据库(非莲花笔记)中,但我正在工作的公司因为不允许我这样做。这种方法会导致我遇到潜在的问题吗?如果是,我还有其他方法可以做到这一点吗?

【问题讨论】:

  • 这对我来说似乎是绝对合法的。这是应用程序范围 bean IMO 的完美用例。不过,我更愿意将其存储在数据库中。

标签: jsf javabeans lotus-notes xpages


【解决方案1】:

这听起来像是对应用程序 bean 的完全有效的使用,但我要提供两个建议。第一种是使用 ConcurrentSkipListMap 而不是 TreeMap。前者是线程安全的,而后者不是。在与较低范围交互时,线程安全通常并不重要,因为每个用户只能写入自己的会话、视图和请求范围,但所有用户都可以写入应用程序范围,因此可以想象并发写入可能会发生,特别是在用户负载较重的应用程序中。第二个建议是提醒注意在应用程序 bean 中存储了多少有关每个会话的信息。由于所有用户都可以访问该 bean,因此理论上可能会无意中将太多关于用户的信息暴露给其他用户。如果除了上次访问时间之外,您只存储会话名称或 ID,那么您会没事的。但是,如果您实际上存储了一个指向每个用户会话范围的指针,您可能会意外地为用户缓存的数据提供一个窗口,而其他用户不应访问这些数据。我实际上从未见过有人因此而受苦,但在应用程序范围内存储任何特定于用户的信息时,牢记这一点始终很重要。

【讨论】:

    【解决方案2】:

    确实,这是对 Application Scope 的一个很好的利用。尽管如此,TreeMap 集合并不是适合您的情况的最佳方法,这存在一些问题:

    • 2 个请求要修改容器中的数据时的并发问题。
    • 如果您的应用程序必须水平扩展,您将在每个托管 bean 中有 2 个TreeMaps。

    一个好的方法是使用缓存系统。有很好的缓存库可以满足这些要求,我已经测试了ehcache,它提供了处理数据和库的并发管理,以防你有 2 个或更多节点来部署你的应用程序,你也可以配置一个算法来清除基于 LRU(不常用)或 FIFO(先进先出)的缓存。

    使用外部数据库处理会话 ID 可能会花费一些时间来获取/设置数据(它可能非常少,但仍然是磁盘 I/O 操作)。对于这个问题,您可以使用BigMemory 作为位于 RAM 中的外部数据库,或者像BigTable 这样的 NoSQL 数据库。

    注意:我不为 ehcache 工作,也不以商业方式关联,我已经对其进行了测试,它满足了我的需求。还有其他缓存系统库,如 JBoss Cacheothers 你可以评估并使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2012-03-27
      • 2013-10-19
      相关资源
      最近更新 更多