我有一个专门用于导出CSV的bean,由于需要大量数据,大约需要15分钟,我会暂停。
为了解决这个问题,我考虑过只为这个bean添加一些配置,因为我不能增加Glassfish超时。因此,在我的本地计算机中,我更改了Glassfish超时配置以进行一些测试并减少15分钟(从网络侦听器请求超时和从线程池中IDLE超时),并且只添加一个@Transactional注释,但是当我使用预生产时机器它没有。
两者都是Glassfish 4.1.1,但在预生产中我也使用Nginx。但是尝试通过8181端口(HTTPS,我的Nginx无法控制),它既不起作用。
所以我一直在尝试不同的解决方案:
这些都不适用于预生产。有人可以指导我一点吗?
修改 这是我对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分钟,但在预生产中我无法避免超时并且在该分钟后连接关闭。
答案 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");
)。更详细的解决方案将是一个完整的工作管理框架,它将持续存在工作状态。