.NET框架下的FastCGI协议实现

在.NET框架下实现FastCGI协议的目的,是为了提供比Mono提供的解决方案更可靠的选择,并且实现一个更干净、可重用的协议,以托管不仅仅是ASP.NET应用程序,还包括通常使用HttpListener实现的自定义的低层次(且快速)应用程序。通过这种实现,可以在Windows和Linux上使用NginxWeb服务器托管ASP.NET应用程序(包括MVC)。

关于Mono的FastCGI实现

在Mono中可以找到FastCGI协议的实现。如果有机会查看源代码,会发现它非常复杂。此外,如果想使用它,还需要部署Mono库,因为它依赖于这些库才能工作。Mono实现的最终目标是提供一个FastCGI替代品来托管ASP.NET。实现包括这一点,但也打开了在Mono实现下不可能的不同实现场景。

阅读本文需要对Web服务器以及特别是IIS如何处理请求有基本的了解。此外,对Web服务及其在.NET中当前可用框架(例如WCF或ServiceStack)的实现有基本理解也将是有用的。

优势

使用此库的主要优势是,可以为ASP.NET应用程序选择Web服务器,而不是IIS。如今,大多数流量密集型的Web应用程序(如Facebook、LinkedIn等)都在转向服务器不基于线程而是使用异步I/O的实现(在Windows下称为IOCP)。例如,Nginx和Node.js(libuv)都使用这种模式。实际上,这种模式在处理大量并发请求时更有效,因为CPU不会忙于在线程之间切换,而只是运行一个单线程(循环),在其中处理所有请求。

因此,可以使用像Nginx这样的酷Web服务器来托管应用程序,但仍然受限于ASP.NET的线程模型!不幸的是,FastCGI实现本身无法解决这个问题。但它是朝着更有效的资源管理迈出的第一步。

第二个优势是,可以选择不使用标准的ASP.NET堆栈,而是使用自己选择的Web框架,或者更好的是创建自己的!ASP.NET是围绕WebForms设计的,引入了许多东西,如会话管理,这些并不总是那么高效或干净地实现(例如,看看这种行为在处理使用读写会话的并发请求时)。MVC框架很棒,解决了使有状态的WebForms模型工作的许多怪异之处。无论如何,它仍然基于ASP.NET堆栈,仍然有一些问题。当然,这只是观点:有很多人发现WebForms模型很棒,并取得了巨大的成功。无论如何,如果像一样对此感到沮丧,并不孤单!

FastCGI协议

FastCGI协议的工作方式非常简单:

  • Web服务器接收请求
  • 注意:如果请求是SSL(https)请求,它也会被解密
  • 如果请求是静态资源,直接处理请求
  • 如果请求是动态页面/资源,请求被转发到FastCGI服务器
  • 注意:这通常需要在Web服务器上进行配置
  • FastCGI服务器处理响应并将其发送回Web服务器
  • Web服务器将响应写回客户端(用户浏览器)

FastCGI服务器是一个TCP/IP服务器,监听Web服务器转发的请求。大多数Web服务器实现了单通道/请求模型。这意味着对于每个请求,都会创建一个新的到FastCGI服务器的套接字。然而,FastCGI协议还为每个通道(套接字)提供了多请求模型。该库目前支持第一种模型,但它被设计为可以轻松实现另一种模型:事实上,由于缺乏良好的Web服务器端支持,目前实现它相当无用。

发送和接收到FastCGI Web服务器的所有数据都在内存(RAM)中:这肯定很快,但在处理大量请求/响应时完全低效。需要非常小心这一点,并考虑其他选择,如果计划使用大量的大型请求/响应。

使用库

尝试/使用库的最简单方法是运行包含的Nginx示例。

  • 在Windows下运行包含在Examples文件夹中的nginx.exe
  • 在Linux下运行Nginx,并使用与Windows示例一起提供的配置

启动FastCgi.Test.exe,可以在Visual Studio中或从命令提示符启动(在这种情况下,需要先构建它)

用浏览器访问http://localhost:8080/info.aspx或http://localhost:8080/test.aspx

在示例中,使用了一个简单的ASP.NET网站作为测试。Root文件夹包含这两个页面,可以从这里开始进行一些实验。在Root\bin子文件夹中,复制了网站的DLL:它也包括Fastcgi库。

在运行示例时,会创建一个新的应用程序域。这是ASP.NET实现所必需的,以便隔离Web应用程序。没有创建应用程序域就无法托管ASP.NET应用程序。尽量在实现上保持简单,不会在这里详细说明,因为这是一个非常复杂的话题。无论如何,可以很容易地找到一些文章,这些文章将在CodeProject、MSDN或网络上详细覆盖它。

C# string path = Path.Combine(Directory.GetCurrentDirectory(), "Root"); SimpleServer server = (SimpleServer)ApplicationHost.CreateApplicationHost( typeof(SimpleServer), "/", path); server.Start();

为了使ASP.NET堆栈处理请求,实现创建了一个自定义的HttpWorkerRequest,称为FastCgiWorkerRequest,从Web服务器接收的数据。这个类还将ASP.NET应用程序处理的数据重定向回Web服务器,使用fastcgi库的Request对象。换句话说,这个FastCgiWorkerRequest是ASP.NET应用程序和fastcgi库之间的链接。

Nginx配置

为了让Web服务器将动态页面请求重定向到FastCGI服务器,在nginx配置中包含了这个:

PHP location ~ ^.+\.aspx { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index Default.aspx; fastcgi_split_path_info ^((?U).+\.aspx)(/?.+)$; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; include fastcgi_params; }

它简单地将所有以.aspx结尾的页面请求重定向到FastCGI服务器。如果在Web上找到了其他适用于MVC的配置。在这种情况下,不能依赖页面扩展名。相反,可以尝试nginx网站上建议的解决方案。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485