Press "Enter" to skip to content

在IIS里运行nodejs站点

这是一个很神奇的功能,可以让你的nodejs开发的web server程序直接运行在iis里面,由iis作为deamon程序,即可以解决nodejs本身的单进程单线程问题,又可以实现把nodejs站点托管到80端口上的功能。而且,nodejs的站点即可以作为一个独立的站点来运行,也可以作为已有的asp.net网站中的一个虚拟目录来运行,完全没有影响。微软对nodejs的社区还是提供了很大的支持的,比如官方提供了sql server的nodejs驱动。

要实现这个功能,基于这样一个项目:https://github.com/WindowsAzure/iisnode,它实现的是一个IIS Module,全局加载到IIS中以后,就可以在任意一个站点中,通过Web.config来指定把某些路径转交给node程序来解释执行,同时可以配置一些额外参数,比如启动多少个nodejs进程,每个进程最大允许多少个连接,允许多少个等待中的连接等等。而且这个module本身还有监视站点文件变化的功能,当你修改了某个js文件,它可以自动重启加载。

你可以下载项目的源代码,自己编译,也可以下载官方已经提供的安装程序。(必须使用安装程序,因为注册为IIS Module需要一些系统注册动作,因为一开始一直找不到最新版的官方的安装程序,就想自己编译一个,结果vs2013又不支持wix项目,只生成了两个dll,修改iis全局配置,搞了几个小时也没有生效,后来找到安装程序以后一下子就成功了。当然,也是因为一开始没有读清楚这个项目的页面上写的编译说明,没有安装http://wix.codeplex.com/这个东西,其实要自己编译生成安装程序还是比较容易的。)推荐windows server 2008及以上,IIS7以上。

首先需要在你的服务器上安装node,建议也使用安装程序吧,可以自动帮你设置path。安装了node以后再安装iisnode,你可以使用这个地址:iisnode-full-iis7-v0.2.7-x64-2.msi。安装完以后它的安装目录下有个www目录,还有个安装测试站点的bat脚本。如果有兴趣你也可以直接使用这个脚本,它会在你的IIS的默认站点下建立一个node的虚拟目录,指向这个www,这样就可以直接看到下面提供的五个测试站点了。

web.config里面只有一句比较重要,就是一个handler配置,你可以把站点中的启动文件,比如app.js,指定用iisnode这个module来托管。然后在浏览器中打开localhost/node/app.js,就可以看到执行结果(如果你的app.js里没有引用非node基本模块的话)。

如果你的项目使用了基本模块之外的依赖,那就需要先npm install一下,这个过程可能很顺利,也可能很痛苦,如果你要安装的东西不需要根据平台重新编译,安装就会直接完成,但是如果需要重新编译,那就比较麻烦,你需要安装visual studio。目前你可以选择在服务器上安装visual studio express 2012 for windows desktop,千万不要装错。中文版大概是一个600多M的iso文件,直接安装就可以。安装完成以后再运行npm install –msvs_version=2012(如果不加这个参数,默认是2010版的编译程序,应该会提示无法加载vcbuild.exe之类的错误)可能还会看到一些警告,不过正常来说应该能编译通过了。不过也有些还会继续有依赖,比如crypt,它需要openssl的头文件。你要下载一个16M的64位windows的完整版openssl,安装到C盘,再来运行npm install。另外也有一些模块依赖的头文件只有unix系统上有提供,那就只好完全放弃了。比如sleep,完全无法编译通过,只能放弃这个函数,改用setTimeout来解决。

做完这些以后,我的整个demo项目的代码就可以完全跑起来了(前提是你还安装好了mongodb的windows版并已经启动)。测试了一下,速度相当快。启动了两个node进程,只占用了150M内存。

另外,还有一点需要处理,就是URL映射。可以通过IIS的urlrewrite模块,把public下的静态文件直接rewrite到文件目录,由IIS来直接提供,不经过node,然后其它路径全部rewrite到app.js上。这时候在node里面看到的程序路径是当前访问的完整路径,所以如果你把这个项目放在一个虚拟路径下,那么在app.get(‘/’)这个url的时候,就要把虚拟目录这一层加进去才可以了。

这样,就你可以在整个asp.net的站点下,把一部分功能交给nodejs来完成。比如,nodejs最擅长的RESTFul形式的api,以及访问量巨大但单个请求负载不高的内容。