Kyuubi服务源码解析:OpenSession解析

  在Kyuubi服务源码解析:FrontendService一文解析HiveConnection的构造函数时,有一行代码是openSession(),现在来解析一下。

Client端OpenSession解析

HiveConnection.java:

  • openSession()方法
  private void openSession() throws SQLException {
    TOpenSessionReq openReq = new TOpenSessionReq();
    ***省略部分代码***
    try {
      //Client远程调用Server端的OpenSession方法
      TOpenSessionResp openResp = client.OpenSession(openReq);

      // validate connection
      Utils.verifySuccess(openResp.getStatus());
      if (!supportedProtocols.contains(openResp.getServerProtocolVersion())) {
        throw new TException("Unsupported Hive2 protocol");
      }
      protocol = openResp.getServerProtocolVersion();
      sessHandle = openResp.getSessionHandle();
      ***省略部分代码***
    } catch (TException e) {
      LOG.error("Error opening session", e);
      throw new SQLException("Could not establish connection to "
          + jdbcUriString + ": " + e.getMessage(), " 08S01", e);
    }
    isClosed = false;
  }

  TOpenSessionResp openResp = client.OpenSession(openReq);
  这句代码中,client的类型是TCLIService.Iface,TOpenSessionResp和TCLIService都是由Thrift文件生成的类:

Kyuubi服务源码解析:OpenSession解析_第1张图片

  Thrift是跨语言的RPC框架,也就是能够远程调用函数。
   client.OpenSession(openReq)实际上调用的是Server端的OpenSession()方法,这个Server端也就是Kyuubi(当然也可以是Hiveserver2)。
  接下来我们看一下Server端的OpenSession方法。


Server端OpenSession解析

FrontendService.scala:

  再看一下FrontendService的类声明:

private[kyuubi] class FrontendService private(name: String, beService: BackendService)
  extends AbstractService(name) with TCLIService.Iface with Runnable with Logging 

  FrontendService实现了TCLIService.Iface接口,上文client.OpenSession(openReq)这个client的类型也是TCLIService.Iface。然后看一下FrontendService的OpenSession方法:

  • OpenSession()方法
  override def OpenSession(req: TOpenSessionReq): TOpenSessionResp = {
    info("Client protocol version: " + req.getClient_protocol)
    val resp = new TOpenSessionResp
    try {
      val sessionHandle = getSessionHandle(req, resp)
      resp.setSessionHandle(sessionHandle.toTSessionHandle)
      // resp.setConfiguration(new Map[String, String]())
      resp.setStatus(OK_STATUS)
      val context = currentServerContext.get
        .asInstanceOf[FrontendService#FeServiceServerContext]
      if (context != null) {
        context.setSessionHandle(sessionHandle)
      }
    } catch {
      case e: Exception =>
        warn("Error opening session: ", e)
        resp.setStatus(KyuubiSQLException.toTStatus(e))
    }
    resp
  }

  实际上FrontendService重写了TCLIService.Iface的OpenSession方法,JDBC client调用的也正是Server端这个重写的OpenSession方法。
  关于Thrift远程调用不理解的同学可以参考这篇博文:thrift远程调用示例。

你可能感兴趣的:(Kyuubi服务源码解析:OpenSession解析)