0

这是场景:

有客户端向服务器发送请求(它将是套接字或 wcf 服务器,这并不重要)。

服务器将保持一个开放的双工通道,并将使用它来向客户端发送答案(序列化数据)。服务器将处理请求并涉及查询生成(基于请求的参数)和针对各种类型的数据源(sql server、文件系统、分析服务服务器 - olaps、离线多维数据集等)的执行。如此繁重的 IO 绑定任务 - 肯定经常长时间运行。

性能很重要,同时考虑成百上千个请求。它必须是可扩展的。

我从未使用过 TPL,也从未编写过异步服务器。但是这几天我读了很多书,但......仍然无法理解它。

  1. TPL(4.0,而不是 4.5)在这里是一个不错的选择吗?
  2. 我应该为到达服务器的每个请求创建 tpl 任务吗?(用于异步处理)
  3. 我应该使用 LongRunning 选项创建这些任务吗?(所以不涉及线程池)
  4. 我应该为请求实现任何队列机制吗?如何?
  5. 我应该将请求处理的所有部分(a. 查询生成 b. 针对数据源的查询执行)与单独的任务(延续)链接起来,还是可以对两者使用单个任务 a. 和b.?
  6. 我应该使用 .FromAsync 任务生成来执行查询吗?还是标准的 .StartNew 就足够了?
  7. 考虑到上述要求,我还应该注意哪些其他重要方面?
4

1 回答 1

2

关于这个话题已经有很多讨论......例如,请参阅https://stackoverflow.com/a/908766/1876226 。那里提到了 Chris Mullins 的帖子,但这些帖子都丢失了。我有一个指向某个网络档案的链接,该档案有一个帖子的缓存版本,我会寻找它。

更新:找到了 Chris Mullins 帖子的注释:

我们在一些使用 HUGE IA64 服务器的实验室中进行了相当多的可扩展性测试。其结果以及我们提出的一些最佳实践详见: http ://www.coversant.net/Default.aspx?tabid=88&EntryID=10

在此处查看存档副本:http: //nleghari.wetpaint.com/page/Windows+Sockets+and+Threading%3A+How+well+does+it+scale%3F

我仍在为我正在开发的类似应用程序而努力。到目前为止,我想到的要点是:

  • Socket异步操作(Begin*、End*、*Async)使用 IOCP;
  • TPL 是实现多线程的一种直接且健壮的方式;
  • 如果你想要异步 - 那么你应该创建一个任务来处理请求。也许除了“已知”是轻量级的请求之外;
  • 如果您使用 创建 LongRunning 任务hundreds or maybe thousands of requests at the same time,那么您可能会获得使系统崩溃的线程数。需要时使用 LongRunning。使用自定义TaskScheduler进行并发控制;
  • 队列将不可避免地出现在您的代码中:要么用于批处理作业以避免过度锁定和上下文切换,要么用于生产者-消费者场景;
  • 某些资源(SQL Server、文件系统...)具有也使用 IOCP 的异步 API。有些资源没有。在前一种情况下,.FromAsync 将有效地使用 IOCP。但请注意,IOCP 线程池也不是无限的:它可能会被数据库查询和网络服务耗尽;
  • MemoryCache如果可能 - 通过实现应用内缓存(.NET或自定义)或批处理不需要响应的数据库请求(例如,进行批量插入)来完全避免数据库访问;
  • 有一个ParallelExtensionsExtras开源库,它部分成为 .NET 4.5 Async 的一部分。因此,您可以在 .NET 4.0 中拥有 neet TPL 扩展。See tour A Tour of ParallelExtensionsExtras

c# 异步套接字服务器有很多幼稚和错误的实现。阅读,但重新检查。

于 2013-01-17T18:53:32.687 回答