C# SSH.NET - 一个 SSH 连接与多个 SSH 连接

use*_*948 1 c# mysql database ssh ssh.net

我有一个使用SSH.NET的 C# 应用程序库连接到服务器。应用程序通过多种方式对数据库执行 SQL 命令。

拥有一个包含所有 SQL 命令的长时间运行的 SSH 连接是否更好,例如:

using (var sshClient = getSshClient()))
{
    sshClient.Connect();

    if (sshClient.IsConnected)
    {
        using (var portForward = setupPortForward()))
        {
            sshClient.AddForwardedPort(setupPortForward());
            portForward.Start();

            // Start SQL commands

            if (!sshClient.IsConnected) {
                sshClient.Connect();
            }
            else {
                executeSQLCommand1();
            }

            if (!sshClient.IsConnected) {
                sshClient.Connect();
            }
            else {
                executeSQLCommand2();
            }

            // End SQL commands

            portForward.Stop();
            sshClient.Disconnect();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者在每个 SQL 语句的开头打开一个 SSH 连接?

using (var sshClient = setupSshClient()))
{
    sshClient.Connect();

    if (sshClient.IsConnected)
    {
        using (var portForward = setupPortForward()))
        {
            sshClient.AddForwardedPort(portForward);
            portForward.Start();

            executeSQLCommand1();

            portForward.Stop();
            sshClient.Disconnect();
        }
    }
}

using (var sshClient = setupSshClient()))
{
    sshClient.Connect();

    if (sshClient.IsConnected)
    {
        using (var portForward = setupPortForward()))
        {
            sshClient.AddForwardedPort(portForward);
            portForward.Start();

            executeSQLCommand2();

            portForward.Stop();
            sshClient.Disconnect();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

众所周知,服务器有时会断开连接,所以我想第二种方法在重新建立连接的“更干净”逻辑方面更好?或者有没有其他更好的方法重新连接?

Mar*_*gus 5

第 1 部分:最小化连接生命周期。

SQL 连接的一个常见“最佳实践”是您希望最小化连接打开时间- 这意味着您在执行查询之前打开连接并在之后关闭它。这同样适用于SSH 连接

使用后没有处理的悬空资源有一个名称,它们被称为内存泄漏

第 2 部分:使用事务来确保数据库状态的一致性

如果 SQL 查询事务中的单个语句失败,则事务将失败。您想要失败,请回滚 DB 在错误之前所处的状态,例如:连接断开并稍后重试。

如果您不需要记录错误,那么您可以set xact_abort on在事务之前使用自动回滚以防出现错误,例如:超时或断开连接。

欲了解更多信息

第 3 部分:创建重试策略

通常,最佳做法是您不想避免失败,而是要接受失败,快速失败并有办法再试一次。您为重试选择哪种策略取决于您。

如果你想做比手动重试更复杂的事情,那么我建议你看看 Rx observable (reactive extension) 或 Polly。它确实有一点学习曲线,但你已经习惯了。

 // Policy to retry 5 times, waiting {2, 4, 8, 16, 32} seconds between retries.
 var policy = Policy
   .Handle<SqlException>()
   .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

 policy.Execute(() => UpdateDatabase1(obj1));
Run Code Online (Sandbox Code Playgroud)