【问题标题】:How can I increase the number of users of my system?如何增加系统的用户数量?
【发布时间】:2009-05-10 10:41:33
【问题描述】:

我有一个客户端/服务器应用程序,它依赖于 MS SQL 数据库进行后端存储,服务器应用程序是一个 WCF TCP 服务,它通过从数据库信息集中进行选择来处理客户端请求。

服务配置为 PerSession 并支持 500 个会话。 在客户端,用户可以打开不同的视图,每个视图都有一个我的服务对象(代理对象),所以每个视图都是一个会话;每个视图都有一个线程计时器,每秒使用代理对象从服务器请求数据。

该应用程序对于具有 8 个视图的少量用户运行良好,但是当我增加数量时,SqlConnection.Open 中出现超时异常,因为连接池中没有可用的连接。

每个视图都有会话/对象,因为 WCF 服务不是线程安全的;它依赖于使用 SqlDataReaders 和 SqlAdapters 的单线程数据库访问层。

有没有办法增加数据库连接数?好像800是最高的!!从您的角度来看,我怎样才能增加用户数量?

我是否应该更改 DB 层并使其成为多线程并使 WCF 服务单一? 我认为这是设计中的瓶颈(您能推荐一篇关于 ADO.net 中的多线程的文章吗)

PS:

我可以用内存数据库或更快的存储替换数据库吗?

根据答案:

我更改了后端服务以关闭每个方法调用的连接,但我面临同样的问题,因为用户数量增加延迟增加(超过一秒),这是否意味着我必须更改数据库解决方案?什么是替代解决方案?。

之后:

我尝试了两种解决方案

  1. 每个方法调用打开和关闭 sql 连接
  2. 增加连接字符串中连接池的大小

但是如果我增加用户数量,两者都会给我带来延迟,同时我会监控 sql porfiler 中的查询,似乎每个查询不会超过 20 毫秒。

【问题讨论】:

  • 如果您已经实施了提供的解决方案,但问题仍未解决,则可能是连接池实施不正确,或者是 WCF 服务本身的体系结构存在问题。 Sql Server 绝对可以处理连接数,而且非常好。或者,问题出在服务器规格上。

标签: .net sql-server wcf client-server


【解决方案1】:

不要为每个会话保持打开数据库连接,而是在每次客户端调用结束时关闭它,以便将连接返回到连接池。 (连接在池中时不会完全关闭,所以重用时重新连接很快。)

这样每个会话只会在真正需要时才使用连接。您应该会看到特定数量的会话所需的连接数显着减少,并且您的应用程序应该能够处理更多的会话。

此外,由于会话不会保持连接,因此您不会对会话数有绝对限制。如果会话需要连接时没有可用的连接,它将重试一段时间,直到有可用的连接。只有当服务器真正超载(即请求进来的速度超过服务器处理它们的速度)时,你才会得到超时错误。

【讨论】:

  • 我已经在会话结束时关闭了连接,但问题是活动会话的数量随着时间的推移而增加,因为会话不是每个应用程序实例,而是每个视图(图表显示形式)
  • 答案是指在每次客户端调用后关闭连接,而不是在会话关闭后。在整个会话期间保持打开状态会导致您遇到问题。
  • 但这会降低性能吗?至于每秒发生的每个方法调用,我将打开和关闭连接
  • 因为关闭的连接返回到池中,这对性能的影响很小。看看this关于 Sql Server 连接池的文章。
  • 是的,每次重置数据库连接时,性能自然会略有下降。这是您必须支付的费用才能大幅增加会话数量。您当前的瓶颈不是性能,而是会话数。只要您没有足够的用户来使用服务器的容量,代码的性能就无关紧要。
【解决方案2】:

Joe Albahari 的Threading in C# 是最好的免费在线多线程书籍之一

Jon Skeet 的 Multi-threading in .NET: Introduction and suggestions 也很棒

【讨论】:

  • 我不想要关于多线程的一般文章,我需要它专门用于 ADO.net
【解决方案3】:

积极关闭连接。仔细检查所有实现 IDisposible 的 ADO.NET 组件的包装,使用块或 try/finally 块调用 IDisposable 和 .Close 连接、命令、数据读取器等。

800 个打开的连接是连接泄漏,除非您有类似 VISA 或 google 的同时交易数量。

【讨论】:

    【解决方案4】:

    我必须同意之前的海报,您应该考虑关闭连接。同时,您可以在连接字符串中指定连接池大小:Max Pool Size

    data source=RemoteHostName;initial catalog=myDb;password=sa;user id=sa;
    Max pool size = 200; 
    

    【讨论】:

      【解决方案5】:

      找到一篇关于 SQL Server 连接池 (ADO.NET) 的文章,您可能会觉得它很有用。

      SQL Server Connection Pooling (ADO.NET)

      【讨论】:

        【解决方案6】:

        经过一组实验,我通过一组更改将我的系统的用户数量增加了 800%

        1. 最大化连接池大小
        2. 为客户端创建单个代理对象并串行而不是并行发送他的请求
        3. 优化 sql 查询并在服务端使用一些缓存

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-06-30
          • 2023-03-28
          • 2021-04-04
          • 2018-12-14
          • 2012-05-29
          • 1970-01-01
          • 2019-10-05
          • 2018-12-07
          相关资源
          最近更新 更多