asp.net, сервер состояний, NLB, сеанс потерян
1-й пост на stackru, надеюсь, что вы получите отличные отзывы:)
В настоящее время я пытаюсь сбалансировать нагрузку нашего веб-сайта. Мы установили NLB на 2 кластера на Windows Server 2003 с IIS 6.
Во время тестирования установки я обнаружил, что иногда наша сессия теряется. Через полтора дня вот результат:
- Да, наш machine.config имеет одинаковый ключ шифрования / дешифрования.
- Да, идентификатор в iis metabase.xml одинаков для обеих машин. На самом деле, весь файл одинаков, за исключением "AdminACL".
- Оба веб-приложения установлены с помощью "StateServer", и оба указывают на один и тот же компьютер.
С этого момента поиск в Google дает меньше информации и возможных решений.
Из того, что я знаю, нет конкретного шаблона, который вызывает эту проблему. Это просто случается время от времени.
Пытаясь найти проблему, я увидел, что запрос отправил файл cookie идентификатора сеанса asp на сервер, но сервер не сопоставил его с сеансом пользователя.
Таким образом, запрос номер x был отправлен от клиента, с куки, сеанс был сопоставлен, и все прошло гладко. Номер запроса x+1 был отправлен клиентом с файлом cookie, но сеанс не найден.
Оба запроса были сделаны на одной машине в NLB.
Вот фрагмент asp trace.axd:
1-й запрос:
Детали запроса Идентификатор сеанса: j2ffvy45updpc52uhw1mbg55 Тип запроса: GET Время запроса: 26.11.2008 14:58:06 Код состояния: 200 Кодировка запроса: Unicode (UTF-8) Кодировка ответа: Unicode (UTF-8)
Запрос коллекции куки
Имя Значение Размер
ASP.NET_SessionId j2ffvy45updpc52uhw1mbg55 42 AID 22 9
Коллекция Ответных Куки
Имя Значение Размер
Коллекция заголовков
Имя Значение
Cookie ASP.NET_SessionId=j2ffvy45updpc52uhw1mbg55; АИД =22
2-й запрос:
Детали запроса Идентификатор сеанса: Тип запроса: POST Время запроса: 26.11.2008 14:58:08 Код состояния:
Кодировка запроса: Unicode (UTF-8) Кодировка ответа:
Запрос коллекции куки
Имя Значение Размер
Коллекция Ответных Куки
Имя Значение Размер
Имя коллекции значений заголовков Cookie ASP.NET_SessionId=j2ffvy45updpc52uhw1mbg55; АИД =22
Как вы можете видеть во втором запросе, файл cookie отправляется клиентом, но asp, похоже, никогда не добавляет файлы cookie в свою "Коллекцию файлов cookie". Я думаю, именно поэтому он не находит сессию.
Так почему же cookie не отображается в сеансе? Это проблема? Проблема в другом месте?
Не стесняйтесь спрашивать любые разъяснения.
Спасибо всем за ваш отзыв.
JF
8 ответов
Я наконец нашел ответ на свою проблему. Его происхождение находится в коде приложения (например, 99% ошибок программистов сторонних разработчиков). Я решил опубликовать его в любом случае, если кто-то находится в подобном сценарии.
Этот код был частью класса WebServiceRequester. Класс запросчика веб-службы был создан при создании сеанса и сохранен в сеансе. Во время создания мы инициализируем член m_webServiceURL, и этот член сохраняется в сеансе после. При каком значении этот элемент инициализировался в зависимости от настроек на локальной машине.
Важной частью является следующее: класс WebServiceRequester содержит объекты WebService. Объекты WebService не могут быть сохранены в сеансе, они не сериализуются в asp. Свойство имеет атрибут [NonSerialized]. Поэтому каждый раз, когда мы обращались к свойству "WebService" объекта для первого в течение жизненного цикла страницы, нам приходилось создавать новое и присваивать ему URL-адрес "m_webServiceURL", который был сохранен в сеансе. Итак, вы видите, новый объект веб-сервиса, возможно, на другой машине, что означает разные настройки на каждой машине.
Итак, вот что случилось: поле 29 было установлено для доступа к веб-службе на локальном хосте
поле 30 было установлено для доступа к веб-службе как 192.168.253.29.
Технически они оба установлены на одной машине. Но вот сценарий:
войдите в систему в окне 29. m_webServiceURL установлен на локальный хост в сеансе.
[запрос на вставку 29 здесь]
Балансировка NLB приводит нас к блоку 30. Блок 30 загружает его сеанс, создает новый объект веб-сервиса с localhost в качестве адреса веб-сервиса. Блок 30 сделал запрос к неправильному веб-сервису, что привело к исключению Session Expired.
Одной из проблем во время отладки было то, что локальная связь не была записана с помощью сетевого монитора.
Что привело меня в трассировку, так это то, что мы никогда не регистрировали исключение в окне трассировки журнала 29, как это должно было быть.
Спасибо всем за предложения, это было действительно оценено.
Хорошего дня. JF
Что ж, если вы используете Visual Studio, вы можете по крайней мере протестировать его с MSDE (урезанная версия SQL Server, которая поставляется с Visual Studio)...
Это может помочь исключить проблемы с сервером состояний...
Я буду хромым и повторю предложение MS SQL Server. Установите SQL Server Express, который полностью бесплатен, в том числе для коммерческого использования, и имеет только 3 недостатка, которые не должны быть проблемой для вас на этом этапе:
- Максимальный размер базы данных 4 ГБ
- Макс. 1 ядро процессора используется
- Макс 1 ГБ ОЗУ используется
Не совсем ответ на ваш вопрос, но пробовали ли вы использовать хранилище сеансов на основе сервера sql? (Ищите в MSDN постоянный скрипт, а не временный скрипт, который поставляется с asp.net)
Я слышал "плохие вещи" о исполняемом сервисе сеанса и, следовательно, не использовал его. Никогда не было проблем с веб-фермерством с помощью решения на основе сервера sql.
Извините, это не совсем ответ на вашу проблему, но он должен либо (а) исправить ее, либо (б) значительно сузить ее.
Несколько моментов, которые следует принять во внимание:
- Какая нагрузка на ваш сайт? State Server имеет тенденцию падать, когда сталкивается с большим количеством одновременных попаданий. Мы используем его только в тех случаях, когда у нас действительно небольшое количество пользователей (в 10-х, в основном, бэкэнд-систем). Всякий раз, когда мы пытались использовать его в работе для сайтов, обслуживающих тысячи пользователей ежедневно, это приводило к сбою, приводившему к потере данных сеанса.
- В одной из производственных сред, которыми мы управляем, мы используем MSSQL 2005 Express для управления сеансами, на сайте более 10 000 пользователей в день и 200 000 страниц в день. Это рекомендуемый подход в случае, когда сессия является обязательной и тесно связана с вашим приложением.
Если вы собираетесь использовать MSSQL Express в качестве своей базы данных состояний, помните, что она не поставляется с агентом SQL Server, что означает, что в фоновом режиме нет планировщика задач, выполняющего очистку сеансов с истекшим сроком действия. Я бы порекомендовал найти планировщик и периодически запускать хранимую процедуру чистых сеансов с истекшим сроком действия.
Удачи
Вместо того, чтобы возиться с SQL, отправьте свои тесты непосредственно на один из узлов IIS, чтобы проверить, не возникла ли такая же проблема. Я уверен, что если вы выполняете только небольшое количество тестов, StateServer не будет проблемой.
Попробуйте установить доменное имя asp.net_sessionid через код ".yourdomain.com". По умолчанию доменное имя файла cookie ASP.net_SessionID имеет полный путь к приложению. Таким образом, это может быть одной из причин, почему куки не путешествуют.
Например, Request.Cookies["ASP.NET_SessionId"].Domain = ".yourdomain.com". Помните первое "." важно в доменном имени.
Вы можете сделать это в HttpModule в событии AcquireRequestState.
Использование подхода к базе данных имеет свои проблемы. Я думаю, что вы должны быть в состоянии использовать ваш предпочтительный подход.
Возможно, эта статья по устранению неполадок поможет?
Или " Устранение проблем, связанных с сеансом в ASP.NET"
Или " Устранение неисправностей истекшего состояния сеанса ASP.NET и ваших параметров"