Nginx请求超时
0
最近用户老说下载失败,我试了一下果然有了问题,记录一下这几个问题:
首先浏览器的提示是:Nginx 504 Gateway Time-out
这个问题其实不是浏览器和Nginx请求超时,而是Nginx和你的应用服务器之间请求超时,也就是我的Tomcat处理超时了。
Nginx错误信息如下:
upstream timed out (110: Connection timed out) while reading response header from upstream
网上看了很多基本上都PHP的,后来发现要设置一下proxy
的属性:
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
设置后发现还是存在问题,最后我去看了一下磁盘信息,发现写入的时候非常慢。
于是我去看了一下我的代码,终于找到了是我的压缩方法有问题:
try {
zos = new ZipOutputStream(out);
zos.setEncoding("UTF-8");
for (File file : files) {
if(file != null && file.exists() && file.isFile()) {
FileInputStream fis = new FileInputStream(file);
ZipEntry entry = new ZipEntry(file.getName());
entry.setUnixMode(644); // linux乱码
zos.putNextEntry(entry);
int len;
while ((len = fis.read()) != -1) {
zos.write(len);
}
fis.close();
zos.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(zos);
IOUtils.closeQuietly(out);
}
然后我改了一下缓冲的大小,立马快了几十倍:
try {
zos = new ZipOutputStream(out);
zos.setEncoding("UTF-8");
for (File file : files) {
if(file != null && file.exists() && file.isFile()) {
FileInputStream fis = new FileInputStream(file);
ZipEntry entry = new ZipEntry(file.getName());
entry.setUnixMode(644); // linux乱码
zos.putNextEntry(entry);
int len;
byte[] bs = new byte[1024];
while ((len = fis.read(bs)) != -1) {
zos.write(bs, 0, len);
}
fis.close();
zos.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(zos);
IOUtils.closeQuietly(out);
}
顺便这里在记录一些问题:
an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/7/29/0000006297 while reading upstream, client
这个原因是因为Nginx的缓冲区设置比较小,修复方法:
proxy_buffer_size 4k;
proxy_buffers 64 32k;
或者关闭
proxy_buffering on;
还有下面一个错误:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
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.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:729)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:585)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:524)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:450)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:400)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:76)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:90)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:515)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1012)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:642)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1555)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:537)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:214)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:366)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:283)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:233)
at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
... 23 more
这个错误困扰了我很久了,一直没有找到原因,后来发现原来response.getOutputStream();
和response.getWriter();
这两个方法不能同时用,我估计freemarker
输出html
的时候使用的response.getWriter()
这个方法,所以在代码里面使用了response.getOutputStream();
都会出现这个问题,如果是返回页面的最好不要用,如果是输出图片就没有返回值的方法,ajax
也是没问题的。