C# SSH.NET - one SSH connection vs multiple SSH connections

时间:2019-01-09 21:57:25

标签: c# mysql database ssh ssh.net

I have a C# application which uses the SSH.NET library to connect to a server. The application executes SQL commands to the database through multiple methods.

Is it better to have one long-running SSH connection that encompasses all SQL commands, eg:

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();
        }
    }
}

Or to open an SSH connection at the start of each SQL statement?

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();
        }
    }
}

The server is known to sometimes drop connections, so I imagine the second method is better in terms 'cleaner' logic for re-establishing a connection? Or are there any other better ways for reconnecting?

1 个答案:

答案 0 :(得分:4)

第1部分:最小化连接寿命。

使用 SQL连接的常见“最佳做法”是您要最小化连接打开时间-这意味着您在执行查询之前就打开了连接然后关闭它。 SSH连接也是如此。

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

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

如果SQL查询事务中的单个语句失败,则事务将失败。您要失败,请回滚错误ex:断开连接之前的状态数据库,然后稍后重试。

如果不需要记录错误,则可以使用set xact_abort on,在发生错误(例如:超时或断开连接)的情况下事务自动回滚之前。

更多信息

第3部分:创建重试策略

通常,最佳实践是您不想避免失败,而是接受失败,快速失败,并有办法重试。您选择哪种策略重试由您决定。

如果您想做比手动重试更复杂的事情,那么我建议您看一下Rx observable(反应性扩展)或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));