【问题标题】:Multiple session-less requests to a page (which interacts with database) results in HTTP Error 500对页面(与数据库交互)的多个无会话请求会导致 HTTP 错误 500
【发布时间】:2012-02-06 23:47:37
【问题描述】:

我有一个 asp.net 网页,它与 SQL Server 数据库交互,获取一些数据,然后返回一个 XML 响应(我使用 xml_curl 将其输入Freeswitch)。

因为 Freeswitch(从现在开始 FS)不存储 cookie,所以每个请求都会创建一个新会话。

当请求数量过多(大约 97 到 100)时,SqlConnection.Open() 方法从 SQL Server 实例获取超时,然后导致 HTTP 错误 500。

为了测试我的假设,我使用 PHP 和 cURL 创建了一个小脚本,它向我的 asp.net 页面发出重复请求。如果我在 PHP 脚本中存储 cookie(以及会话),我可以在近 314 秒内发出 10000 个成功请求。

但如果没有会话,我会卡在大约 97~100 个请求,然后收到 HTTP 错误 500。

有没有办法克服这个问题?

==编辑==
以下是我与数据库交互的方式:

String connectionString = WebConfigurationManager.ConnectionStrings["SqlServerConnection"].ConnectionString;
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = connection.CreateCommand();
command.CommandType = CommandType.Text;
command.CommandText = "Select * from dbo.Template where Name = '" + name + "'";

Template template = new Template();

connection.Open();

SqlDataReader reader = command.ExecuteReader();


if (reader.HasRows)
{
    reader.Read();
    template.Name = reader["Name"].ToString();
    template.XMLContent = reader["XMLContent"].ToString();
}
else
{
    template.Name = "";
    template.XMLContent = "";
}

reader.Close();
connection.Close();

return template;

模板表有这些字段:

ID => int, identity, primary key
Name => nvarchar(255), unique
XMLContent => ntext

【问题讨论】:

  • 如何调用数据库?当您不再需要连接时,您是否正在关闭它?您是否禁用了连接池?如果您发布访问数据库的代码会有所帮助。您还应该检查您执行的 SQL 语句,以确保不会导致数据库阻塞。顺便说一句,ASP.NET 会话与访问数据库无关 - 除非添加了绑定两者的代码,例如在会话开始时打开连接,在会话关闭时关闭它。
  • 我添加了代码。正如我所说,如果我存储 cookie(以及会话),代码会运行 10000 个请求。
  • 顺便说一句,您将希望通过使用参数而不是字符串连接来避免 SQL 注入。 msdn.microsoft.com/en-us/library/…
  • 要添加到边带 cmets,如果您不需要完整的 ASP.NET 页面框架,请考虑使用通用处理程序 ('ashx')。它不会帮助解决 这个 问题,但会在资源和时间上为您的网络服务器提供更高的性能。
  • @DMoses 我想在这里保持简单。我知道这一点。谢谢。

标签: c# asp.net sql-server


【解决方案1】:

看来您正在使用连接池。默认情况下,这些池最多有 100 个到您的 SQL 服务器的连接,并将任何其他连接排队。队列有一个超时时间(默认为 15 秒),如果您希望将请求排队更长时间,可以延长该超时时间。这意味着您可能会在服务器上得到备份。如果您的 SQL 服务器可以处理,您还可以增加池的最大大小。

这是增加连接设置的方法by adding these parameters:

  • 超时=60
  • 最大池大小=150
  • 等等等等

【讨论】:

  • 谢谢你。我使用Pooling=false 禁用了连接池(因为只有一页使用此连接字符串,所以没关系)。问题解决了。
  • 在单个页面上使用池在您的方案中做了 2 件事:1) 让您限制应用程序针对 SQL 使用的连接数量(因此不与 SQL 服务器挂钩)和 2) 使创建与 sql server 的连接要快得多。如果您的 SQL 语句在 10 毫秒内运行但获得连接需要 300 毫秒,这可能会很明显。无论如何,很高兴这对你有用。
【解决方案2】:

改进此代码的一些步骤。

  1. 如果您不需要会话,请为此页面禁用它,这样就不会生成 cookie。
  2. 这里根据name使用一些缓存如果请求的名字相同,从缓存中获取而不打开数据库
  3. 使用静态变量只读取一次连接字符串。
  4. 把它放在[try catch |使用] ,以确保在失败的情况下关闭连接
  5. 也许您可以尝试互斥锁逻辑,以避免同时请求过多。
  6. 在您的 sql 调用中使用参数。

【讨论】:

    【解决方案3】:

    除了@Aristos 的建议:

    • 使用异步页面!

    Example"Benchmark"

    前段时间我问了差不多same question here on so

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 2021-05-12
      相关资源
      最近更新 更多