The Network Adapter could not establish the connection问题研究
最近一个项目会报上述错误,但也不是经常发生,所以很难跟踪,影响不是很大,但每次看到日志中这个错误就会不舒服,还是要想办法解决才是。
- 错误提示信息很明确是网络适配器不能创建连接。
查了很多资料,并且Oracle官网也有说明并且列举了可能产生这种问题的原因,但是如何规避还是不知所措。其中涉及到Oracle MTS模式、IPv4、IPv6、JVM,最有可能原因是Oracle服务器支持IPv4和IPv6网卡,所以可能同时提供了这两种连接服务,而JDBC客户端连接时也支持IPv4和IPv6,猜测IPv4服务不能对IPv6请求服务,所以报错。
- 要解决这种时隐时现的问题,很重要一个方法则是能方便重现。
多次尝试,终于在并发线程提高到500时,重新了错误。并且也得到SQLException的ErrorCode:17002。这个错误信息和Oracle官网提示是一样的了。
然后按照猜测进一步去解决问题。
- 把涉及到点先搞明白,最关键两点:
Oracle MTS模式和Dedicated模式,
MTS模式:Dispatch进程将Client Connection Request,进行排队,由后台多个Shared Server并行处理排队的请求。所以如果存在Client Request请求处理耗时过长,则整体处理效率就会下降。
Dedicated模式:会为每个Client Connection Request分配专门进程进行处理,所以该模式更适应于请求处理时间较长,请求数相对较少情况。
客户采用的Oracle配置方式是MTS模式。Oracle官网介绍这种情形下JDBC程序可能会产生这个错误。
IPv4、IPv6,
IPv4、IPv6它们分别是两种寻址协议,由于IPv4的局限性和缺点,所以产生了IPv6,简言之:IPv6迟早是要替代IPv4的,然而由于历史原因,它们是要共存一段时间的,但是共存期间它们又存在互相通信的需求,所以就产生了一系列解决方案,无论哪种方案都离不开这两种协议的互转,不是你转成它就是它转成你,总之是翻译成一致后才能互相交流。
- 据Oracle所述:Java在1.4版本后加入了对两种协议的支持,其中Windows平台是Java5版本后才支持的。Java在检测到OS支持双协议时优先采用IPv6进行通信,除非显式指定采用哪种协议。
到目前为止,算是知道Oracle官方明确提示这个问题是可能产生的,并且罗列了产生的情景,以及解决方法。这时问题应该能解决才对。
首先对于Oracle两种模式,Oracle提示可以通过在JDBC连接符中知指定参数使程序固定采用Dedicated模式,并且JVM也提供参数可以指定程序固定采用IPv4进行通信,分别尝试了两种方法仍然不行。无奈,固才有此文诞生。
但还是得要解决问题啊,,,重新找分析原因。
- 无奈再出发,完整异常堆栈:
java.sql.SQLException: Io 异常: The Network Adapter could not establish the connection
ErrorCode:17002 SQLState:null Io 异常: The Network Adapter could not establish the connection
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:162)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:274)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:328)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:348)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:151)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:563)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at com.sfit.dorado.utils.BaseDaoTest.getConnection(BaseDaoTest.java:30)
at com.sfit.dorado.utils.BaseDaoTest$1.run(BaseDaoTest.java:71)
关键点oracle.jdbc.driver.T4CConnection.logon,即通过Oracle用户名密码去获取连接,无法建立连接。也许真的是达到可以创建的最大连接数了。
降低并发量再测试,300并发只出现一次没拿到连接,再来2次300并发测试都是最多一次错误,说明还真的可能达到上限了。加到400测试2次,出现一次以上错误。加到500测试,除上述错误,还出现了另外错误,
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found
The Connection descriptor used by the client was:
(description=(address=(host=172.19.124.3)(protocol=tcp)(port=1521))(connect_data=(sid=ctp))(SERVER=DEDICATED)) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:280)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:328)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:348)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:151)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:563)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at com.sfit.dorado.utils.BaseDaoTest.getConnection(BaseDaoTest.java:30)
at com.sfit.dorado.utils.BaseDaoTest$1.run(BaseDaoTest.java:71)
所以猜测采用200并发测试,多次测试均能正常通过。结果错误频发。
降低至50个并发,7次测试,1次出现1个错误,6次全通过。
补充,以上测试均采用固定IPv4即指定了运行参数-Djava.net.preferIPv4Stack=true,并且程序指定dedicated模式,每次测试,持有连接20s。
去掉-Djava.net.preferIPv4Stack=true参数,7次100并发测试,2次出现1个错误,2次2个错误,3次全通过。
去掉IPv4参数,再去掉连接符中指定Dedicated模式测试,7次100并发测试,7次全通过。7次200并发测试,1次出现1个错误,6次全通过。
上述测试情况正好印证了MTS模式和Dedicated模式的优缺点以及分别适应的场景。
结合目前客户Oracle数据库使用情况,大概有10个维护人员通过PLSQL使用数据库,10个人开发人员在通过Tomcat使用数据库,2个WEB系统使用数据库,WEB系统启动过程时会较长时间持有数据库连接进行初始化数据;WEB系统采用数据库连接池机制,启动时初始化4个连接池,以前每个连接池初始化连接50,最大100个(会经常报上述错误),优化后开发人员每个连接池分配5个连接,最多10个,部署的WEB系统为10-30个。
这么分析话,目前偶尔报无法建立连接的错误算是正常了。
真的要进一步优化,就要在Oracle配置上面花费些功夫了。
补充:有些论坛提供的IP地址添加到host文件中解决了问题,也是因为那情那景下添加了IPv4地址到host文件,所以采用IPv4通信了。
连接池数量不够用时也会报这个错误。
终于想通了。
The Network Adapter could not establish the connection问题研究的更多相关文章
- Io 异常: The Network Adapter could not establish the connection 解决方法
1.IP错误: 在设置URL时错误,例如:jdbc:oracle:thin:@192.168.1.80:1521:orcl 数据库服务器是否正确:ping 服务器IP是否通畅.ping不通则将URL更 ...
- 数据库连接报错之IO异常(The Network Adapter could not establish the connection)
Io 异常: The Network Adapter could not establish the connection 有以下四个原因: 1.oracle配置 listener.ora 和tnsn ...
- Io 异常: The Network Adapter could not establish the connection
新接触一个项目,导入源码,在本地启动的时候后台报了一个错误: Could not discover the dialect to use. java.sql.SQLException: Io 异常: ...
- IO 异常:The Network Adapter could not establish the connection 怎么解决
IO 异常:The Network Adapter could not establish the connection 怎么解决
- weblogic报错----Received exception while creating connection for pool "TDMSKD": The Network Adapter could not establish the connection
<2017-8-16 上午08时58分37秒 CST> <Info> <WebLogicServer> <BEA-000377> <Startin ...
- Oracle安装后遇到错误:The Network Adapter could not establish the connection
http://note.youdao.com/noteshare?id=e6baee7ea7b7f60d7a265124e2bdd46c&sub=988945C6DDE843D5A7D6588 ...
- sqldeveloper建立新的连接是出现Status : Failure -Test failed: IO Error: The Network Adapter could not establish the connection
Status : Failure -Test failed: IO Error: The Network Adapter could not establish the connection解决办法: ...
- Io 异常: The Network Adapter could not establish the connection解决方案
Io 异常: The Network Adapter could not establish the connection解决方案 2016年06月04日 13:30:21 阅读数:46589 Io ...
- sql developer链接不上oracle 报 The Network Adapter could not establish the connection
安装时候报 : Oracle 支持在具有 DHCP 分配的公共 IP 地址的系统上进行安装.但应使用静态 IP 地址来配置系统的主网络接口, 以便 Oracle 软件正常工作.有关在配置有 DHCP ...
随机推荐
- java提高篇---HashTable
在java中与有两个类都提供了一个多种用途的hashTable机制,他们都可以将可以key和value结合起来构成键值对通过put(key,value)方法保存起来,然后通过get(key)方法获取相 ...
- Java中的内部类与匿名内部类总结
内部类 内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类 如同一个人是由大脑.肢体.器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液.跳动) ...
- EasyUI-标签(Tabs)用法
用法示例 创建tabs 1. 经由标记创建Tabs 从标记创建Tabs更容易,我们不需要写任何JavaScript代码.记住把 'easyui-tabs' 类添加到<div/>标记,每个t ...
- 2016年12月15日 星期四 --出埃及记 Exodus 21:10
2016年12月15日 星期四 --出埃及记 Exodus 21:10 If he marries another woman, he must not deprive the first one o ...
- 2016年6月24日 星期五 --出埃及记 Exodus 14:21
2016年6月24日 星期五 --出埃及记 Exodus 14:21 Then Moses stretched out his hand over the sea, and all that nigh ...
- hahaha
[问题描述] 小Q对计算几何有着浓厚的兴趣.他经常对着平面直角坐标系发呆,思考一些有趣的问题.今天,他想到了一个十分有意思的题目: 首先,小Q会在x轴正半轴和y轴正半轴分别挑选n个点.随后,他将轴的点 ...
- Mac 下Cordova开发
一 Cordova开发环境搭建 1,安装node.js环境 官网: http://nodejs.org/ 下载包安装 2,使用命令行安装 cordova 主要命令: 安装Cordova: sudo ...
- 无法为表空间 XX 中的段创建 INITIAL 区
select * from dba_data_files where TABLESPACE_NAME='XX'--找到表空间文件 alter database datafile '/opt/app/o ...
- 在包a中新建一个类A,在类A中有一个int add(int m)方法,用来求1+2+…+m 的和。在包b中新建一个类B,在类B中有一个int cheng(int n)方法,用来求n! 的结果。在包c中新建一个主类C,调用A、B中的方法输出1+2+…+30的和, 以及5!的计算结果。
package a; public class A { public void add(int m) { int sum=0; for (int i = 1; i <=m; i++) { sum ...
- C#中获取程序集版本号的方法
我的方法: string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); 方法一: public v ...