我们有一个将 webapp 实现为多个OSGi
bundle 的场景。我们希望进行捆绑更新,以透明地将错误修复等部署到正在运行的系统。假设更新周期包含刷新和捆绑重新启动,当正在重新加载其类的对象已存储在 s 的HttpSession
前导时,这将导致问题ClassCastException
。
我们正在研究几种不同的方法来使包更新成为可能,而不会丢失登录会话中的状态。为了简化会话状态访问依赖图,我们正在考虑设置以下限制:
- 一个bundle只能访问它自己的会话状态,即不能直接访问另一个bundle设置的状态(强制调用bundle API来间接访问它的状态)
- 添加到会话状态的对象的 Java 类应该来自包本身(以避免我们的会话状态受到除我们之外的其他包的更新的影响)这些限制实际上只有下面的一些替代方案需要。
因此,这些是我们以某种从最小到最大暗示顺序提出的替代方案:
- 将所有状态存储为
java.*
类型(String
、、List
等)
-> 状态类永远不会重新加载。 - 将会话锁定到创建其状态的服务版本(通过 f ex 使用转发到该会话之前使用的版本的代理解决方案
) -> 新会话将获取更新的捆绑版本,而现有会话将保留在旧版本上。 - 更新捆绑包时序列化会话状态并将其反序列化回新的捆绑包版本(如 appserver 会话序列化,但在更细粒度的级别)
-> 所有会话将获取更新的捆绑包,但要求序列化状态兼容。 - 只要有活动的会话,就避免更新有状态的服务,利用传统的负载均衡器技术一次更新一个应用服务器
-> 更长的部署周转时间并且可能需要更多资源。 - 完全避免有状态
OSGi
服务并将状态保留在其他地方
-> 不处理OSGi
...
我错过了任何有趣的选择吗?
您推荐什么解决方案?
[虽然这篇文章明确讨论了会话状态,但同样的讨论可能适用于其他范围,例如会话状态、应用程序状态等]