使用 IIS 创建可伸缩的 Windows 服务






3.12/5 (7投票s)
本文讨论了一种使用 IIS 创建可伸缩 Windows 服务的方法。
引言
之前,我们需要开发一个相当可伸缩的企业级 Windows 服务。创建一个简单的服务很简单,但部署它以实现可伸缩性并非易事。本文将介绍我们如何将 Windows 服务和 IIS 结合在一起,实现一个真正良好的可伸缩部署。
IIS 为我们提供了大量允许可伸缩性的功能,例如
- 应用程序池的使用及其回收
- 开箱即用的横向扩展和负载均衡
- 当 IIS 工作进程使用过多内存时,会启动新的工作进程,从而带来更好的性能等功能
我可以继续说下去,但重点是 IIS 比 Windows 服务具有更好的可伸缩性功能,默认情况下提供了诸如多线程和执行空间分区之类的简单功能。只需稍作努力,我们就可以开发出可在服务器场中和谐工作的解决方案。
问题是,只有在使用 HTTP POST 请求时,IIS 功能才能工作。 如果我们将两者的优点结合起来,我们就能得到一个非常好的解决方案。 这就是我们试图在本文中做的事情。
要了解有关 IIS 如何提供可伸缩性的信息,请访问此链接。
Windows 服务本质上是在每个时间间隔之后重复执行一些业务逻辑。 该解决方案将此循环逻辑保留在 Windows 服务中,而业务逻辑应位于 Web 或 WCF 服务中。 现在,可以从 Windows 服务调用此服务来完成工作。
解决方案的架构

Windows Server 执行服务 - 这是一个非常简单的 Windows 服务,其唯一目的是按周期性间隔调用 Web 服务或 WCF 服务。
负载均衡器 - 这可能是基于硬件或软件的负载均衡器,其工作是分发请求。
执行业务逻辑的服务器 - 这些服务器将服务公开为 Web / WCF 服务。 在这些服务器中编写代码以确保可伸缩性,例如,如果我们想处理数据库中的记录或服务器上的文件,则此业务逻辑将锁定一些记录/文件,以便其他竞争服务器可以参与该任务。 这些服务器的设计方式还应确保如果先前的请求未完成,则新请求不应干扰先前的请求。
一些示例代码
这是一个非常简单的示例,其中每分钟,我们都会请求处理文件夹中放入的最新文档。
Timer timer = null;
protected override void OnStart(string[] args)
{
timer = new Timer(60 * 1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
}
当服务启动时,会触发服务的 OnStart
事件处理程序。 我们所做的只是在这里设置我们的计时器。
当计时器到期时,我们想要像此代码中一样调用 Web 服务
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
ServiceReferenceProxy.ServiceSoapClient webServiceProxy =
new ServiceReferenceProxy.ServiceSoapClient();
webServiceProxy.DoSomeTaskCompleted +=
new EventHandler<AsyncCompletedEventArgs>(webServiceProxy_DoSomeTaskCompleted);
webServiceProxy.DoSomeTaskAsync();
}
应该注意的是,为此,我们使用了 Web 服务方法上的异步操作。 这样做是为了如果任务未完成且计时器再次到期,我们将获得更好的可伸缩性。
还应注意的是,我们没有做任何具体的事情来在 Windows 服务端获得可伸缩性。 网络负载均衡器将为我们完成这项工作。
当 Web 服务任务完成时,我们可以选择记录或执行某些任务,这由 Completed 事件处理程序完成。
void webServiceProxy_DoSomeTaskCompleted(object sender, AsyncCompletedEventArgs e)
{
//Log Something
}
设置可伸缩性选项
本节指出了有关在网络上设置可伸缩性的一些参考资料
历史
- 2009年10月25日:首次发布