Windows Service 和 IIS 内 Application 之比较
这次dp2图书馆集成系统升级到2.0版本,其中一个重大的改进就是把若干宿主于IIS的服务器模块改为Windows Service形式。
这里对两种模块形式进行技术上的比较。以阐明这次升级的必要性和重要性。
dp2图书馆集成系统的1.0版本,当时选择若干服务器模块宿主于IIS,作为IIS里面的Application来实现,是由于这些服务器模块都需要WebService的能力,而当时Micsrosoft的开发方式中,只有IIS里面的Application能实现携带WebService接口的服务器模块功能。也就是说,当时Microsoft强迫WebService的开发者使用宿主于IIS的方式。
这种方式的缺点很多,比较重要的有:
1) IIS假定WebApplication适合多重启动和并行。从IIS 6.0的重叠启动功能就可以看出这方面的一些端倪。这是基于一种假定,就是WebApplication并不是数据源,它只是实现一些页面发生的功能,多重启动不但不是有害的,而且还是有益的。如果按照这种思路,势必要为一个服务器模块先设计出独立的数据层,例如实现为Windows Service形式,然后再在WebApplication中构造为各种页面,实现界面和交互功能。
如果说为了开发一个Web界面,这种做法是可以接受的,但是类似rmsws这样的纯数据服务模块,根本没有什么Web界面的必要,非要它宿主在IIS下面,这就是有些莫名其妙了。在这种既有格局下,如果另行实现一个Windows Service模块,和WebApplication配合,两个模块一起实现功能也是可能,但是,这个Windows Service模块和WebApplication之间靠什么设施来通讯呢?用WebService? 可是当时分明只能是WebApplication才能用.asmx实现WebService接口嘛,这就陷入了一个怪圈:
如果按照上面模式编写一个Windows Service模块,并自行为这个模块配备了类似RPC之类的通讯设施,那就似乎没有再寻找一个外壳WebApplication来装配成WebService模块的必要了,这个Windows Service模块自己和前端通讯不就得了。
所以,当时的开发小组,被迫在WebApplication里面实现全部功能,成为一个希望单一启动的Instance,而IIS的重叠启动等等的本来为WebApplication而服务器的“好”机制,变成了这样的纯数据服务模块的烦恼。这样,应用经常会被不经意重新启动,软件产品在如何处理随时升、降的Instance方面耗费了不少开发力量,而这些本来是可以避免的。
在用户方面,也增加了一些管理上的成本和消耗。当然,也不是全无好处,可以说好处是锻炼了系统管理员,使他们从各个方面加倍熟悉了IIS的配置和管理。
2) IIS这个额外多出来的要求,限制了服务器模块的安装环境,使得可安装环境范围变得狭窄。也就是说,必须要预先安装有IIS的服务器,才能安装这些服务器模块。dp2图书馆集成系统不囿于“阳春白雪”的自我定位中,其实它也很希望在比较轻型、小型的环境中发挥它的长处,想大展拳脚,想全线通吃。这样,安装环境的限制就造成了不少的遗憾。
3) IIS为了网络安全考量,对里面WebApplication的执行权限进行了若干限制,这样造成安装过程复杂,例如需要为数据目录专门增添特定的Windows用户权限。这些都是额外的开销。
4) IIS只允许Web类的相关通讯协议,例如HTTP协议,限制了采用诸如namepipe之类协议的可能。但是,我们知道,其实很多将几个服务器模块安装在同一台机器的情况下,模块之间本可以采用namepipe之类的协议,运行速度可能更快一些。同时因为不使用HTTP协议,某种角度增强了安全性(namepipe只能在本机内起作用)。
5) 不管IIS理论上安全性如何,IIS的所谓安全性在人群中的口碑不是太好,常有人诟病它的安全性。dp2图书馆系统的服务器模块,特别是纯粹提供数据服务的模块,本来根本没有必要使用IIS,平白担上IIS的风险,这有些冤枉。
现在好了。自动Microsof发布WCF框架以来,WCF就提供了独立宿主这样一种可能,也就是说如果要实现WebService接口,没有必要非宿主在IIS之内。实际上,宿主于IIS已逐渐退位为一种另类的方式了。
作为服务器模块,通常是实现为Windows Service,这样,只要服务器启动,无论是否登录进入控制台桌面环境,服务器模块都是可用的。
对应于上面说的几点宿主于IIS的缺点,现在说说作为独立的Windows Service模块的好处:
1) 完全独立的Instance。一经启动,就长期稳定运行,不会无端重启。
2) 安装环境非常广泛,没有什么限制。因为服务器模块是自带HTTP协议的,即便是使用HTTP协议,也不必借助IIS。只要是.NET Framework 4.0能安装的环境,服务器模块都可以安装。
3) 通常Windows Service本来就是以最高权限运行的,不需要为其数据目录额外设定什么Windows用户权限,安装非常简便。
4) 除了HTTP协议,服务器模块也支持namepipe等协议,能比较灵活地利用环境优势。
5) 从安全性的角度,首先在没有必要使用HTTP协议的场合可以不使用它,另外,即便是使用HTTP协议,新的服务器模块由于只支持基本的WebService调用,没有IIS的各种后门和漏洞,安全性也得以提升(实际上是一种回归)。而类似OPAC模块这样必须宿主于IIS的模块,由于其下级(例如dp2library和dp2kernel)层次被有效隔离(例如分置到不同的服务器,被防火墙所保护),由于OPAC主要是对信息的读取访问,写入和修改较少,少量的写入和修改也是在完整的帐户权限体系约束下进行的,所以整体安全性是很高的。
这样就返归正途了。有时候,这类事情会让我们不得不感叹,来得早不如来得巧。利用WCF方式来实现服务器模块的WebService接口,也算是Microsoft首次实现WebService的.asmx方式以后的“第二版”。常有说法是,每个程序员都有2.0情结,一般来说,一个产品的2.0版本才能接近成熟的,每个程序员都渴望实现自己的第二版产品。
正巧,我们现在推出的就是2.0版。其客观的2.0地位,恰逢其时,是个好彩头,让我们祝福这个产品一路走好。
Windows Service模块形式,会更“不显山不露水”,深藏在后面,给系统提供坚实的服务基础。这也符合我们公司求真务实低调的价值取向和品味所在。