JDK 1.7.0 + Tomcat 8.5 部署的web应用,启动后第一次打开很快。长时间不用后,再次浏览器访问时很慢卡住,或是socket连接超时。后台代码卡住的位置不是很确定,后来发现都是卡到了Service层。连接池是druid 1.0.8。
解决问题的思路:
1.首先确定卡在那里。
(方法用jps和jstack和远程调试)
问题重现后立即进行如下操作:
a.找到进程ID,查看进程命令:ps -ef 或者 jps -v
b.查看java进程中的线程命令:jstack 进程ID
可以看到java进程里的每个线程的调用栈。
类似如下图(linux在内网,用外网的windows截图代替)
可以看到每个线程目前运行到哪里。
如果是和我一样卡在Service层的方法,而且里面又有类似getConnection这样获取数据库连接的情况下:
Service层方法有事务,事务需要数据库连接,连接池里连接长时间不用会断开。
这就是我的问题原因。可以用netstat -ant | grep 11521可查看这些被卡住的socket连接。
2.我的问题解决方法:a+b双管齐下
a.避免因为安全随机数慢导致获取连接卡住,centos7.2里用jdbc连接Oracle时,会因为这个问题超时[socket reset]或程序卡住,在tomcatbin/目录下新建setenv.sh文件内容如下(注意英文双引号和"/./"是必须的):
export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom" #export CATALINA_OPTS="-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=18000" #export CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,address=18000,server=y,suspend=n,timeout=60000" export JAVA_OPTS="-server -Xms2048m -Xmx2048m -XX:PermSize=128m -XX:MaxPermSize=512m $JAVA_OPTS"
设置后,tomcat的启动速度加快很多。
b.尝试修改我的druid数据源配置后:这个配置应该可以解决大部分问题。
initialSize=5 初始化5个连接 minIdle=5 最小空闲5个连接 maxActive=20 最多20个连接 maxWait=10000 获取连接最多等待10000毫秒 useUnfairLock=true 处理等待时使用非公平锁 testWhileIdle=true 检查空闲连接可用性 timeBetweenEvictionRunsMillis=60000 一分钟检查一次空闲连接,同时关闭多余的空闲连接 毫秒 testOnBorrow=true 获取连接前检查可用性 minEvictableIdleTimeMillis=300000 一个连接在池中最小生存的时间毫秒 validationQuery=select 1 from dual validationQueryTimeout=4 检查连接可用性的超时时间4秒
但是我这台电脑上发现每次打开都很卡,使用netstat -ant | grep 11521可以看到数据库连接要么没有,要么已经wait_close。然后我停用了Druid,换Spring自带数据源:
<!-- 数据源配置, 不使用连接池 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
使用netstat -ant | grep 11521 可以看到总是有数据库连接是建立的。 观察几个星期,问题都不在出现了。问题解决!
但是druid哪里设置错了吗?有知道的可以回复一下,告诉我。
2019年12月10日
spring boot 开发的微服务项目存在同样问题,jdbc('org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '1.4.1.RELEASE'),spring boot默认使用连接池:org.apache.tomcat.jdbc.pool.ConnectionPool
jstack信息:
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.172-b11 mixed mode): "XNIO-2 task-6" #61 prio=5 os_prio=0 tid=0x00007fddb4004800 nid=0x16a1 runnable [0x00007fde84bcb000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.FileDispatcherImpl.read0(Native Method) at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) at sun.nio.ch.IOUtil.read(IOUtil.java:197) at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) - locked <0x00000000d1c78c28> (a java.lang.Object) at oracle.net.nt.TimeoutSocketChannel.read(TimeoutSocketChannel.java:144) at oracle.net.ns.NIOHeader.readHeaderBuffer(NIOHeader.java:82) at oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:139) at oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:101) at oracle.net.ns.NIONSDataChannel.readDataFromSocketChannel(NIONSDataChannel.java:80) at oracle.jdbc.driver.T4CMAREngineNIO.prepareForReading(T4CMAREngineNIO.java:98) at oracle.jdbc.driver.T4CMAREngineNIO.unmarshalUB1(T4CMAREngineNIO.java:534) at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:485) at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:252) at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:612) at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:213) at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:37) at oracle.jdbc.driver.T4CStatement.executeForDescribe(T4CStatement.java:733) at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:904) at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1082) at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1737) at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1692) - locked <0x00000000d1c6e380> (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:300) at org.apache.tomcat.jdbc.pool.PooledConnection.validate(PooledConnection.java:509) at org.apache.tomcat.jdbc.pool.PooledConnection.validate(PooledConnection.java:443) at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:784) at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:635) at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:187) at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:132) at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:82) at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:68) at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:338) at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:84) at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62) at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:326) at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109) at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:108) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) at com.sun.proxy.$Proxy165.query(Unknown Source) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) at com.sun.proxy.$Proxy124.selectOne(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:166) at com.xxxxxx.core.dao.impl.BaseDaoImpl.select(BaseDaoImpl.java:23) at com.xxxxxx.core.dao.impl.BaseDaoImpl$$FastClassBySpringCGLIB$$fa9bc947.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) at com.xxxxxx.core.dao.impl.BaseDaoImpl$$EnhancerBySpringCGLIB$$789fcc35.select(<generated>) at com.xxxxxx.core.service.PublicService.queryUserDeptCount(PublicService.java:58) at com.xxxxxx.core.configurate.LoginInterceptor.preHandle(LoginInterceptor.java:45) at org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:134) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:958) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) at javax.serv
解决方法类似(停用连接池):
spring.datasource.type=org.springframework.jdbc.datasource.DriverManagerDataSource spring.datasource.url=jdbc:oracle:thin:@xxx:xx/xx spring.datasource.username=xx spring.datasource.password=xx spring.datasource.driver-class-name=oracle.jdbc.OracleDriver #spring.datasource.initialSize=1 #spring.datasource.maxActive=200 #spring.datasource.minIdle=5 #spring.datasource.maxIdle=20
必须使用连接池?
那么可以考虑把连接池设置为:得到连接时不验证连接可用性,同时缩短空闲连接可用性检查的间隔,同时设置检查可用性的超时时间。如果没有任何bug(尤其超时时间可能有问题,你设置了,jdbc驱动可不一定会用)那么理论上不会卡。祝你好运!
https://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html
https://www.cnblogs.com/prefectjava/p/9397999.html
https://www.cnblogs.com/yeahwell/p/9252931.html
相关推荐
jdk-7u45-linux-x64.tar.gz centos 6.5 jdkjdk1.7.0_45
腾讯云服务器Linux CentOS 7.2 yum安装LAMP环境
Linux CentOS 7.2,自己用的,亲测可以用,记录并分享给大家,不用那么难找Linux是开源的操作系统是一个支持多用户、多进程、多线程、实时性较好、功能强大而稳定的操作系统,也是目前运行硬件平台最多的操作系统。...
CentOS7.2版本的ISO包,text文件中为永久有效分享的百度网盘下载链接地址,若是由于某些原因导致失效,还烦请私信。
centos上安装配置Tomcat环境,纯手工编写,测试过文档无误
Linux系统管理基础项目教程(CentOS7.2)(微课版)-课件PPT.zip
由于Tomcat爆出漏洞,前几天公司让在测试环境配置Tomcat8.5.51的https ,配置了很久都不对。最后换了Tomcat8.5.54的才配置成功。下面就是我配置的过程,记录一下,与大家共勉。 1.首先公司的泛域名,运维给了ssl证书...
CentOS7.2Linux安装OracleDatabase12c
Centos7.2.1511 网盘下载 ,text文件中为永久有效分享的百度网盘下载链接地址。********************
Linux安装WerbSphere Application Server V8.5 1、安装所需要的软件包 agent.installer.linux.gtk.x86_64_1.6.0.zip WAS_ND_V8.5_1_OF_3.zip WAS_ND_V8.5_2_OF_3.zip WAS_ND_V8.5_3_OF_3.zip 2、安装Installation ...
CentOS7.2下安装部署OpenStack+KVM 云平台虚拟化环境详解
centos 7.2 gcc 包
介绍centos环境下系统的安装、JDK的配置、Tomcat的安装
centos7系统 下 jdk1.7 tomcat7.0 的安装包亲测可用的
Tomcat的安装和配置. 附带Tomcat安装包,省去Tomcat的下载
centos7 安装jdk tomcat oracle
centos搭建jdk tomcat my5.6自启动服务
centos7.2安装部署 OpenStack+KVM 云平台虚拟化环境详解
CentOS7.2.1521下安装MySQLCentOS7.2.1521下安装MySQLCentOS7.2.1521下安装MySQLCentOS7.2.1521下安装MySQLCentOS7.2.1521下安装MySQL
该镜像是centos:7.2.1511镜像离线包,下载该镜像在docker机器上执行命令: cat centos7.2.1511.tar | docker import - centos:7.2.1511