最近项目中一个模块出现一个问题,本人做的比较浅显,所以很简单的问题一直搞了好几天,通过各种查资料、工具终于分析除了问题。问题如下:
现在对tomcat一个工程(会通过httpurlconnection去请求别的资源)并发过多时候,tomcat直接跟挂去一样,再输入任何地址都一直不响应。通过java自带的检测工具看到像http-8080-1这样的http线程全部一直处于RUNNABLE状态,正常应该请求完处于WAITING。
其实这个问题很简单,去csdn等发问,版主说是死锁了--!结果耗去我很多时间去检查、分析哪里死锁了,其实这个不是线程死锁,忍不住吐槽下,不过也有我的原因在里面。最后通过jconsole,jvisualvm分析下tomcat进程,用jstack分析了thread dump,发现只要并发超过最大线程数然后就会这样,所有http线程都是在处理此工程的请求。而真实情况是此工程需要请求另一个服务(也部署在tomcat)才能得到返回结果,这样就造成了所有线程都是在等待返回结果(因为httpurlconnection没有设置超市时间),造成另一个服务一直获得不到线程去处理,从而造成了这种情况!
附上原来的实现原理,引以为戒!
packag 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 { } }