It involves using Tomcat as a server in our daily development, but how much of a thread pool should we set up? And according to what principles to design this thread pool? Next, I will introduce how I design and calculate.
Determine the tomcat server thread pool size
As is well known, Tomcat accepts a request post-processing process that will design to CPU time and IO wait time. When IO waits, the CPU passively discards execution, and other threads can take advantage of this time slice to operate.
So we can adopt the general rules of server IO optimization:
Thread size = ((thread IO time + thread CPU)/thread CPU hours) * CPU Cores
Example: Thread io time is 100ms (IO operation such as database query, synchronous remote call, etc.), thread CPU time 10ms, server physical machine core number is 4. By the above formula, we calculate the size is ((+)/10) = 44. Theoretically we have a basis, but how do we know the thread IO time and CPU time during the actual calculation? This is designed to monitor the processing time during the actual coding process. Now, let me tell you what I'm doing.
1. Using Java to implement the built-in filter interface, we can get the total time consumed by a request
Public classMoniterfilterImplementsFilter {Private Static FinalLogger Logger = Loggerfactory.getlogger (moniterfilter.class); @Override Public voidDoFilter (ServletRequest request, servletresponse response, Filterchain chain)throwsIOException, servletexception {LongStart =System.currenttimemillis (); HttpServletRequest HttpRequest=(httpservletrequest) request; HttpServletResponse HttpResponse=(httpservletresponse) response; String URI=Httprequest.getrequesturi (); String params=getquerystring (HttpRequest); Try{chain.dofilter (HttpRequest, HttpResponse); } finally { LongCost = System.currenttimemillis ()-start; Logger.info ("Access URL [{}}], cost time [{}] ms)", URI, params, cost); } PrivateString getquerystring (httpservletrequest req) {StringBuilder buffer=NewStringBuilder ("?")); Enumeration<String> Emparams =Req.getparameternames (); Try { while(Emparams.hasmoreelements ()) {String SParam=emparams.nextelement (); String svalues=Req.getparameter (SParam); Buffer.append (SParam). Append ("="). Append (Svalues). Append ("&"); } returnBuffer.substring (0, Buffer.length ()-1); } Catch(Exception e) {logger.error ("Get Post arguments Error", buffer.tostring ()); } return""; } @Override Public voiddestroy () {} @Override Public voidInit (Filterconfig filterconfig)throwsservletexception {}}
2. Monitor thread io time by adding facets (jdk,cglib)
Public classDaointerceptorImplementsMethodinterceptor {Private Static FinalLogger Logger = Loggerfactory.getlogger (daointerceptor.class); @Override PublicObject invoke (Methodinvocation invocation)throwsthrowable {StopWatch Watch=NewStopWatch (); Watch.start (); Object result=NULL; Throwable T=NULL; Try{result=invocation.proceed (); } Catch(Throwable e) {T= e = =NULL?NULL: E.getcause (); Throwe; } finally{watch.stop (); Logger.info ("({}ms)", Watch.gettotaltimemillis ()); } returnresult; }}
The above code can be used to calculate the corresponding time, so as to calculate the size of the outgoing thread. But we're done here?
In fact, the calculated value is only in the theoretical case, we still need to use the pressure measurement tool (Jmeter) to test the line server, while dynamically fine-tuning based on the QPS value of the thread pool size just calculated.
At this point, the thread pool size should be out.
How do I set the tomcat thread pool size?