开发者社区> 问答> 正文

tomcat线程一直处于RUNNABLE,不接受请求 400 请求报错 

现在对tomcat一个工程(会通过httpurlconnection去请求别的资源)并发过多时候,tomcat直接跟挂去一样,再输入任何地址都一直不响应。通过java自带的检测工具看到像http-8080-1这样的http线程全部一直处于RUNNABLE状态,正常应该请求完处于WAITING。现在不知道是什么原因导致的,希望有大神给分析下,感激不尽!下面是线程dump,就随便贴两个:

"http-8080-7" daemon prio=6 tid=0x183bd400 nid=0x6f50 runnable [0x1958f000]
   java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked <0x09cd8e58> (a java.io.BufferedInputStream)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)
- locked <0x09b2a448> (a sun.net.www.protocol.http.HttpURLConnection)
at peacemap.coorshare.search.LocalSearch.getInfoFromService(LocalSearch.java:163)
at peacemap.coorshare.search.LocalSearch.doGet(LocalSearch.java:80)
at peacemap.coorshare.search.LocalSearch.doPost(LocalSearch.java:141)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:662)


   Locked ownable synchronizers:
- None


"http-8080-6" daemon prio=6 tid=0x183bcc00 nid=0x6f48 runnable [0x1953f000]
   java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked <0x09b2c688> (a java.io.BufferedInputStream)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195)
- locked <0x09b2c728> (a sun.net.www.protocol.http.HttpURLConnection)
at peacemap.coorshare.search.LocalSearch.getInfoFromService(LocalSearch.java:163)
at peacemap.coorshare.search.LocalSearch.doGet(LocalSearch.java:80)
at peacemap.coorshare.search.LocalSearch.doPost(LocalSearch.java:141)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:662)


   Locked ownable synchronizers:
- None

展开
收起
kun坤 2020-05-29 22:50:20 1238 0
1 条回答
写回答
取消 提交回答
  • 网络IO阻塞,HttpURLConnection 启动太多了.######差不多就是这个意思,呵呵######可能是你程序里面任何一个地方的锁死问题。建议在有可能长时间操作的地方使用线程,让http线程能及时释放###### 这个是代码实现,请大家帮看看有啥问题。谢谢了

    package peacemap.coorshare.search;
    
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.io.Reader;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.ProtocolException;
    import java.net.URL;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class test extends HttpServlet {
    
    	public test() {
    		super();
    	}
    
    	public void destroy() {
    		super.destroy();
    	}
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		String url = "http://localhost:8080/solr/select/?q=name%3A%E8%B4%B5%E5%B7%9E&version=2.2&start=0&rows=10&indent=on&wt=json";
    		response.setContentType("text/html");
    		response.setCharacterEncoding("UTF-8");
    		PrintWriter printWriter = response.getWriter();
    		String returnStr=getInfoFromService(url);
    		System.out.println(returnStr);
    		printWriter.write(returnStr);
    		printWriter.close();
    	}
    
    	private String getInfoFromService(String url) {
    		String resultStr = "";
    		try {
    			URL destURL = new URL(url);
    			HttpURLConnection urlConn = (HttpURLConnection) destURL
    					.openConnection();
    			urlConn.setRequestMethod("GET");
    			urlConn.setDoOutput(true);
    			urlConn.setDoInput(true);
    			urlConn.setUseCaches(false);
    			InputStreamReader inStream = new InputStreamReader(urlConn
    					.getInputStream(), "utf-8");
    			resultStr = getRequestContent(inStream);
    			inStream.close();
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (ProtocolException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return resultStr;
    	}
    
    	private String getRequestContent(Reader reader) throws IOException {
    		StringBuffer sb = null;
    		sb = new StringBuffer();
    		char[] data = new char[1024];
    		int i = reader.read(data);
    		while (i != -1) {
    			sb.append(data, 0, i);
    			i = reader.read(data);
    		}
    		String sreq = sb.toString();
    		return sreq;
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    	public void init() throws ServletException {
    	}
    
    }
    inStream.close();

    流没关闭吧, 试一下把这个放在finally里面 ######这个。。。不是这个问题###### 这个连接没有手动释放掉吧

    finally{
        urlConn.close();
    }
    1.大量的并发,导致请求将tomcat的连接数占满。
    1. 每个并发请求线程 需要tomcat连接去访问其他资源String returnStr=getInfoFromService(url);
      导致:每一个请求都在等待tomcat连接而挂起。

    以上纯属猜测,并无依据。 ######嗯,就是这个原因啊######设置下请求超时时间,如果请求超时未处理会导致大量线程在等待 RequestConfig config = RequestConfig.custom().setConnectTimeout(6000).setSocketTimeout(6000).build(); httpPost.setConfig(config);######建议jstack看一下  ######第一个,请强制关闭流;第二个请关闭请求,在做http请求的时候,每次都要调用close,谢谢。

    2020-05-29 22:50:29
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Apache Tomcat 的云原生演进 立即下载
多IO线程优化版 立即下载
低代码开发师(初级)实战教程 立即下载