4

我正在使用 Azure 云并尝试实现一个主要是IO-bound的可扩展 HTTP 服务器。

说明:举个例子,假设服务器是“blob 代理”——这意味着客户端连接,服务器从 Azure 存储下载一个 blob 并将其流式传输到客户端。而已。

我的目标当然是从一台机器上挤出最大的并发客户端。

向 node.js 学习

似乎 node.js 非常适合此类问题。服务器所做的只是 IO。Node 是完全异步的,在一台机器上可能会达到几万个并发。

我最终选择了反对 node.js 来支持 c# 和 .net 框架,并且我正在尝试使用 c# 提供的类似策略。我不是想复制节点——只是它的方法。

我在 Azure 上的 c# 实现

目前,我有一个 Azure 云服务,其中包含 IIS 上的瘦 Web 角色。这里是MyHandler.ashx

public class MyHandler : HttpTaskAsyncHandler
{
    public override async Task ProcessRequestAsync(HttpContext context)
    {
         CloudBlockBlob blob = GetBlockBlobReference(...);
         await blob.DownloadToStreamAsync(context.Response.OutputStream);
    }
 }

我有这个简单的路由Web.config

<system.webServer>
  <handlers>
    <add verb="*" path="*" name="MyHandler" type="MyWebRole.MyHandler" />
  </handlers>
</system.webServer>

讨论:

  1. 我希望 .net 4.5 的新 async/await API 与 node.js 中的 JS 一样异步,并且非常易于使用。这个假设有什么严重的错误吗?

  2. 为了最大化并发数,应该对我的 Azure Web 角色进行哪些调整/优化?

    • 我听说我必须增加最大连接数,因为它默认只有 12*num 个核心。这是真的吗,它是如何完成的?

    • 我应该做些什么来改变默认线程池吗?

    • 还有其他重要的提示/调整/优化吗?

  3. 我应该完全放弃 IIS 吗?我可以在 Worker Role 中托管一些“更精简”的服务器实现。相对于 IIS,这会显着提高性能吗?值得麻烦吗?

  4. 总的来说,我在正确的轨道上吗?有没有更好的方法来使用 c#/.net 做到这一点?

4

2 回答 2

5
  1. 是的,.NET 4.5 的 Async API 将与 Node 一样快,但是由于 Node 是最低限度的服务器,它总是看起来更快,因为默认情况下 Node 不管理会话和 IIS 为各种功能提供的许多其他钩子. IIS 还提供应用程序域等,以隔离不同的应用程序,每个此类功能都会使 IIS 减慢几位,节点实现的所有示例都没有涵盖任何高级功能,这就是它们看起来更快的原因。

  2. 您将不得不查看配置,我相信它必须是可配置的,否则您可以删除 Azure Web 角色并移动到 Azure 网站并创建预留容量,您可以在其中完全自定义 web.config,或者您可以简单地创建一个可以在任何级别配置整个 IIS 的 VM。它是您的私人服务器。

  3. 不,在不知道它所能做的一切的情况下放弃 IIS 就是重新发明轮子,IIS 很大,它有许多插件和许多安全改进。您最终将创建一个带有许多您可能没有意识到但可能有害的安全漏洞的服务器。

  4. 异步 API 在 C# 中是尽你所能,并且与它一起,你会获得许多好处,比如带有实体框架的全功能 Visual Studio 以及更高级的调试功能。使用 Node 或任何自定义实现,调试和创建通用例程会占用您所有的时间。相反,您可以为开源 IIS 相关开发做出贡献,因为它的许多部分现在都可以在 codeplex 上使用。

带有 ASP.NET 4.5 MVC 的 IIS,它也是完全异步的。您可以创建异步控制器和处理程序。事实上,大多数人都不知道从 ASP.NET 2.0 开始就可以使用异步编程,唯一的问题是异步逻辑很难编写。比较开发成本与开发时间,我们经常忽略异步编程的好处,除非我们付出的时间回报非常高。但是从 .NET 4.5 开始,async关键字await使异步编程变得非常容易。

于 2013-08-24T13:18:24.880 回答
1

我会认真建议不要在这里重新发明轮子。在最新版本的 IIS 中,支持 websockets,并且异步请求/响应已经有一段时间了。

关于你对臃肿的评论,你仍然可以相当瘦。至于视图引擎和路由引擎,您不必使用它,此时您真正想要的是什么?您可以注册/使用不同的或自定义的视图引擎。渲染部分是一个很小的交互,在这里几乎不值得一提,尤其是结合输出缓存。

这实际上取决于您尝试完成 NodeJS 提供的功能。NodeJS 最大的卖点是能够处理成千上万的同时连接的用户来处理大量的 IO 和事件绑定负载。主要是用于 IO 的 filesystem/db/services 和用于事件绑定的 WebSockets。

如果不分析特定的应用程序,就不可能给出建议。鉴于 ASP.Net + IIS(最新版本)中有很多内容。如果您要重新发明轮子,那么准确确定您的实际需求非常重要。


在这种情况下,您似乎想在 IIS 中执行 CDN 类型的加载,在这种情况下,如果您想坚持使用 IIS,您可能应该使用 HTTP 模块。

如果您不需要将资源限制为经过身份验证的用户,我建议您查看前端加载的 CDN 或缓存反向代理。随着 IIS+.Net 的大量集成,您不会以任何其他方式解决很多臃肿问题,同时坚持使用 IIS+.Net。

除此之外,微软已经提供了一个由 azure blob 存储支持的 CDN 解决方案。这可能是您最好的选择,如果您需要身份验证,我相信也有此方法。在任何情况下,您都可以通过 ASP.Net MVC 或 WebService 接口使用 .Net 和 C# 来做您想做的事情……无需视图。


顺便说一句,我自己真的很喜欢 node.js,您可能很想在一些 node.js 实例前面为您的服务使用 varnish。Azure 支持 linux VM,我们一直在使用 Ubuntu 和 Docker,它们运行良好。

于 2013-08-24T00:16:49.703 回答