【问题标题】:How to handle stateful OSGi services to maintain session state across bundle updates?如何处理有状态的 OSGi 服务以跨包更新维护会话状态?
【发布时间】:2013-05-06 17:18:44
【问题描述】:

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

我们正在研究几种不同的方法来使包更新成为可能,而不会丢失登录会话中的状态。为了简化会话状态访问依赖图,我们正在考虑设置以下限制:

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

因此,这些是我们以某种从最小到最大暗示顺序提出的替代方案:

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

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

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

【问题讨论】:

  • 如何将存储在会话中的实际对象保存在自己的包中?那不会避免类转换异常吗?
  • 是的,我正在考虑将其添加为单独的替代方案,但我没有,因为如果更新了具有“状态类”的捆绑包,我们仍然会回到其他替代方案。

标签: java session osgi httpsession


【解决方案1】:

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

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

更多关于缓存和持久数据关系:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2012-10-14
    相关资源
    最近更新 更多