场景:在工程A中调用工程B的接口完成一些逻辑,A中每调用一个接口打印一条信息,观察到当接口连续调用一段时间后,会卡住一会,然后又继续执行。老大给出建议查看下jstack dump堆栈信息,查看阻塞和耗时长的操作。

  1. 在命令行终端,输入jps 查看当前java进程id;
  2. jstack –l PID >>log.txt, PID指进程Id,将堆栈信息输出到当前目录下的log.txt文件中。

    对其中参数解释:
    -l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
    -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
  3. 堆栈的详细分析,参考jstack dump日志文件详细分析

通过上述的分析,发现项目中的日志打印中存在同步程序,导致所有的接口都在等待日志打印;另一个问题是身份验证太慢。

解决:

  1. 日志级别调成error,减少日志打印占用的资源,p6spy关闭减少资源占用,打印日志非常耗费资源,日志中的同步更是让接口处于等待状态。
  2. tokenID认证使用本地的认证,或者将认证去掉,原来使用外网地址的认证,通过Apache访问认证接口,Apache默认长连接,会限制连接的数量,等待连接释放,使程序阻塞。

除此之外,能够增加接口处理速度的设置:

  1. 设置MySQL数据库,my.ini
max_allowed_packet = 64M
innodb_buffer_pool_size =20G   --也不用设置过大,4096M也还可以
  1. 设置数据库的连接数,增加初始连接数,最大连接数:
#定义初始连接数  
initialSize=10  
#连接池处于活动状态的数据库连接的最大数目,0表示不限制,表示最大并发
maxActive=200 
#连接池处于空闲状态的数据库连接的最大数目,取非正整数表示不受限制,超过此数值时多余的空闲连接将会被释放
maxIdle=20
#连接池处于空闲状态的数据库连接的最小数目,低于此数值将会创建所欠缺的连接,设0无限制  
minIdle=10
#连接池中连接用完时,新的请求的等待时间(即等待别的连接空闲),超时返回异常,毫秒  
maxWait=60000
  1. 修改Tomcat,server.xml
<Connector  
	executor="tomcatThreadPool"
	port="8280"  
	protocol="org.apache.coyote.http11.Http11Nio2Protocol" 
	enableLookups="false"  
	acceptCount="1500"               
	disableUploadTimeout="false"      
	connectionTimeout="180000" 		
	connectionUploadTimeout="300000"
	maxConnections="10000"              
	URIEncoding="UTF-8"                           
	redirectPort="8443"               
	compression="on"              
	compressionMinSize="1024" 
	useSendfile="false"
	keepAliveTimeout="60000"
	tcpNoDelay="true"
	noCompressionUserAgents="gozilla, traviata" 
	maxPostSize="-1"  
    maxParameterCount="-1"
   compressibleMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript "   />
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>

将tomcat的线程池最大连接数增加改成maxThreads=200;
http的长连接超时时间keepAliveTimeout设置为keepAliveTimeout="2000"ms,因为我只是调用一下,不需要保持长连接获取数据,无用连接快速释放就可以了。