C# SSH.NET - одно соединение SSH против нескольких соединений SSH

У меня есть приложение C#, которое использует библиотеку SSH.NET для подключения к серверу. Приложение выполняет команды SQL для базы данных несколькими способами.

Лучше ли иметь одно продолжительное SSH-соединение, которое охватывает все команды SQL, например:

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

Или открыть соединение SSH в начале каждого оператора SQL?

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

Известно, что иногда сервер сбрасывает соединения, поэтому я полагаю, что второй метод лучше с точки зрения "более чистой" логики для восстановления соединения? Или есть какие-то другие лучшие способы для повторного подключения?

1 ответ

Часть 1. Минимизируйте время жизни соединения.

Распространенная "лучшая практика" для SQL-соединений заключается в том, что вы хотите минимизировать время открытия соединения - это означает, что вы открываете соединение непосредственно перед выполнением запроса и закрываете его сразу после этого. То же относится и к SSH-соединениям.

У висящих ресурсов, которые вы не утилизируете после их использования, есть имя, и они называются утечками памяти.

Часть 2. Использование транзакций для обеспечения согласованности состояния БД

Если в ваших транзакциях SQL-запросов произойдет сбой одного оператора, транзакция завершится неудачей. Если вы хотите потерпеть неудачу, откатите состояние БД до того, как возникла ошибка ex: соединение разорвалось, и повторите попытку позже.

Если вам не нужна регистрация ошибок, то вы можете использовать set xact_abort on до того, как ваша транзакция автоматически откатится в случае ошибки, например: timeout или сбросьте соединение.

Для получения дополнительной информации

Часть 3. Создание политики повторных попыток

Как правило, лучшая практика заключается в том, что вы не хотите избегать неудачи, а вместо этого принимаете ее, быстро терпите неудачу и можете попробовать еще раз. Какую политику вы выбираете для повторной попытки, зависит от вас.

Если вы хотите сделать что-то более сложное, чем ручная повторная попытка, тогда я бы порекомендовал вам взглянуть на Rx наблюдаемый (реактивное расширение) или Полли. У этого есть немного кривой обучения, но вы привыкаете к этому.

 // 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));
Другие вопросы по тегам