【问题标题】:Manage many TCP connections effectively and efficiently有效和高效地管理许多 TCP 连接
【发布时间】:2010-12-22 21:11:20
【问题描述】:

我很好奇是否有人可以就如何有效地管理大量 TCP 连接给我任何想法或建议。我说的是大约 1000 个 tcp 连接(也许更多)。管理所有这些连接的应用程序需要定期从客户端(连接的另一端)提取信息。例如,可能每 30 秒一次。我会为此使用 .NET 4.0。有没有内置的东西可以帮助解决这个问题,或者有一种特殊的方法来构建所有东西来管理所有这些连接,而不会让这个应用程序陷入困境以至于它没有用处?

【问题讨论】:

  • 客户端也是.Net应用程序吗?如果不是,它是用什么构建的?
  • 不是。我相信它是一个运行嵌入式 linux 的机顶盒。
  • 您是否也在开发客户端,或者这是按原样提供给您的东西?
  • 按原样提供。我知道所有的 IP 地址,我只是单独连接到每个盒子。我只是通过发送他们理解的结构化命令来与他们交流。
  • 这太糟糕了,因为它确实限制了你的选择,但我猜你知道这一点以及你问这个问题的原因:)

标签: c# .net c#-4.0 tcp


【解决方案1】:

我可以给你一个快速的见解:

甚至不要考虑为每个连接生成一个线程。使用框架的内置异步/任务框架来管理连接。那是;让线程池来做吧。

另外,请注意密切关注您的线程在做什么;确保您不能一次从多个线程读取/写入连接流。但同时,请注意如何使用锁定机制来做到这一点,这样您就不会得到一个拥有 1000 个活动连接的进程,以及一个充满等待获取锁的线程的线程池,而这些线程永远不会获得。

【讨论】:

  • +1,我支持这个。但是,如果 Paul 仍想为每个连接生成线程,他可以使用 .NET ThreadPool 类来管理线程。
  • +1 我第三个!我的回答也围绕着同样的概念。
  • 关于如何以这种方式使用任务的任何想法或示例?我只用过一次,而且是为了小东西。我真的想不出一种方法来使用它们来处理所有这些 TCP 连接。
【解决方案2】:

处理数千个连接并不困难,只要您只使用异步 API。 “每个连接一个线程”的概念不仅不能扩展,而且(在一般协议情况下)是错误的。请注意,异步 API 与使用 ThreadPool 不同。

异步编程需要一些时间才能掌握,但它并没有那么复杂。您会发现自己必须手动跟踪比同步编程更多的状态。

确保您的协议类可以处理任何大小的部分接收(这需要额外的状态),并且每个连接都有一个协议实例。

任何套接字错误都应该导致连接被关闭并清除状态。

然后记录。一切。 TraceSource是你的朋友;了解如何使用可以通过编辑 app.config 打开(甚至在生产中)的 .NET 跟踪。

【讨论】:

    【解决方案3】:

    我不记得对这个特定场景有任何内置支持。但基本上这就是我的做法,通常被称为一种好的做法:

    1) 有一个负责连接的线程池(规模很小 - 可能大约 5 个)。这将从作业队列(打开或关闭)中读取并管理打开和关闭连接。

    2) 有一个线程池(中等大小)用于管理通信和操作。我认为 50 个池应该没问题。

    3) 您将有一个线程负责编排整个操作,但这不应该被任何操作所干扰,并且只能将操作排队到其他线程。

    【讨论】:

      【解决方案4】:

      只是在这里已经很好的答案中添加一个“次要”的东西。

      一个经常被忽视的领域是网卡本身的功能。确保服务器中的网络适配器支持 TCP 卸载。就此而言,请购买一个不错的并验证驱动程序是否是最新/最好的。

      适配器中内置的 TCP 卸载引擎在比您的代码更低的级别上工作,它将处理与客户端之间的数据混洗的所有工作。这会对您的软件产生巨大的性能和可扩展性影响。

      【讨论】:

      • 在这件事上我别无选择,但我可以看看他们是否这样做。不过,感谢您对此的提醒。
      • @Travyguy:一般最近2、3年生产的品牌服务器都有这个。并非总是如此,但一般来说。只需确保驱动程序是最新的。
      【解决方案5】:

      【讨论】:

      • 不确定这个数量的连接,肯定不会为每个连接使用一个线程,但异步套接字库是我要开始的地方
      • 我已经在异步使用套接字了。我需要有效地管理所有这些连接(打开/关闭/发送数据/接收)是问题所在。现在它只是一个内存猪,而且效果不佳,所以我想我会要求一个更好的解决方案。
      【解决方案6】:

      首先,使用其他人所说的异步方法。合理的硬件和合理的设计,1000 个连接应该不是问题。

      我将拥有这些连接的集合,这些连接由单个写入器多读取器锁保护。我可能每个连接都有一个计时器来处理轮询的周期性。当计时器触发时,我会触发对机顶盒的请求,然后允许该连接上的异步读取来累积响应,然后处理它。理想情况下,我会尽量避免访问连接集合并存储与连接相关的数据,以便可以在不锁定读取完成的情况下访问它。

      我在这里写了关于支持“大量”并发连接的博客:http://www.serverframework.com/asynchronousevents/2010/10/how-to-support-10000-or-more-concurrent-tcp-connections---part-2---perf-tests-from-day-0.html 恕我直言,重要的是确保您从一开始就在测试这种负载,以便您可以在添加不良负载时快速发现设计不可扩展的决策。

      【讨论】:

        猜你喜欢
        • 2022-11-18
        • 2011-11-06
        • 2011-06-25
        • 2021-07-07
        • 1970-01-01
        • 1970-01-01
        • 2017-02-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多