近期发现生产环境一业务应用系统,不定时发生数据库连接断开,再次请求后正常连接问题。
系统日志中具体错误信息如下:ORA-03135: 连接失去联系\n进程 ID: 9349\n会话 ID: 2834 序列号: 64475"。
oracle版本:11.2.0.4
日志信息:

错误信息:ORA-03135: 连接失去联系

堆栈信息: at Oracle.ManagedDataAccess.Client.OracleException.HandleError(OracleTraceLevel level, OracleTraceTag tag, Exception ex)

at OracleInternal.TTC.TTCExecuteSql.ReceiveExecuteResponse(Accessor[]& defineAccessors, Accessor[] bindAccessors, Boolean bHasReturningParams, SQLMetaData& sqlMetaData, SqlStatementType statementType, Int64 noOfRowsFetchedLastTime, Int32 noOfRowsToFetch, Int32& noOfRowsFetched, Int64& queryId, Int32 longFetchSize, Int64 initialLOBFetchSize, Int64[] scnFromExecution, Boolean& bAllPureInputBinds, DataUnmarshaller& dataUnmarshaller, MarshalBindParameterValueHelper& marshalBindParamsHelper, Int64[]& rowsAffectedByArrayBind, Boolean bDefineDone, Boolean& bMoreThanOneRowAffectedByDmlWithRetClause, List`1& implicitRSList, Boolean bLOBArrayFetchRequired)

at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Int64& internalInitialLOBFS, OracleException& exceptionForArrayBindDML, Boolean isDescribeOnly, Boolean isFromEF)

at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)

at Oracle.ManagedDataAccess.Client.OracleDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)

ORA-03135出现的原因较多,问题有可能出在网络设备、操作系统、数据库上,最有可能是由于网络和防火墙配置所导致。

解决方案:
经与网络组工程师沟通确认,当前防火前未开启长连接设置,开启后此问题解决。

补充一下长连接和短连接的概念:

①长连接的概念

长连接功能用于设置特定数据流的超长保持时间,让数据流的会话连接保持时间不受全局老化时间限制。其实这项特殊业务与目前业界的状态防火墙的实现机制是存在矛盾的。

为保证内部网络的安全,防火墙上的各会话缺省保持时间都相对较短,例如:缺省情况下,TCP的保持时间为1200s,UDP的保持时间为120s。

正常情况下,当一个TCP会话的两个连续报文到达防火墙的时间间隔大于该会话的保持时间时,为保证网络的安全性,防火墙将从会话表中删除相应会话信息。后续报文到达防火墙后,防火墙根据自身的转发机制,丢弃该报文,导致连接中断。在实际应用中,用户需要查询服务器上的数据,这些查询时间间隔远大于TCP/UDP默认的会话保持时间。此时需要在防火墙上保持TCP连接一段相对较长的时间。当某会话的报文长时间没有到达防火墙后再次到达时,仍然能够通过防火墙,这种技术就是长连接。

②短连接的概念

某些应用频繁发起连接,如果不缩短其会话保持时间,则会使防火墙的会话数爆涨,进而拖垮防火墙。保持太多的会话对防火墙没有必要,相反,当系统资源过多地用在会话保持的话,会相应损害每秒生成会话的能力,这是一个同样重要的性能指标。设定过高的会话数量,却降低了每秒生成会话的能力,其结果,只能是保留一些永远用不到的会话虚数而已。

因此,我们可以根据网络应用环境的实际需求,缩短某些会话的保持时间,从而减少防火墙的工作负荷,提高网络性能。

长、短连接参考资料:

https://www.cnblogs.com/lcplcpjava/p/6581179.html

小知识贴士:
oracle 本地登录的方式登录oracle服务端:sqlplus "/as sysdba",不需要用户名密码即可登录。
禁用方法:

1.linux下

转到目录$ORACLE_HOME/network/admin下,

cd $ORACLE_HOME/network/admin

vi sqlnet.ora

在文件sqlnet.ora中,增加一行即可:

sqlnet.authentication_services=(none)

如果应用程序时不时地报错“ORA-03135连接失去联系”,该问题可能与sqlnet.ora设置参数SQLNET.EXPIRE_TIME 有关

在文件sqlnet.ora中,增加一行,单位分钟:

SQLNET.EXPIRE_TIME = 10

2.windows下

SQLNET.AUTHENTICATION_SERVICES= (NTS)是基于操作系统验证;

SQLNET.AUTHENTICATION_SERVICES= (NONE)是基于Oracle验证;

SQLNET.AUTHENTICATION_SERVICES= (NONE,NTS)是二者共存。