gpt4 book ai didi

jsf - Weld + GF4 + SessionScoped : Sometimes wrong bean?

转载 作者:行者123 更新时间:2023-12-04 12:58:26 25 4
gpt4 key购买 nike

TL;博士 我们得到 @SessionScoped注入(inject)的 bean 实例具有另一个 session 的内容

最近,我们的两个客户系统遇到了严重的问题。我们的客户正在两台装有 WELD 2.0.5 的 Glassfish 4.0 服务器的机器上运行同一 JSF 2.2 应用程序的两个独立实例(内存泄漏!)。

一些用户一直在报告问题,例如提交表单,响应显示另一个用户名而不是最初登录的用户名。由于我们无法在我们的开发和测试环境中重现这种行为,我们开始从生产系统中获取日志数据。

我们记录了什么?

在我们第一次尝试时,我们开始记录哪个用户在某个时间从哪个客户端执行了哪个操作。在浏览日志后,我们发现了这样的序列:

Time Client   User   Action
.............................
t=0 ClientA UserA Login
t=1 ClientA UserA Logoff
t=2 ClientB UserB Login
t=3 ClientB UserB ActionA
t=4 ClientB *UserA* ActionB
t=5 ClientB UserB Logoff

而替换用户的 session (此处为 User A )在替换发生之前并不总是结束(有时会导致一个用户注销另一个用户......)。那么当前登录的用户存储在哪里呢?我们将其作为属性存储在 @SessionScoped 中bean 被注入(inject) @RequestScoped bean 在我们需要这些信息的任何地方。这使我们得出了一个理论,即 @SessionScoped bean 有时会混淆。
@Named
@javax.enterprise.context.SessionScoped
public class SessionStateBean {
private User user;

public void setUser(...) { }
public User getUser() { }
}

因此,在我们的第二次尝试中,我们通过以下功能扩展了日志数据:
  • 我们开始在 HTTP session 中存储用户名,并在每个请求中将其与来自 @SessionScoped 的值进行比较。 bean 角,扁 bean 。
  • @SessionScoped 的每个实例bean 收到自己的 UUID 并在 bean 构建和销毁以及用户属性更改时进行记录。我们知道 @SessionScoped 是可能的beans 可以有多个代理,被钝化等,但我们试了一下。

  • 关于第一个日志功能,我们开始看到序列显示来自 session 范围 bean 的用户名和存储在 HTTP session 中的值之间的实际差异:
    Time Session Client   User   Action
    .............................
    t=0 SessA ClientA UserA Login
    t=1 SessA ClientA UserA Logoff
    t=2 SessB ClientB UserB Login
    t=3 SessB ClientB UserB ActionA
    t=4 |SessB ClientB *UserA* ActionB
    +-> SessionScope != Session
    t=5 SessB ClientB UserB Logoff

    考虑到所有正在处理的请求, session 范围值与 session 值不匹配的请求大约是60 到 150 个请求中的 1 个。

    更有趣的是 @SessionScoped 发生了什么 bean 实例。由于我们正在跟踪 @PostConstruct & @PreDestroy事件,观察到如下序列:
    Time Session Bean   Action     UserValue
    ................................
    t=0 SessA BeanA Construct (null)
    t=1 SessA BeanA SetUser UserA // login
    t=2 SessA BeanA SetUser (null) // logout
    t=3 SessA BeanA Destroy (null)
    // so far so good, now it gets interesting
    t=4 SessB BeanA SetUser UserB // login
    t=5 SessB BeanA SetUser (null) // logout
    t=6 SessC BeanA SetUser UserC // login
    t=7 SessC BeanA SetUser (null) // logout
    t=8 SessD BeanA SetUser UserD // login
    t=9 SessD BeanA SetUser (null) // logout

    没想到有时候在 @PreDestroy之后事件 bean 实例无需经过构建和销毁的生命周期即可重用。考虑到所有记录的 bean 实例,这发生在大约。从 500(系统 A)到 4000(系统 B)中的 1 个 bean。当 session 范围值和 HTTP session 值不同时,这并不总是发生,但是当我们看到这样的 bean 实例被重用时,总是发生在值不同的时候。

    最初我们假设这些事件更有可能在服务器负载一段时间后发生,但事实证明并非如此。有时它们会在上次服务器重启后几个小时发生,有时在两周后发生。

    在互联网上搜索这些问题,我们无法找到其他人在 WELD ( best trace, but wrong version)、Glassfish、Grizzly ( best trace, but too old)、JSF 等中遇到相同问题或已知错误的实际痕迹。

    所以我们的问题是:有没有人遇到过类似的问题?这种奇怪的行为是否是我们刚刚试图在错误的位置识别的已知错误?甚至有实际的修复吗?任何提示都很高兴!

    更新:我们发现,如果我们重新启动整个机器,所描述的行为就会消失大约两周。如果我们只是重新启动 Glassfish,则需要几个小时才能恢复奇怪的行为。说真的,什么会严重影响 Glassfish 或 JVM,以至于只有机器重启才能改变行为?

    目前,我们通过将我们保存的所有数据放在 @SessionScoped 中来绕过这个问题。 bean 直接进入 HTTP session ,到目前为止它似乎工作正常。但是这种方法实在是太笨拙了……

    最佳答案

    而不是以这种方式注入(inject) session 范围的 bean:

    @Inject
    private SessionBean sessionBean;

    尝试以这种方式注入(inject)它:
    @Inject
    private Instance<SessionBean> sessionBean;

    关于jsf - Weld + GF4 + SessionScoped : Sometimes wrong bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25017334/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com