gpt4 book ai didi

java - 如何防止 "Broken pipe"关闭我的 tomcat 网站?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:54:42 27 4
gpt4 key购买 nike

我有一个 Tomcat 8 网络应用程序,它使用一个 2 MB 的 png 图像作为“初始页面/登陆页面”背景。该图像在外部样式表中被引用。

如果我清除浏览器缓存,直接请求图像的 URL,但在图像加载之前离开图像,它会完全杀死我的 Web 应用程序。它无法为任何请求提供更多响应。

我收到这个错误:

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:396)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:344)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:421)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:409)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:97)
at org.apache.catalina.servlets.DefaultServlet.copy(DefaultServlet.java:1795)
at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:919)
at org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:400)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at other.JsCssImgResponseHeaderFilter.doFilter(JsCssImgResponseHeaderFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at other.CatchAnyExceptionFilter.doFilter(CatchAnyExceptionFilter.java:39)

我正在 try catch 该异常(或与此相关的任何异常)并显示一个友好的 ErrorPage.jsp,但我无法重定向到 ErrorPage,因为响应已经提交。

我无法在测试环境中复制它,但我可以让它在生产环境中随意中断。

有谁知道我解决这类问题的选择是什么?提前致谢。

顺便说一句,这是我的 Filter 类的 doFilter 方法的样子:

    public void doFilter(ServletRequest req,
ServletResponse res,
FilterChain fc) throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession();

try
{
fc.doFilter(req, res);

// Have learned that response headers should not be set until we have determined there won't be an exception.
// Can't easily redirect or forward (to an error page, for example) if headers have already been committed.

if (SessionHelper.hasNeedsJsCssImgResponseHeaderFlag(request))
{
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, JsCssImgResponseHeaderFilter.SECONDS_TO_CACHE);
response.setHeader("Cache-Control", "PUBLIC, max-age=" + JsCssImgResponseHeaderFilter.SECONDS_TO_CACHE + ", must-revalidate");
response.setHeader("Expires", DateUtils.getDateInExpiresHeaderFormat(cal.getTime()));
}
else if (SessionHelper.hasNeedsDynamicPageResponseHeaderFlag(request))
{
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "Mon, 25 Nov 2013 00:00:01 GMT"); // in the past
}
else if (SessionHelper.hasNeedsRestServicesResponseHeaderFlag(request))
{
// CORS - Cross Origin Resource Sharing: allow service requests from other domains --
// such as local development domains hosting AngularJS projects.

response.setHeader("Access-Control-Allow-Origin", "http://localhost.domain.com:8080");

response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
// response.setHeader("Access-Control-Allow-Methods", "*");

response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
}
}
catch (Exception e)
{
SessionHelper.setErrorPageException(req, session, e);
final String uri = request.getRequestURI();
final String playerName = SessionHelper.getLoggedInPlayerName(session);

String outerLogEntryText = "Player = " + playerName + " - IP = " + request.getRemoteAddr() +
" - Mobile = " + SessionHelper.isMobileBrowser(request) +
" - URI = " + uri + " - Exception MSG = " + e.getMessage();

LogUtils.writeLogEntry(outerLogEntryText, true, e);
SessionHelper.setRedirectPage(session, SessionHelper.ERROR_PAGE_PATH);
}
finally
{
String redirectPage = SessionHelper.getRedirectPage(session);
SessionHelper.clearRedirectPage(session);

if (redirectPage != null)
{
if (response.isCommitted())
{
// Article: http://stackoverflow.com/questions/11305563/cause-of-servlets-response-already-committed
System.out.println("Response has been committed. Cannot redirect to: " + redirectPage);
}
else
{
response.sendRedirect(redirectPage);
}
}
}
}

当问题发生时,我的“Response has been committed...”输出语句确实被写入,因此它没有重定向到我的错误页面。这就是我的挑战:发生这种情况时如何重定向到某个地方——或者采取一些更好/无害的行动。

最佳答案

进行一些更改后,生产环境中没有出现该问题。最有影响力的变化是减小了我的背景/启动图像的大小。另一个变化是我将 Tomcat Connector connectionTimeout 属性设置增加了 6 倍。

关于java - 如何防止 "Broken pipe"关闭我的 tomcat 网站?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35761657/

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