如何以编程方式为方法或bean覆盖Glassfish超时配置?

时间:2016-02-23 14:04:55

标签: java nginx glassfish java-ee-7

我有一个专门用于导出CSV的bean,由于需要大量数据,大约需要15分钟,我会暂停。

为了解决这个问题,我考虑过只为这个bean添加一些配置,因为我不能增加Glassfish超时。因此,在我的本地计算机中,我更改了Glassfish超时配置以进行一些测试并减少15分钟(从网络侦听器请求超时和从线程池中IDLE超时),并且只添加一个@Transactional注释,但是当我使用预生产时机器它没有。

两者都是Glassfish 4.1.1,但在预生产中我也使用Nginx。但是尝试通过8181端口(HTTPS,我的Nginx无法控制),它既不起作用。

所以我一直在尝试不同的解决方案:

  • @Transactional(导致Glassfish中的事务超时为0)
  • 使用EJB
  • @StatefulTimeout
  • @TransactionManagement(TransactionManagementType.CONTAINER)和@TransactionAttribute(TransactionAttributeType.REQUIRED)

这些都不适用于预生产。有人可以指导我一点吗?

修改 这是我对Nginx的配置。

server {
    listen       80;
    client_max_body_size 900M;
    server_name *my config*;
    location / {
        proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_buffering off;
            proxy_ignore_client_abort off;
            proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:8080;
    }
}

即使在Glassfish中设置超时并将其减少到1分钟,但在预生产中我无法避免超时并且在该分钟后连接关闭。

1 个答案:

答案 0 :(得分:0)

对于在线申请,长期交易通常不是一个好主意。考虑到将连接超时限制为1分钟可能是有意义的。

您可以做的是在后台异步执行实际的CSV导出。通过使用@Async注释无状态会话bean的业务方法,该方法将在单独的线程中执行,而原始请求立即完成。当然,需要增加@Async注释方法的事务超时,但您可能已经完成了。由于初始请求立即结束,因此超时不再是问题。导出在服务器后台执行,无需连接到客户端。

注意:默认情况下,使用@Async注释的业务方法在新事务中启动。

剩下的问题是如果需要,可以正确地向用户报告CSV导出的结果。在初始请求之后,用户只能被告知已经触发了CSV导出作业,而不是它是否已成功完成。一种可能的解决方案是,长时间运行的导出方法返回FutureResult<ExportJobResult>,该@Singleton注册在由作业ID键入的Future中。生成的作业ID(例如,UUID)以初始响应返回给客户端。然后,客户端可以每隔10秒轮询一次isDone()对象的状态(检查String line = red.readLine(); String[] items = line.split("\\s"); )。更详细的解决方案将是一个完整的工作管理框架,它将持续存在工作状态。