java-如何处理有状态的OSGi服务以在捆绑更新中维护会话状态?

我们有一个方案,其中一个Web应用程序实现为多个OSGi捆绑包.我们要进行捆绑更新,以将错误修正等透明地部署到正在运行的系统.假设具有刷新和捆绑包重启的更新周期,当将要重新加载其类的对象存储在HttpSession上导致ClassCastExceptions时,这将引起问题.

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

>包只能访问其自己的会话状态,即不能直接访问另一个包所设置的状态(强制改为调用包API以间接访问其状态)
>添加到会话状态的对象的Java类应该来自捆绑包本身(以避免我们的会话状态受到除我们自己以外的其他捆绑包的更新的影响)
这些限制实际上仅是以下某些替代方法所需要的.

因此,以下是我们以某种方式(至少以最大暗示顺序)提出的替代方案:

>将所有状态存储为java.*类型(字符串,列表等)
–>状态类永远不会重新加载.
>将会话锁定到创建其状态的服务版本(由前任使用proxying solutions转发到该会话先前使用的版本)
->新会话将获取更新的捆绑软件版本,而现有会话将保留在旧版本上.
>在更新捆绑软件时序列化会话状态,然后反序列化回新的捆绑软件版本(例如appserver会话序列化,但粒度更细)
->所有会话都将获取更新的捆绑包,但要求序列化状态兼容.
>避免在有活动会话的情况下更新有状态服务,利用传统的负载平衡器技术一次更新一个应用服务器
->部署周转时间更长,可能需要更多资源.
>完全避免使用有状态的OSGi服务,而将状态保持在其他位置
->无法处理OSGi中的问题…

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

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

解决方法:

我认为正确的答案不是简单的规则,而是一系列规则,例如:

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

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

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

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

上一篇:Java HttpSession .getAttribute(字符串名称)


下一篇:java-客户端上的GWT HTTP会话可用性