如何处理有状态OSGi服务以跨捆绑更新维护会话状态?

时间:2013-05-06 17:18:45

标签: java session osgi httpsession

我们有一个将webapp实现为多个OSGi捆绑包的方案。我们希望进行捆绑更新,以便将错误修正等透明地部署到正在运行的系统中。假设刷新和包重新启动的更新周期,当重新加载类的对象存储在导致HttpSession的{​​{1}}时,这将导致问题。

我们正在寻找几种不同的方法来实现捆绑更新,而不会在登录会话中丢失状态。为了简化会话状态访问依赖关系图,我们考虑设置以下限制:

  • 一个bundle只能访问自己的会话状态,我没有直接访问另一个bundle设置的状态(强制调用bundle API来间接访问它的状态)
  • 添加到会话状态的Java类对象应该来自bundle本身(以避免我们的会话状态受到除我们之外的其他bundle更新的影响) 实际上只有下面的一些替代方案才需要这些限制。

所以,这些是我们以某种最小到最大的含义顺序提出的替代方案:

  1. 将所有状态存储为ClassCastException类型(java.*String等)
    - >州级课程永远不会重新加载。
  2. 将会话锁定到其状态创建的服务版本(通过f ex使用proxying solutions转发到该会话之前使用的版本)
    - >新会话将获取更新的捆绑版本,而现有会话将保留旧版本。
  3. 更新捆绑包时序列化会话状态并将其反序列化为新捆绑包版本(如appserver会话序列化,但更精细) - >所有会话都将获取更新的捆绑包,但要求序列化状态兼容。
  4. 只要存在活动会话,就可以避免更新有状态服务,利用传统的负载均衡器技术一次更新一个应用服务器 - >更长的部署周转时间,可能需要更多资源。
  5. 完全避免有状态的List服务,并将状态保持在其他地方 - >没有处理OSGi ...
  6. 中的问题

    我是否错过了任何有趣的选择? 你推荐什么解决方案?

    [尽管这篇文章明确谈到了会话状态,但同样的讨论可能适用于其他范围,例如会话状态,应用程序状态等]

1 个答案:

答案 0 :(得分:4)

在我看来,正确的答案不是一个简单的规则,而是一系列规则,如:

  • 如有必要,仅在应用程序的入口点使用有状态对象。入口点可以是IO设备的Servlet,套接字监听器,监听器类(从外部向您的应用发送请求并需要状态的东西)......
  • 仅在会话中存储对象,这些对象是从来自java。*的类实例化的。 (你的第一个选择。)
  • 如果您认为需要存储复杂的数据结构再考虑一下。您是否更快地返回持久数据?
  • 尽可能少地在会话中存储信息(没有实体对象,只有它们的id)
  • 使用服务包中的缓存来加快响应时间。我建议使用支持群集和XA事务的键值对缓存实现。这两个要求在以后都很重要。在键中只使用java。*类。如果使用读取密集型数据(在Web应用程序中占很大比例),请使用失效缓存。

有关缓存和持久数据关系的更多信息:

  • 将持久数据划分为逻辑集,其中一个集具有相同的生命周期。
  • 只能从一个捆绑包修改和缓存一个逻辑数据集。如果您没有此规则,如果有人更改了一个捆绑包的代码(这会影响另一个捆绑包中的缓存),则缓存可能会损坏。

这就是我们在公司设计Web应用程序的方式,这似乎是一种好方法。但是,还有其他方法。