一次Tomcat奇慢无比的调试,使用Python
开发中在向2000 Server转移时,发现3台2000 server上面运行的Tomcat都奇慢无比,开一个网页要1分钟甚至更多。而在个人PC上却没有问题。
通过几次排查,甚至写Java App来测试,发现DriverManager.getConnection()过程时间非常长,基本上就是出现速度瓶颈的地方,但是问题是并不是每一台电脑做Tomcat服务器都这么慢,有些速度很快。最后用Python写了一段连接数据库的代码做测试,整个从连接到查询,显示结果等等都不超过1秒钟。
最后目标锁定在DriverManager.getConnection()上面。后来一次编译一个用于测试速度的Java App时发现编译过程非常缓慢,不足100行的代码编译了近2分钟。随后试着关闭了KV的文件监控,然后,所以问题就都解决了。在其它电脑上也是,关闭了杀毒软件的文件监控以后就不再出现这个问题了。
结论:Java的软件,每个类就是一个文件,编译结果也是如此,所以一个Java程序的文件数量是很大的,另外有些软件还要以JAR来发布,解压过程更加漫长。所以杀毒软件在进行文件监控时会分析每一个被访问到的文件。而性能瓶颈也就出了问题在此,SQL server的JDBC驱动被杀毒软件反复的检查,每次被访问到都会查毒,所以导致速度奇慢无比。
解决办法:在服务器上将Java相关的目录,或者是.jar、.class、.java文件排除,不再需要杀毒软件检查。
附录1:使用Python连接SQL server数据库的测试脚本。需要安装pymssql模块。
import pymssql
import time
import msvcrt
starttime=time.time()
print "Start ... "+time.ctime(starttime)
conn=pymssql.connect(host="192.168.0.1",user="sa",password="******",database="******")
print "connected!!!! "+time.ctime()
cur=conn.cursor()
cur.execute("select * from T_sample")
print "Query end!!!! "+time.ctime()
print cur.fetchall()
print "output end !!!! "+time.ctime()
cur.close()
conn.close()
endtime=time.time()
print "Time Long="+str(endtime-starttime)+" s."
print "Press any key to close"
msvcrt.getch()
附录2:一个模拟SQL server的TCP服务器,用于记录JDBC客户端的连接时间及发送请求时间的时间差。需要twisted模块。
from twisted.internet import reactor,protocol
from twisted.protocols import basic
import time
class LieSQL(basic.LineReceiver):
def connectionMade(self):
print time.ctime()+"/tConnected!"
return
def lineReceived(self,line):
print time.ctime()+"/tlen="+str(len(line))
return
class LieSQLFactory(protocol.ServerFactory):
protocol=LieSQL
if __name__=="__main__":
port=1433
reactor.listenTCP(port,LieSQLFactory())
print time.ctime()+"/tStart ..."
reactor.run()
附录3:测试数据库服务器的TCP连接时延。使用socket方式。
from socket import *
import time
host="192.168.0.1"
starttime=time.time()
s=socket(AF_INET,SOCK_STREAM)
s.connect((host,1433))
s.close()
endtime=time.time()
print 'Time Long='+str(endtime-starttime)