简体   繁体   English

Hive JDBC - getConnection失败时的连接泄漏

[英]Hive JDBC - connection leakage when getConnection fails

I am using cloudera hive jdbc https://www.cloudera.com/downloads/connectors/hive/jdbc/2-6-2.html 我正在使用cloudera hive jdbc https://www.cloudera.com/downloads/connectors/hive/jdbc/2-6-2.html

Sometimes, when the calling of getConnection() fails (not always, depends on server stability), it shows this exception: 有时,当调用getConnection()失败时(并非总是如此,取决于服务器稳定性),它会显示以下异常:

MyDAO - Cannot create connection from DataSource@21f421b8 
at com.cloudera.hiveserver2.hivecommon.api.HS2Client.closeSession(Unknown Source)
at com.cloudera.hiveserver2.hivecommon.core.HiveJDBCCommonConnection.establishConnection(Unknown Source)
at com.cloudera.hiveserver2.jdbc.core.LoginTimeoutConnection.connect(Unknown Source)
at com.cloudera.hiveserver2.jdbc.common.BaseConnectionFactory.doConnect(Unknown Source)
at com.cloudera.hiveserver2.jdbc.common.AbstractDataSource.getSimbaConnection(Unknown Source)
at com.cloudera.hiveserver2.jdbc.common.AbstractDataSource.getConnection(Unknown Source)

And when I check with netstat cmd: 当我用netstat cmd检查时:

netstat -an --tcp --program

There's a new socket connection established, I have to wait about 1 hour then see that tcp connection gone. 建立了一个新的套接字连接,我必须等待大约1小时,然后看到tcp连接消失了。

The question is: 问题是:

  1. Why when I call getConnection(), the closeSession() is called? 为什么当我调用getConnection()时,会调用closeSession()?
  2. Is it because the closeSession() fails, the tcp connection cannot be released? 是因为closeSession()失败了,tcp连接无法释放? Is it considered as a connection leakage? 它被认为是连接泄漏吗?

I decompiled the driver, check the H2SClient class: 我反编译驱动程序,检查H2SClient类:

public void closeSession() throws ErrorException {
    if (this.m_hasOpenSession) {
        try {
            TCloseSessionReq var1 = new TCloseSessionReq();
            var1.setSessionHandle(this.m_openSessionResp.getSessionHandle());
            this.m_client.CloseSession(var1);
            if (null != this.m_client && null != this.m_client.getInputProtocol() && null != this.m_client.getInputProtocol().getTransport()) {
                this.m_client.getInputProtocol().getTransport().close(); //line 8
            }

            this.m_hasOpenSession = false;
        } catch (Exception var3) {
            ErrorException var2 = HiveJDBCCommonDriver.s_HiveMessages.createGeneralException(HiveJDBCMessageKey.CONN_SESSION_ERR.name(), "Close Session Error");
            var2.initCause(var3);
            throw var2;
        }
    }

}

If there is any exception which makes the line 8 cannot be reached, the socket connection is not closed. 如果存在任何导致无法到达线路8的异常,则不会关闭套接字连接。 That closing should be called also in catch block or finally block: 关闭也应该在catch块或finally块中调用:

public void closeSession() throws ErrorException {
    if (this.m_hasOpenSession) {
        try {
            TCloseSessionReq var1 = new TCloseSessionReq();
            var1.setSessionHandle(this.m_openSessionResp.getSessionHandle());
            this.m_client.CloseSession(var1);

            var2.initCause(var3);
            throw var2;
        } finally {
            if (null != this.m_client && null != this.m_client.getInputProtocol() && null != this.m_client.getInputProtocol().getTransport()) {
                this.m_client.getInputProtocol().getTransport().close(); //line 8
            }   
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM