Каковы накладные расходы на PostAuthenticateRequest? - PullRequest
7 голосов
/ 09 февраля 2011

Я внедряю систему пользовательских билетов, используя метод Application_PostAuthenticateRequest в моем файле global.asax (ASP.NET MVC).Мне интересно, каковы издержки для такого рода вещей - так как это будет десериализовать некоторую информацию по каждому запросу.Он генерирует cookie размером около 1,8 Кб, что составляет тонну, но является ли это лучшей альтернативой, чем частые поездки в базу данных?

Десериализованная информация

  • Идентификатор пользователя (int)
  • Роли (строка [])
  • Электронная почта (строка)
  • Связанные идентификаторы (int []) // (сложно описать, что это такое, но у каждого пользователя будет около 3из них)

Казалось бы, разумнее внедрить пользовательскую систему FormsAuthenticationTicket, чем непрерывно выполнять обходы базы данных на основе User.Identity.Name.Но я просто беспокоюсь, что эта постоянная десериализация очень тормозит.Но это выглядит примерно так ...

    protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
    {
        HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            string encTicket = authCookie.Value;

            if (!String.IsNullOrEmpty(encTicket))
            {
                // decrypt the ticket if possible.
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encTicket);

                var userData = Deserializer.Deserialize(ticket);
                UserPrincipal principal = new UserPrincipal(userData);

                HttpContext.Current.User = principal;
            }
        }
    }

Вот класс, сериализуемый как UserData в FormsAuthenticationTicket.

[Serializable]
public class MembershipData
{
    public string Email
    {
        get;
        set;
    }

    public int Id
    {
        get;
        set;
    }

    public string[] Roles
    {
        get;
        set;
    }

    public int[] Ancillary
    {
        get;
        set;
    }
}

Ответы [ 2 ]

8 голосов
/ 09 января 2013

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

Первоначально мы проходили тот же процесс, что и вы, и включили в файл cookie довольно много пользовательских данных. Этот процесс сократил количество посещений нашей базы данных, но в итоге мы столкнулись с ошибкой, когда некоторые пользователи вообще не могли войти, а другие могли. Оказывается, из-за наших сериализованных данных файл cookie молча отбрасывался, когда его размер превышал определенный размер.

Наш текущий процесс представляет собой двухуровневую систему кэширования. Мы сохраняем идентификатор базы данных пользователя в файле cookie как User.Identity.Name, а затем в PostAuthenticateRequest пытаемся получить информацию о пользователе из локального кэша ASP.net, возвращаясь к распределенному кэшу Redis. Локальный кэш находится в работе и хранится в течение 15 секунд (поэтому повторяющиеся запросы не требуют передачи данных по Redis). Кэш Redis хранится в течение дня и становится недействительным при обновлении. Если оба из них пропущены, мы загружаем информацию из SQL Server.

Затем мы переносим эту пользовательскую информацию в пользовательский IPrincipal, и все работает как чудо. Похоже, что это работает очень хорошо для нас на веб-сайте с довольно высокой загрузкой.

2 голосов
/ 10 февраля 2011

Я бы порекомендовал вам измерить производительность, но я ожидал бы, что подход с использованием куки будет быстрее, чем выполнение обходов базы данных.Вы также можете упростить сериализацию и сделать ее максимально быстрой, используя строку с разделителями-запятыми или специальными символами.Вот как бы я оценил различные операции с точки зрения производительности:

  1. внутрипроцессное взаимодействие
  2. межпроцессное взаимодействие
  3. межсетевое взаимодействие
...