Может ли этот код убить мой сервер? - PullRequest
1 голос
/ 18 октября 2010

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

System.Data.SqlClient.SqlException: истекло время ожидания. Период ожидания истек до завершения операции или сервер не отвечает.

Этим утром я попробовал тест, в котором отключил пул в строке подключения, это также не сработало.

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

Вот один из них

public static List<Member> AllMembers
{
    get
    {
        if (HttpRuntime.Cache["Members"] != null)
        {
            return (List<Member>)HttpRuntime.Cache["Members"];
        }
        else
        {
            GetAllMembers();
            return (List<Member>)HttpRuntime.Cache["Members"];
        }
    }
}

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

Теперь это веб-приложение, и, поскольку мой трафик все время увеличивается,

Могут ли мои свойства быть причиной?

Любая помощь наиболее ценится

Truegilly

Ответы [ 3 ]

6 голосов
/ 18 октября 2010

Предполагая, что вы утилизируете все правильно, у меня есть альтернативное объяснение:

Если кэш пуст / истек и несколько страниц пытаются вызвать AllMembers одновременно, то каждая страница может закончитьсявызов GetAllMembers() одновременно, замедление запроса к базе данных.Это может привести к порочному циклу, если время начала вызовов истечет.

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

private static object _allMembersLock = new object();
public static List<Member> AllMembers
{
    get
    {
        lock (_allMembersLock)
        {
            List<Member> members = (List<Member>)HttpRuntime.Cache["Members"];
            if (members == null)
            {
                members = GetAllMembers();
                HttpRuntime.Cache["Members"] = members;
            }
            return members;
        }
    }
}
1 голос
/ 18 октября 2010

Всего несколько обычных подозреваемых:

  1. Вы утилизируете все свои SqlCommand'ы и читатели?

  2. Вы распределяете / закрываете SqlConnection?

  3. Может ли ваша база данных справиться с нагрузкой? У вас там проблемы с производительностью?

Код из вашего поста не похож на проблему.

0 голосов
/ 18 октября 2010

Я не вижу здесь никакой защиты от множественных одновременных вызовов геттера, вызывающих GetAllMembers. Конечно, вы хотите, чтобы только один поток за один раз загружал свойство. Требуется какой-то lock().

Вы должны убедиться, что код, который очищает кэш, также использует тот же lock().

Если этот код можно вызывать с нескольких серверов, вам также необходимо убедиться, что любая программная логика на стороне базы данных (хранимые процедуры или динамический SQL от клиента), которая лежит в основе GetAllMembers, эффективно и правильно обрабатывает несколько одновременных считывателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...