如果发生数据库死锁,我想自动重复 HTTP 请求;但是,FilterChain.doFilter()被定义为单向链(因此我无法重置其状态)。
在安全的情况下,是否可以在不让客户端重新提交请求的情况下重复 HTTP 请求?
更新:我刚刚发现这种方法存在问题。即使您重复请求,您也需要缓冲请求InputStream。这意味着如果用户上传 100MB 的数据,无论是否发生死锁,您都将被迫缓冲该数据。
我正在探索让客户端在这里重复请求的想法:返回 HTTP 503 以响应数据库死锁是否合适?
如果发生数据库死锁,我想自动重复 HTTP 请求;但是,FilterChain.doFilter()被定义为单向链(因此我无法重置其状态)。
在安全的情况下,是否可以在不让客户端重新提交请求的情况下重复 HTTP 请求?
更新:我刚刚发现这种方法存在问题。即使您重复请求,您也需要缓冲请求InputStream。这意味着如果用户上传 100MB 的数据,无论是否发生死锁,您都将被迫缓冲该数据。
我正在探索让客户端在这里重复请求的想法:返回 HTTP 503 以响应数据库死锁是否合适?
回答我自己的问题:
不要尝试重复 HTTP 请求。为此,您将被迫为所有请求缓冲InputStream,即使从未发生死锁。如果您被迫接受大量上传,这会使您面临拒绝服务攻击。
我推荐这种方法:返回 HTTP 503 以响应数据库死锁是否合适?
然后,您可以将大型上传分解为使用 AJAX 拼接在一起的多个请求。不漂亮,但它可以工作,总的来说你的设计应该更容易实现。
更新:根据布雷特·伍尔德里奇:
您需要一个最多包含几十个连接的小池,并且您希望其余的应用程序线程阻塞在池中等待连接。
正如 Hikari 建议使用长请求队列的少量线程一样,我相信 Web 服务器也是如此。通过限制活动线程的数量,我们限制了需要缓冲的 InputStream 数量(剩余的请求在发送 HTTP 正文之前被阻塞)。
为了进一步强调这一点,Craig Ringer建议尽可能从服务器端的故障中恢复。
您可以对原始请求进行“转发”,如下所示。
RequestDispatcher rd= request.getRequestDispatcher("/originalUrl");
rd.forward(request, response);
这里request和response分别代表HttpServletRequest/HttpServletResponse。参考 http://docs.oracle.com/javaee/5/api/index.html?javax/servlet/RequestDispatcher.html
或者,您可以对响应进行重定向。但是,这将向浏览器发送响应,要求它为提供的 url 发出新请求。如下所示
response.sendRedirect("originalUrl?neededParam=abc");