[原文发表地址]Installing and Running node.js applications within IIS on Windows - Are you mad?

[原文发表时间]2011-08-28 08:03

我们团队中的一些成员正在努力优化node.js在Windows上的运行效果。你可能会问一些问题。

首先,node.js是什么?

如果你不熟悉node.js,我要说这是一个炙手可热的新型web编程工具包。要是你没听说过会让你觉得自己很过时,就好像几年前Rail上的Ruby那样风靡。同行们把它称之为“Node”,简单来说是服务器端的JavaScript。如果你在客户端做一系列的JavaScript,而且时常一做就是一整天,那为什么不在服务器端试试呢。学起来应该很简单,我猜想是这样的。

如果你是一个ASP.NET编程员,你可以把node.js看成是用JavaScript写成的IhttpHandler。其实它的等级更低, 它连HttpHandler都不是,这里我只是想做一个类比。Brett McLaughlin写的一篇有关Node.js 更多细节以及概述的文章很不错。文章的副标题就是“Node不可能解决所有的问题,但的确可以解决一些重要的问题”,这个描述很贴切。

更新1为什么node.js那么重要?

为什么我们需要node呢?node有许多有趣的部分。它使用的是非常快速的JavaScript引擎V8,更重要的是它的I/O是异步的,而且与传统同步代码形成鲜明对比的是它的事件驱动。

举例来说,ASP.NET中的HttpHandler要用几秒来“做些什么”(如获取文件,访问服务等)如下所示:

 1: public class SimpleHandler : IHttpHandler 
 2: {
 3: public void ProcessRequest(HttpContext context)
 4: {
 5: Thread.Sleep(2000); //Do something that takes a while
 6: context.Response.Write("Hello from SimpleHandler");
 7: }
 8: 
 9: public bool IsReusable { get { return true; } }
 10: }

这用来处理大部分情况还是很好的。不过,当我用测试工具同时加载1000个虚拟客户端打算测试它的极限时,我一秒钟连60个请求都获取不到。请求线程和工作线程同时进行时,大家都在排队。我把ASP.NET程序池的资源都消耗光了。如果工作线程结束后能及时回调(Call Back)那就太完美了。这就好像在等待技术支持一样,你只能被迫等待一个结果。他们要是能在他们准备好之后及时通知你这不是很好吗?

ASP.NET一直可以(看看MSDN上一篇发表于2003年关于Async Handlers的 文章)通过IHttpAsyncHandler做很多工作,但过程繁复一点而且几乎没什么人知道。有了.NET内建的Async CTP和Task库,你就能在IhttpAsyncHandler的顶部创建更好的抽象元素。Ayende对AbstractAsyncHandler有一个简单的实例(有很多类似的应用,比如在我们自己的工具里,MVC里,还有SignalR里(将来还会有更多)),让我们可以用来做类似的工作。这个实例还可以做一些更复杂细小的事情,比如文件IO,数据库 IO或者调用web服务。这是一个再简单不过的例子,可能并没有完全同步Node,但基本还是可以的。而且,看上去还是不错的。

 1: public class SimpleAsyncAyendeHandler : AbstractAsyncHandler
 2: {
 3: protected override async Task ProcessRequestAsync(HttpContext context)
 4: {
 5: await TaskEx.Delay(2000);
 6: await context.Response.Output.WriteAsync("Hello from Ayende and Scott");
 7: }
 8: }

同样是同时处理1000个虚拟客户,我在一秒内收到了500个请求,每个请求大约需要2秒来完成,这样的效率是合理并可以接受的。如果我们不是在干等,而是在做I/O或者其他更复杂的长时间运行工作的话,效果会比第一个例子更好。有了上述两行代码的支持,以及Ayende的简单实例,在.NET中做异步代码和并行比以前方便许多。在Node中这样的东西既简单又优雅,的确是很吸引人的。

Node最擅长异步了,通过JavaScript进行回调来实现完整的异步。你已经会在客户端使用JavaScript调用和事件了,那为什么不融会贯通到服务器端呢?这里提供Marc Fasel针对这个话题的一篇博文实例

首先, 通过Marc实现一些同步文件工作:

 1: var fs = require('fs'), filenames, i, processId;
 2: 
 3: filenames = fs.readdirSync(".");
 4: for (i = 0; i < filenames.length; i++) {
 5: console.log(filenames[i]);
 6: }
 7: console.log("Ready.");
 8: 
 9: processId = process.getuid();

还有用异步来完成同样的工作,看上去很熟悉吧!

 1: var fs = require('fs'), processId;
 2: 
 3: fs.readdir(".", function (err, filenames) {
 4: var i;
 5: for (i = 0; i < filenames.length; i++) {
 6: console.log(filenames[i]);
 7: }
 8: console.log("Ready.");
 9: });
 10: 
 11: processId = process.getuid();

I/O开始后,回调函数则由I/O的执行的结果决定。很强大吧。

为什么要在WindowsIIS上运行node.js

Tomasz Janczuk最近在做iisnode项目。你可能会认为Windows和node完全不搭边。“这是不对的!他们在想什么?IIS都是.NET相关的东西?”那么你可以回忆一下几年前我在CodeMash上说的,有关IIS7和PHP,当时我也做了个截屏展示了IIS7, PHP和 FastCGI是怎么在一秒内聚齐上千的请求的。IIS的工作人员,Windows的工作人员,Azure的工作人员都希望Windows上所有东西都会运行顺畅。记住,我们是卖Windows的,它可以做越多的事对我们来说是好事。

干嘛还要让node在IIS上运行呢?

Tomasz的回答是我见过最棒的:

使用iisnode模块在IIS中托管node.js应用程序来取代自托管node.exe进程的优势在于:

· 进程管理。 Iisnode模式注重node.exe进程的长期管理,能够更简洁地改善整体可靠性。你无需实现用来运行,停止或者显示进程的基础工具。

· 多核服务器上的可扩展性。由于node.exe是一个单线进程,只可适用于单核CPU。而iisnode模块允许每个应用中创建多个node.exe进程,并根据HTTP流量调整使其负载平衡。,从而充分可以发挥服务器CPU性能,无需额外的基础代码。

· 自动更新。Iisnode模块保证了node.js应用随时保持更新(比如,在脚本文件变更时就会更新),node.exe进程得到循环。旧版本的应用能正确地完成正在进行中的请求执行,而所有的新请求都会分派到应用的最新版本。

· 通过HTTP访问日志。Iisnode模块提供通过HTTP访问node.exe进程中的输出。(比如,由console.log调用生成的输出)。这个功能是帮你调试在远程服务器上的node.js应用程序问题的关键。

· 与其他内容类型相连。 Iisnode模块与IIS相融,让一个单一的web页面能够涵盖许多内容类型。比如,一个单一的页面可以包含一个node.js应用,统计HTMLJavaScript文件,PHP应用和ASP.NET应用。这就让用户能随意挑选最适合的工具,并未已有应用完成迁移。

· 只需改变少部分node.js应用代码。 Iisnode模块支持最少的改动来托管现有HTTP node.js应用。你只需通过process.env.PORT环境变量把HTTP服务器列出的地址变为iisnode提供的地址就可以了。

融合管理体验。 issnode模块完全集成IIS配置系统,并使用相同的工具和机制,类似于IIS其它组件的配置和维护。

除了有利于iisnode模块中特定的点,在IIS中托管node.js应用还能让开发者从一系列IIS功能中获益匪浅,包括:

    • 端口共享(通过80多个端口托管多个HTTP应用)
    • 安全(HTTPS,身份验证和授权)
    • URL 重写
    • 压缩
    • 缓存
    • 日志

都非常有说服力,但在我看来,最有趣的要数一体化了。Iisnode模块是一个合理的IIS模块,就像ASP.NET和PHP一样。这就意味着你可以在一个单一的网站上看到多种内容。正如上述:

比如,一个单一的页站可以包含一个node.js应用,统计HTMLJavaScript文件,PHP应用和ASP.NET应用。

一些同仁们一听到我说,你可以在同一个AppPool中使用ASP.NET WebForms和ASP.NET MVC就好像“混血儿”一样,就会疯狂起来。亲爱的读者,大家都没有意识到IIS的强大和灵活性。当你插入像node一样的新东西,但还是按旧方法来操作时,它仍然会延续所有包含的优点。

好吧,你说服我了,那我要怎么在Windows上运行node.js呢?

我假定你运行的是IIS7.

· 去 下载node.exe,放在 c:\node

· 去 下载iisnode.

· 解压iisnode压缩包,解压到\inetpub\iisnode

· (只是我的建议,未必是最好的位置)

· 以管理员身份在命令行中运行install.bat。

Install.bat将会:

· 从你安装的IIS中取消注册已有的“iisnode”全局模块,如果你已经注册过的话。

· 在你的安装的IIS中注册iisnode为本地模块

· 安装“iisnode”模块配置文件

· 从applicationHost.config中的system.webServer组移除现有“iisnode”部分

· 在applicationHost.config中的system.webServer组添加新的“iisnode”部分

· 如果有iisnode web应用,直接删除

· 为IIS添加新的iisnode站点

没有保证!要小心,你是在边缘行走。记住,你只是在偶然看到的博客上看到这篇文章。

警告:我搞不清楚正确的AppPool和文件系统权限,所以我直接给了我本地AppPool“SYSTEM”的权限。这很糟糕,都是我的错。我在iisnode GitHub上写下了问题,等他们有回复时我会想办法修复然后更新的。

我为node做了个新的AppPool,给了它SYSTEM的访问权限,然后将Node Site分配给这个新的AppPool。你的站点看上去就是这样的:

如果你在IIS7的这个页面上点击这个模块,你将会看到iisnode是本地模块:

现在,你可以点击http://localhost/node/helloworld/hello.js 然后得到回馈:

Hello, world! [helloworld sample]

内容很简单:

 1: var http = require('http');
 2: 
 3: http.createServer(function (req, res) {
 4: res.writeHead(200, {'Content-Type': 'text/plain'});
 5: res.end('Hello, world! [helloworld sample]');
 6: }).listen(process.env.PORT);

很棒吧。

玩玩WCAT(Web容量分析工具)和node。

免责声明:先说清楚,这只是玩玩。不过为了展示它的确能用,而且运行的速度很快。我做的不是基准内容,我也没说过“这个运行起来比别的工具好”。记住,他们最近刚刚起步,把node迁移到Windows,Tomasz和他的朋友们最近才开始做。所以不要期望太高。话说回来,他们现在做成的内容已经很叹为观止了。

我真是有些激动了。我是说把一个新的东西安装到另一个新的东西上,然后只运行一次就成功了。我做完一系列基础工作之后,我想做一些简单的压力测试看看大家做了些什么。

首先,我安装了WCAT,一款IIS团队开发的免费Web容量分析工具。

1. WCAT 6.3 x86

2. WCAT 6.3 x64

警告:这是一个仅支持命令行的工具,运行起来真的有点小家子气。有点混乱,设置安装也花了我点时间。以下是我安装的步骤。都是从管理者权限的命令提示符中执行的。注意我是在同一台机器上做的,记住这是GOM 。

1. cscript //H:Cscript

2. wcat.wsf –terminate –update –clients localhost

3. 然后我建了一个文件夹命名为\nodetests,然后把这三个文件放了进去。

wcat.bat

pushd C:\Users\Scott\Desktop\nodetests 
"c:\program files\wcat\wcat.wsf" -terminate -run -clients localhost -f settings.ubr -t nodescenario.ubr -s localhost -singleip -o C:\Users\Scott\Desktop\nodetests 
pause

nodescenario.ubr (你可以随意命名)

这也很简单。它会被4个示例程序一一调用。

 1: scenario
 2: {
 3: name = "node_fun";
 4: 
 5: warmup = 30;
 6: duration = 90;
 7: cooldown = 30;
 8: 
 9: default 
 10: 
 11: setheader
 12: {
 13: name = "Connection";
 14: value = "keep-alive";
 15: }
 16: setheader
 17: {
 18: name = "Host";
 19: value = server();
 20: }
 21: version = HTTP11;
 22: statuscode = 200;
 23: close = ka;
 24: }
 25: 
 26: transaction
 27: {
 28: id = "foo";
 29: weight = 1000;
 30: request
 31: {
 32: url = "/node/logging/hello.js";
 33: }
 34: }
 35: transaction
 36: {
 37: id = "bar";
 38: weight = 2000;
 39: request
 40: {
 41: url = "/node/helloworld/hello.js";
 42: }
 43: }
 44: transaction
 45: {
 46: id = "baz";
 47: weight = 2000;
 48: request
 49: {
 50: url = "/node/defaultdocument/";
 51: }
 52: } 
 53: transaction
 54: {
 55: id = "bat";
 56: weight = 2000;
 57: request
 58: {
 59: url = "/node/configuration/hello.js";
 60: }
 61: } 
 62: }

settings.ubr

我从别的例子中复制过来并去掉注释然后进行了一点修改(在测试过程中修改的):

 1: server = "hexpower7";
 2: clients = 1;
 3: virtualclients = 8;

现在,运行以测试

然后,我以管理者身份运行wcat.bat。你会看到node.exe开始行动。

(记得他们是以SYSTEM运行的,因为我搞不清正确的权限,是我的错。我总有一天会搞清楚的。)

这是WCAT工具的控制台输出。我可以连续在一秒内做一万个HelloWorld,这最终会是上百万个正常请求并且在90秒内得到回应。那可是很多个HelloWorld。

记住Hanselman的运行法则。

“什么都不做,那就有无限的可能”—我

当然,这些都是在一台配置不错的机器的本地操作。这不过是个HelloWorld(外加一些日志),所以没有太多的测试node和IIS,不过倒是测试了整个系统,IIS,iisnode和node本身的合作互动。

另:ASP.NET IhttpHandler在同台机器上做同样的事情,结果是在一秒内有22500个请求,所以node和iisnode还有上升空间,这是个好消息。

以下是node/iisnode的结果:

还有很多东西我可以配置在两个站点上,客户数量,虚拟客户,还有iisnode特定设置(都在web.config中管理):

 1: <configuration>
 2: <system.webServer>
 3: <handlers>
 4: <add name="iisnode" path="hello.js" verb="*" modules="iisnode" />
 5: </handlers>
 6: <iisnode 
 7: nodeProcessCommandLine="%systemdrive%\node\node.exe"
 8: maxProcessCountPerApplication="4"
 9: maxConcurrentRequestsPerProcess="1024"
 10: maxPendingRequestsPerApplication="1024"
 11: maxNamedPipeConnectionRetry="3"
 12: namedPipeConnectionRetryDelay="2000" 
 13: asyncCompletionThreadCount="4"
 14: initialRequestBufferSize="4096"
 15: maxRequestBufferSize="65536"
 16: uncFileChangesPollingInterval="5000"
 17: gracefulShutdownTimeout="60000"
 18: loggingEnabled="true"
 19: logDirectoryNameSuffix="logs"
 20: maxLogFileSizeInKB="128"
 21: appendToExistingLog="false"
 22: />
 23: </system.webServer>
 24: </configuration>

相当酷的东西。我很高兴能与这个团队合作,一起致力于让IIS上的应用性能更好。我很惊讶现在竟然可以不用VM就开始鼓捣node。等我学到更多的东西我还会回来跟大家分享的,不见不散。

相关链接

· 下载node.js

· GitHub上的iisnode项目

· 下载iisnode二进制文件

在Window IIS中安装运行node.js应用—你疯了吗的更多相关文章

  1. 在Sublime Text 3 中安装SublimeLinter,Node.js进行JS&CSS代码校验

    转载自:http://www.wiibil.com/website/sublimelinter-jshint-csslint.html 在Sublime Text中安装SublimeLinter,No ...

  2. ubantu 14.04中安装npm+node.js+react antd

    今天折腾了半天,各种安装问题,最终还是装上了: 1.安装npm $ sudo apt install npm 2.升级npm $ sudo npm install npm@latest -g 输入np ...

  3. 玩儿转物联网IoT - 在Beagle Bone Black上运行node.js 程序

    物联网(IoT)技术方兴未艾,智能手环,智能血压计,智能眼镜甚至智能鞋垫都开始进入我们的生活,各种智能设备层出不穷,世界已经到了一个"人有多大胆,地有多大产"的时代,不玩儿点物联网 ...

  4. VPS 运行 Node.js 的一些经验

    VPS 系统选择 各系统安装难易对比 Ubuntu.Debian 较为简单,CentOS 稍麻烦,32位系统比64位更节省内存 DigitalOcean 甚至推出了 Ubuntu + Node.js ...

  5. Node.js的安装以及Node.js的模块管理

    索引: Node.js的安装以及Node.js的模块管理Node.js开发环境搭建以及对ES6的支持Node.js构建Vue.js项目Vue.js单文件组件的开发基于Vue.js的UI组件(Eleme ...

  6. LocalDB在IIS中的运行失败

    Using LocalDB with Full IIS, Part 1: User Profile http://blogs.msdn.com/b/sqlexpress/archive/2011/12 ...

  7. 前端环境安装(node.js+npm+grunt+bower)

    前端开发环境安装(本教程不带开发工具的安装教程,只是环境安装) 本人机器环境win7 64位. 一.node.js安装 进入官网下载node.js文件,http://www.nodejs.org/ 2 ...

  8. 如何在 Android 安卓手机上运行 Node.js 应用 | 如何在安卓手机配置node开发环境

    最近在学习js,由于没法随身携带笔记本电脑,在手机翻阅<JavaScript高级程序设计>时,时常想调试一下书中的代码.于是就有了,能否在手机上配置一个js开发环境.考虑到手机上的Chro ...

  9. 在SUBLIME TEXT中安装SUBLIMELINTER进行JS&CSS代码校验

    一:Sublime Text 中需要先安装Package Control.(如果有则无需安装) 安装方法:打开Sublime Text控制台(快捷键Ctrl+`),在控制台粘贴以下代码,按回车执行. ...

随机推荐

  1. Using breakpad in cocos2d-x 3.2,dump信息收集

    作者:HU 转载请注明,原文链接:http://www.cnblogs.com/xioapingguo/p/4037268.html 一.基本步骤 1.生成转换工具 2.把breakpad加入到项目 ...

  2. HDU 5289 Assignment(2015 多校第一场二分 + RMQ)

    Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

  3. UITableViewcell autolayout下动态高度

    项目中最经常使用的一个UI就是UITableView了.iOS7.8进一步优化了复用机制,用起来相当爽.配合Autolayout,适配工作减轻了非常多. 曾经做适配工作都是在heightForRow里 ...

  4. 【48】认识template元编程

    1.TMP(template metaprogramming),模版元编程有两个效力:第一,它让某些事情更容易:第二,可将工作从运行期转移到编译期.

  5. hdu 5445 Food Problem 多重背包

    Food Problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5 ...

  6. iOS开发——网络编程OC篇&GCDAsyncSocket编程

    GCDAsyncSocket编程 同上一篇文章一样,这里也是使用Socket实现一个聊天室,但是这里使用的是一个常用的框架实现的:GCDAsyncSocket 一:导入这个框架 二:声明这个Socke ...

  7. ATF批量导出工具

    ATF批量导出工具 08 / 31, 2013 批量导出Atf的工具,使用是adobe atf 编码核心 先说一下关于atf的bug 当atf导出时候启用了mips选项会导致:如果纹理问长方形时上传会 ...

  8. android118 上拉下拉刷新列表listView实现

    MainActivity.java package com.heima52.pullrefresh; import java.util.ArrayList; import com.heima52.pu ...

  9. 将字符串写进txt中方式

    try { File file = new File(filePath); PrintStream ps = new PrintStream(new FileOutputStream(file)); ...

  10. 将WSDL文件生成的Java文件