【问题标题】:What is the overhead on PostAuthenticateRequest?PostAuthenticateRequest 的开销是多少?
【发布时间】:2011-02-09 18:54:33
【问题描述】:

我正在使用 global.asax 文件 (ASP.NET MVC) 中的 Application_PostAuthenticateRequest 方法实现自定义票证系统。我想知道这种事情的开销是什么——因为它会反序列化每个请求的一些信息。它会生成一个大约 1.8 kb 的 cookie,这是一大堆 - 但这是否比频繁访问数据库更好?

正在反序列化的信息

  • 用户 ID(整数)
  • 角色(字符串[])
  • 电子邮件(字符串)
  • Associated Ids (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;
            }
        }
    }

这是在FormsAuthenticationTicket 中被序列化为UserData 的类。

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

    public int Id
    {
        get;
        set;
    }

    public string[] Roles
    {
        get;
        set;
    }

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

【问题讨论】:

  • 我在野外有许多应用程序可以执行此操作 - 将数据存储在表单身份验证票证的 userData 部分。我不必反序列化,因为数据只是一个逗号分隔的列表,但我想这对你来说不会成为瓶颈。你必须做一些测试。

标签: c# performance asp.net-mvc-3 forms-authentication


【解决方案1】:

我知道这个问题现在有点老了,并且已经有了一个可以接受的答案,但我想谈谈我的想法以及我们目前如何使用类似的设置来做事。

最初,我们正在经历与您相同的过程,并在 cookie 中包含相当多的用户数据。这个过程确实减少了我们的数据库访问,但最终我们遇到了一个错误,其中一些用户根本无法登录,而其他用户则可以。事实证明,由于我们的序列化数据,当 cookie 超过一定大小时,它会被静默丢弃。

我们当前的流程是一个两层缓存系统。我们将用户的数据库 ID 作为User.Identity.Name 存储在 cookie 中,然后在 PostAuthenticateRequest 上,我们尝试从本地 ASP.net 缓存中检索用户信息,然后返回到分布式 Redis 缓存。本地缓存在进程内并存储 15 秒(因此重复的请求不需要通过网络连接到 Redis)。 Redis缓存存储一天,更新失效。如果这两个都未命中,我们就从 SQL Server 加载信息。

然后,我们将该用户信息放入自定义 IPrincipal 中,一切都像魅力一样工作。在一个使用率相当高的网站中,这似乎对我们来说非常有效。

【讨论】:

    【解决方案2】:

    我建议您测量性能,但我希望 cookie 方法比往返数据库更快。您还可以通过使用逗号分隔或某些特殊字符分隔的字符串来简化序列化并使其尽可能快。以下是我如何根据性能对不同操作进行排名:

    1. 进程内通信
    2. 进程间通信
    3. 网络间通信

    【讨论】:

    • 即使cookie大小为1.8 kb,还是比频繁往返好?我从 FireFox、Chrome 和 Safari 收到关于 cookie 大小的危险信号……但我想不出任何其他方式来存储我需要的相关信息。我不能仅仅依赖于将它放在Session 中,这就像将它加载到 cookie 中一样糟糕,而且它容易出现更多问题。我不能真正依赖缓存它,因为它需要绑定到登录,而我使用依赖注入只是意味着更多次往返数据库。
    • 要减小 cookie 的大小,您可以查看票证的自定义序列化 - 我听说过 Google Protocol Buffers 的好评。
    猜你喜欢
    • 2021-07-26
    • 2011-11-23
    • 2017-09-27
    • 1970-01-01
    • 2011-05-17
    • 2012-01-05
    • 2016-04-15
    • 2013-05-06
    • 2013-05-20
    相关资源
    最近更新 更多