如何以编程方式为方法或 bean 覆盖 Glassfish 超时配置?
How to override Glassfish timeout configuration programmatically for a method or bean?
我有一个专用于导出 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)
None 这在试生产中有效。有人可以指导我吗?
编辑:
这是我的 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 分钟可能是有意义的。
您可以做的是在后台异步执行实际的 CSV 导出。通过使用@Async
注释无状态会话bean 的业务方法,该方法将在单独的线程中执行,而原始请求立即完成。 @Async
注释方法的事务超时当然需要增加,但您可能已经这样做了。由于初始请求立即结束,超时不再是问题。并且导出是在服务器后台执行的,没有连接到客户端。
注意:使用@Async
注释的业务方法默认在新事务中启动。
剩下的问题是在需要时向用户正确报告 CSV 导出的结果。在初始请求之后,只能告诉用户 CSV 导出作业已被触发,但不知道它是否成功完成。一种可能的解决方案是,long-运行 导出方法 returns 和 FutureResult<ExportJobResult>
,它在由作业 ID 键入的 @Singleton
中注册。生成的作业 ID(例如 UUID)与初始响应一起返回给客户端。然后客户端可以轮询,比方说每 10 秒,Future
对象的状态(检查 isDone()
)。一个更详细的解决方案是一个完整的作业管理框架,它可以保持作业状态。
我有一个专用于导出 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)
None 这在试生产中有效。有人可以指导我吗?
编辑: 这是我的 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 分钟可能是有意义的。
您可以做的是在后台异步执行实际的 CSV 导出。通过使用@Async
注释无状态会话bean 的业务方法,该方法将在单独的线程中执行,而原始请求立即完成。 @Async
注释方法的事务超时当然需要增加,但您可能已经这样做了。由于初始请求立即结束,超时不再是问题。并且导出是在服务器后台执行的,没有连接到客户端。
注意:使用@Async
注释的业务方法默认在新事务中启动。
剩下的问题是在需要时向用户正确报告 CSV 导出的结果。在初始请求之后,只能告诉用户 CSV 导出作业已被触发,但不知道它是否成功完成。一种可能的解决方案是,long-运行 导出方法 returns 和 FutureResult<ExportJobResult>
,它在由作业 ID 键入的 @Singleton
中注册。生成的作业 ID(例如 UUID)与初始响应一起返回给客户端。然后客户端可以轮询,比方说每 10 秒,Future
对象的状态(检查 isDone()
)。一个更详细的解决方案是一个完整的作业管理框架,它可以保持作业状态。