管理连接

要针对 Snowflake 执行语句,首先需要建立连接。Snowflake Node.js 驱动程序允许按如下方式建立连接:

重要

从 Snowflake 8.24 版开始,网络管理员可以选择要求对所有与 Snowflake 的连接进行多因素身份验证 (MFA)。如果您的管理员决定启用此功能,则您必须将您的客户端或驱动程序配置为在连接到 Snowflake 时使用 MFA。有关更多信息,请参阅以下资源:

  • 8.24 版本说明

  • MFA(多重身份验证)

  • 使用 Snowflake MFA 排查服务用户身份验证问题 (https://community.snowflake.com/s/article/Troubleshooting-service-users-authentication-issues-with-Snowflake-MFA) 知识文库文章

创建单个连接

要创建与 Snowflake 的单一连接,请执行以下操作:

  1. 调用 snowflake.createConnection 创建一个新的 Connection 对象,并传入一个指定 :ref:` 连接选项 <label-nodejs_connection_options>` 的 JavaScript 对象。

  2. 使用 Connection 对象,调用 connect 方法建立连接。

    备注

    如果将 authenticator 选项设置为 EXTERNALBROWSER (以便使用 :ref:` 基于浏览器的 SSO <label-nodejs_sso>`)或 :code:` https:// (https://) <okta_account_name> .okta.com ` (以便 :ref:` 通过 Okta 使用本机 SSO <label-nodejs_native_sso>`),请调用 connectAsync 方法,而不是 connect 方法。

    要处理连接错误,请传入具有以下签名的回调函数:

    function(err, conn)
    

    其中:

    • err 是一个 JavaScript Error 对象。

    • conn 是当前的 Connection 对象。

    如果在连接过程中出现错误, connect 方法会将一个 Error 对象传递给回调函数。可以在回调函数中使用此对象来获取有关错误的详细信息。如果需要有关当前 Connection 对象的信息,可以使用传递给回调函数的 conn 实参。

以下示例建立连接并使用密码进行身份验证。要使用其他身份验证方法,请参阅 身份验证选项

// Load the Snowflake Node.js driver.
var snowflake = require('snowflake-sdk');
// Create a Connection object that we can use later to connect.
var connection = snowflake.createConnection({
    account: account,
    username: user,
    password: password,
    application: application
  });
// Try to connect to Snowflake, and check whether the connection was successful.
connection.connect( 
    function(err, conn) {
        if (err) {
            console.error('Unable to connect: ' + err.message);
            } 
        else {
            console.log('Successfully connected to Snowflake.');
            // Optional: store the connection ID.
            connection_ID = conn.getId();
            }
    }
);

创建连接时,可以按照 :ref:` 选项参考 <label-nodejs_connection_options>` 中的描述设置连接选项。

验证连接是否已准备好接收查询

在提交 Snowflake 查询之前,可以使用 connection.isValidAsync() 方法(在版本 1.6.23 和更高版本中)来确保连接已启动并准备好在 Snowflake 上执行请求。如果连接已准备就绪,该方法返回 true,否则返回 false

// Create a Connection object and connect to Snowflake
// ..

// Verify if connection is still valid for sending queries over it
const isConnectionValid = await connection.isValidAsync();

// Do further actions based on the value (true or false) of isConnectionValid

创建连接池

可以定义 Snowflake 连接的缓存,以便根据需要重复使用,而不必在客户端应用程序每次需要访问 Snowflake 时都创建连接。连接池通常可减少建立连接的滞后时间。但是,如果出现 DNS 问题,连接池可能会减慢将客户端故障转移到备选 DNS 的速度。

要创建连接池,请执行以下操作:

  1. 调用 snowflake.createPool(connectionOptions, poolOptions) 创建一个新的 ConnectionPool 对象,并传入两个指定 连接选项 和池选项的 JavaScript 对象。

    备注

    Snowflake Node.js 驱动程序使用开源的 node-pool 库来实施连接池。有关支持的 poolOptions 的信息,请参阅 node-pool 库文档中对 opts 实参的描述。

  2. 使用 ConnectionPool 对象,调用 use 函数为连接池中的单个连接执行语句。

    要处理连接错误,请传入具有以下签名的回调函数:

    function(err, stmt, rows)
    

    其中:

    • err 是一个 JavaScript Error 对象。

    • stmt 是一个包含被执行的 SQL 语句信息的对象,包括语句的字面量文本。

    • rows 是一个包含语句“结果集”的数组。


    如果在执行语句时出错, connect 方法会将一个 Error 对象传递给回调函数。可以在回调函数中使用此对象来获取有关错误的详细信息。

以下示例创建一个支持最多十个活动连接的连接池。它使用密码进行身份验证。要使用其他身份验证方法,请参阅 身份验证选项

// Create the connection pool instance
const connectionPool = snowflake.createPool(
    // connection options
    {
      account: account,
      username: user,
      password: password
    },
    // pool options
    {
      max: 10, // specifies the maximum number of connections in the pool
      min: 0   // specifies the minimum number of connections in the pool
    }
);
  

以下示例使用 connectionPool.use 方法通过池中的连接执行 SQL 语句。clientConnection.execute 方法指定要执行的 SQL 语句并定义回调函数。

// Use the connection pool and execute a statement
connectionPool.use(async (clientConnection) =>
{
    const statement = await clientConnection.execute({
        sqlText: 'select 1;',
        complete: function (err, stmt, rows)
        {
            var stream = stmt.streamRows();
            stream.on('data', function (row)
            {
                console.log(row);
            });
            stream.on('end', function (row)
            {
                console.log('All rows consumed');
            });
        }
    });
});

创建连接池时,可以按照 :ref:` 选项参考 <label-nodejs_connection_options>` 中所述设置连接选项。

处理空闲连接

如果节点池 evictionRunIntervalMillis 选项的默认设置为 0,则不运行空闲连接驱逐检查。如果您的应用程序运行时间更长,这种行为可能会导致终止的连接滞留在连接池中,而当驱动程序获取这些连接并尝试通过它们向 Snowflake 发送查询时,会导致错误。

要在长时间运行的应用程序中解决这种行为,您可以考虑以下处理方法:

  • 创建带已启用的驱逐程序的 Snowflake ConnectionPool

    您可以将 evictionRunIntervalMillis 选项添加到池选项,如以下示例所示:

    const pool = snowflake.createPool(
        {
          account: account,
          username: username,
    
          //rest of the connection options
    
        },
        {
          evictionRunIntervalMillis: 60000 // default = 0, off
          idleTimeoutMillis: 60000, // default = 30000
          max: 2,
          min: 0,
        },
    );
    

    此示例每分钟运行一次驱逐程序,并驱逐空闲时间超过一分钟的所有连接。您可以调整 :codenowrap:`numTestsPerEvictionRun`(默认值:3),更改每次驱逐运行期间检查的资源数量。

    See the node-pool library documentation (https://github.com/coopernurse/node-pool/blob/master/README.md) for details and more options.

  • 确保现有连接在池中处于活动状态

    如果您需要确保连接处于活动状态的频率超过每小时一次,则可以在池选项中添加以下内容:

    • clientSessionKeepAlive: true

    • clientSessionKeepAliveHeartbeatFrequency: n,其中 n 介于 900 秒(15 分钟)与 3600 秒(1 小时)之间(默认值:3600)。

    以下示例每 15 分钟发送一次“保持活动”检测信号,以确保连接处于活动状态,即使没有发生其他活动(例如来自客户端的查询)也会如此。

    const pool = snowflake.createPool(
        {
          account: account,
          username: username,
    
          // rest of the connection options
    
          clientSessionKeepAlive: true,  // default = false
          clientSessionKeepAliveHeartbeatFrequency: 900 // default = 3600
        },
        {
          max: 2,
          min: 0,
        },
    );
    

    您还可以在不使用池中连接的情况下使用 clientSessionKeepAlive 选项。

    有关会话保持活动状态的更多信息,请参阅 Node.js 选项参考

通过代理连接

您可以在创建 Connection 对象时将详细信息作为连接选项提供,通过代理连接到 Snowflake。

以下示例显示如何使用 HTTP 连接到代理:

var connection = snowflake.createConnection({
      account: "account",
      username: "user",
      password: "password",
      proxyHost: "localhost",
      proxyPort: 3128,
});

从版本 1.15.0 开始,Snowflake Node.js 驱动程序完全支持 HTTP_PROXYHTTPS_PROXYNO_PROXY 环境变量,但它们对应的连接参数除外。

默认情况下,新的 useEnvProxy 全局配置设置为 true,这将启用对环境变量的支持。

由于能够在 Connection 对象和环境变量中设置这些代理,驱动程序使用以下层次结构来确定要使用哪些值:

  • 如果 Connection 中定义了代理,则该值优先。驱动程序会忽略 HTTP_PROXYHTTPS_PROXY 环境变量。

  • 如果 Connection 没有设置代理值,则驱动程序会使用 HTTP_PROXYHTTPS_PROXY 环境变量中的值(如果已定义)。

  • 如果 useEnvProxy 连接设置为 false,则驱动程序会忽略 HTTP_PROXYHTTPS_PROXY 环境变量(如果已定义)。

如果要禁用对代理环境变量的支持,您必须在全局配置中将其禁用,如下所示:

const snowflake=require('snowflake-sdk');
snowflake.configure({ useEnvProxy: false });

备注

在 Linux 和 MacOS 上,环境变量区分大小写。在 Windows 上,它们不区分大小写。

  • 如果为相同的环境变量同时定义了小写 (https_proxy) 和大写 (HTTPS_PROXY) 变体,则驱动程序会使用小写 (https_proxy) 变量中的值。

  • 如果仅存在大写 (HTTPS_PROXY) 变体,则驱动程序会使用大写变量的值。

通过经过身份验证的代理进行连接

创建 Connection 对象时,通过提供身份验证凭据作为连接选项,可以通过经过身份验证的代理连接到 Snowflake。

备注

从 Snowflake Node.js 驱动程序版本 1.6.4 开始支持通过经过身份验证的代理服务器进行连接。

以下示例显示如何使用 HTTP 连接到经过身份验证的代理:

var connection = snowflake.createConnection({
      account: "account",
      username: "user",
      password: "password",
      proxyHost: "localhost",
      proxyPort: 3128,
      proxyUser: "myname",
      proxyPassword: "mypass"
});

要使用 HTTPS 连接到经过身份验证的代理,还必须提供 proxyProtocol 连接属性,如下所示:

var connection = snowflake.createConnection({
      account: "account",
      username: "user",
      password: "password",
      proxyHost: "localhost",
      proxyPort: 3128,
      proxyUser: "myname",
      proxyPassword: "mypass",
      proxyProtocol: "https"
});

使用 SnowCD 验证与 Snowflake 的网络连接

配置驱动程序后,可以使用 SnowCD 评估与 Snowflake 的网络连接并进行故障排除。

可以在初始配置过程中使用 SnowCD,也可以根据需要随时使用,以评估与 Snowflake 的网络连接并进行故障排除。

OCSP(在线证书状态协议)

当驱动程序发起连接时,Snowflake 会发送一个证书,确认其要连接的是 Snowflake 而不是冒充 Snowflake 的主机。驱动程序将该证书发送到 OCSP(在线证书状态协议)服务器,验证该证书是否被撤消。

如果驱动程序无法访问 OCSP 服务器来验证证书,则驱动程序可以 “故障打开”或“故障关闭”

终止连接

通过调用 connection.destroy() 方法可以终止连接。这将立即结束与连接关联的会话,而无需等待运行语句完成:

connection.destroy(function(err, conn) {
  if (err) {
    console.error('Unable to disconnect: ' + err.message);
  } else {
    console.log('Disconnected connection with id: ' + connection.getId());
  }
});