Search:nodejs相关搜索

webpack入门——webpack 配置
dquo;web” 在浏览器中使用的编译环境(默认值) “webworker” 被作为webworker编译 “node” 在nodejs环境下编译(用require加载chunks) “async-node” 在nodejs环境下编译(用fs和vm异步加载chunks) “node-web
2018/5/30 Comments:
vue-cli#2.0 webpack 配置分析
DE_ENV) process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)var path = require('path') // 使用 nodejs 自带的文件路径工具var express = require('express') // 使用 expressvar webpack = require('webpack') // 使用 webpac
2016/12/28 Comments:
Windows2008在IIS7.x上安装iisnode配置实现Express访问
今年年初打算用Node.js基于Express框架重写博客程序,从此告别ASP.NET。然而,我目前用的VPS是Windows Server系统、IIS服务器,如果让Express和IIS都监听80端口,明显会产生冲突。幸好,有一个叫做iisnode的扩展可以把Node.js程序托管到IIS。而且,这样托管之后也意味着可以使用IIS里面的各种功能(进程管理、GZip压缩、日志、缓存、权限控制、域名绑定等)。...今年年初打算用Node.js基于Express框架重写博客程序,从此告别ASP.NET。然而,我目前用的VPS是Windows Server系统、IIS服务器,如果让Express和IIS都监听80端口,明显会产生冲突。幸好,有一个叫做iisnode的扩展可以把Node.js程序托管到IIS。而且,这样托管之后也意味着可以使用IIS里面的各种功能(进程管理、GZip压缩、日志、缓存、权限控制、域名绑定等)。要使用iisnode,得安装: Node.js IIS的URL Rewrite模块 iisnode(例如:https://github.com/azure/iisnode/releases/download/v0.2.21/iisnode-full-v0.2.21-x64.msi 可以使用迅雷下载)装好之后,还是按照常规操作,在IIS管理器中创建站点,指向Express程序的目录,关键是还要增加一个web.config文件:<configuration> <system.webServer> <handlers> <add name="iisnode" path="bin/www" verb="*" modules="iisnode" resourceType="Unspecified" requireAccess="Script" /> </handlers> <rewrite> <rules> <rule name="all"> <match url="/*" /> <action type="Rewrite" url="bin/www" /> </rule> </rules> </rewrite> </system.webServer></configuration>这段内容也可以通过IIS管理器的可视化界面配置。大概意思把所有请求重写到bin/www,而且使用iisnode扩展运行bin/www。然而,打开站点后,却出现了这样的错误提示:请求筛选模块被配置为拒绝包含 hiddenSegment 节的 URL 中的路径起初是觉得不明所以,后来突然醒悟,ASP.NET里面的bin目录是个不允许访问的特殊目录。把请求重写到bin/www,恰好命中了这条规则。所以呢,改一下目录名就好了,比如把bin改成launch(事实证明这不是好做法,后面再说),web.config也要对应调整:<configuration> <system.webServer> <handlers> <add name="iisnode" path="launch/www" verb="*" modules="iisnode" resourceType="Unspecified" requireAccess="Script" /> </handlers> <rewrite> <rules> <rule name="all"> <match url="/*" /> <action type="Rewrite" url="launch/www" /> </rule> </rules> </rewrite> </system.webServer></configuration>在IIS管理器中重启站点后再次访问,终于运行起来了,不容易啊!不过还是高兴得太早了。在测试程序功能的过程中,竟然发现获取到的IP为空。在Express框架中,IP是通过req.ip获取的,而req.ip又是从请求头的REMOTE_ADDR获取值。通过一段简单的测试代码,发现REMOTE_ADDR的值也为空。很明显,从IIS到Node.js的过程中,这段头信息丢失了。Google一番之后,发现iisnode确有此问题,官方提供的解决方案是使用X-Forword-For,不过我又发现了另外一个办法。Web.config中有一段配置(加到</system.webServer>前)可以保留REMOTE_ADDR:<iisnode promoteServerVars="REMOTE_ADDR" />根据说明,保留的REMOTE_ADDR会被改名为x-iisnode-REMOTE_ADDR,所以还得把req.ip的值覆盖一次,在Express的app.js中增加一个中间件函数:app.use(function(req, res, next) { req.ip = req.headers['x-iisnode-remote_addr']; next();});然而,这样调整后,获取到的IP还是空,这不免让人怀疑,req.ip的赋值是不是失败了。看一下Express的源代码可以发现,req.ip是通过define getter的方式定义的,所以要覆盖它就得再define一次:app.use(function(req, res, next) { Object.defineProperty(req, 'ip', { get: function() { return this.headers['x-iisnode-remote_addr']; } }); next();});这样问题终于解决了,但这不是一个好方法,要是以后Express把req.ip设成只读就麻烦了。继续测试,又发现另外一个问题。正常来说,博客后台的文件上传功能会把文件传到public/upload这个目录下,但实际上却在launch目录(即原来的bin目录)下生成了public/upload文件夹。其实原因是作为程序入口的www文件是在launch目录下,所以launch目录成了应用程序的执行目录。我的解决办法是,把launch目录的名字改回bin,在根目录下创建一个launch.js去调用bin/www:#!/usr/bin/env noderequire('./bin/www');然后把程序入口改为launch.js:<configuration> <system.webServer> <handlers> <add name="iisnode" path="launch.js" verb="*" modules="iisnode" resourceType="Unspecified" requireAccess="Script" /> </handlers> <rewrite> <rules> <rule name="all"> <match url="/*" /> <action type="Rewrite" url="launch.js" /> </rule> </rules> </rewrite> <iisnode promoteServerVars="REMOTE_ADDR" /> </system.webServer></configuration> 当放到Window Server 2008 R2服务器上后,出现如下错误提示: iisnode encountered an error when processing the request. HRESULT: 0x2HTTP status: 500HTTP subStatus: 1002HTTP reason: Internal Server Error
2016/12/8 Comments:
Expressjs的安装创建与启动(pm2重启express)
初次接触nodejs,想快速用nodejs建个站,于是找到了expressjs这个框架,摸索了许久才弄明白expressjs项目的创建与启动,现在分享一下。前提环境:window系统、已安装nodejs、已联网。补充:在安
2015/9/18 Comments:
如何构建Web前端模拟服务器(Mock Server)? - 大前端进化论
虑使用jetty,一个1.8M的jar即可;如果是php的后端,可以考虑使用php 5.4以后内置的server,启动命令是 php -S 127.0.0.1:3000 router.php;如果是nodejs,那就很简单了,估计都不需要Mock Server,本地也可以跑的 当代理数据接口的生产/测试环境不具备新接口的时候,Mock Server要在本地制造假数据响应请求,可以使用 http
2015/9/9 Comments:
跨域CORS 带Cookie传递,在nodejs + express中的具体实现
st(AJAX) 中已经支持了这个协议。可以实现ajax跨域访问。(其实IE8也实现了,只不过是另外一个对象)由于是跨来源的的访问,标识HTTP状态的Cookie的使用有一些特别处理。Server nodejs 代码res.setHeader('Access-Control-Allow-Origin', req.headers.origin);//注意这里不能使用 * res.setHeader('Acces
2015/5/5 Comments:
Nginx与nodejs实现简单的代理跨域(proxy_pass)
在用nodejs时,有个地方需要用到跨域,使用   app.use(function(req, res, next){         res.he
2014/11/3 Comments:
Karma和Jasmine实现自动化单元测试 以及istanbul检测代码覆盖率
ma和istanbul代码覆盖率 Karma第一次启动时出现的问题前言在Java领域,Apache, Spring, JBoss 三大社区的开源库,包罗万象,但每个库都在其领域中都鹤立鸡群。而nodejs中各种各样的开源库,却让人眼花缭乱,不知从何下手。nodejs领域: Jasmine做单元测试,Karma自动化完成单元测试,Grunt启动Karma统一项目管理,Yeoman最后封装成一个项
2014/8/27 Comments:
cmd下报错:'karma'不是内部或外部命令 ERROKarma安装后找不到指令
Ubuntu 14下:Karma:未找到命令根据官方教程,当但装了nodejs,并且通过npm 成功安装了Karma,但是你输入Karam的时候显示如下:Ubuntu 14下:Karma:未找到命令根据官方教程,当但装了nodejs,并且通过npm 成功安装了Karma,但是你输
2014/8/27 Comments:
10个nodejs的性能优化技巧
下面是我们使用Node.js时遵循的10个性能规则:1. 避免使用同步代码在设计上,Node.js是单线程的。为了能让一个单线程处理许多并发的请求,你可以永远不要让线程等待阻塞,同步或长时间运行的操作。Node.js的一个显著特征是:它从上到下的设计和实现都是为了实现异步。这让它非常适合用于事件型程序。不幸的是,还是有可能会发生同步/阻塞的调用。例如,许多文件系统操作同时拥有同步和异步的版本,比如writeFile和writeFileSync。即使你用代码来控制同步方法,但还是有可能不注意地用到阻塞调用的外部函数库。当你这么做时,对性能的影响是极大的。// Goo下面是我们使用Node.js时遵循的10个性能规则:1. 避免使用同步代码在设计上,Node.js是单线程的。为了能让一个单线程处理许多并发的请求,你可以永远不要让线程等待阻塞,同步或长时间运行的操作。Node.js的一个显著特征是:它从上到下的设计和实现都是为了实现异步。这让它非常适合用于事件型程序。不幸的是,还是有可能会发生同步/阻塞的调用。例如,许多文件系统操作同时拥有同步和异步的版本,比如writeFile和writeFileSync。即使你用代码来控制同步方法,但还是有可能不注意地用到阻塞调用的外部函数库。当你这么做时,对性能的影响是极大的。// Good: write files asynchronouslyfs.writeFile('message.txt', 'Hello Node', function (err) { console.log("It's saved and the server remains responsive!");}); // BAD: write files synchronouslyfs.writeFileSync('message.txt', 'Hello Node');console.log("It's saved, but you just blocked ALL requests!");我们的初始化log在实现时无意地包含了一个同步调用来将内容写入磁盘。如果我们不做性能测试那么就会很容易忽略这个问题。当以developer box中一个node.js实例来作为标准测试,这个同步调用将导致性能从每秒上千次的请求降至只有几十个。2.关闭套接字池Node.js的http客户端会自动地使用套接字池:默认地,它会限制每台主机只能有5个套接字。虽然套接字的重复使用可能会让资源的增加在控制之下,但如果你需要处理许多数据来自于同一主机的并发请求时,将会导致一系列的瓶颈。在这种情况下,增大maxSockets 的值或关闭套接字池是个好主意:// Disable socket pooling var http = require('http');var options = {.....};options.agent = false;var req = http.request(options)3.不要让静态资源使用Node.js对于css和图片等静态资源,用标准的WebServer而不是Node.js。例如,领英移动使用的是nginx。我们同时还利用内容传递网络(CDNs),它能将世界范围内的静态资拷贝到服务器上。这有两个好处:(1)能减少我们node.js服务器的负载量(2)CDNs可以让静态内容在离用户较近的服务器上传递,以此来减少等待时间。4.在客户端渲染让我们快速比较一下服务器渲染和客户端渲染的区别。如果我们用node.js在服务器端渲染,对于每个请求我们都会回送像下面这样的HTML页面:<!-- An example of a simple webpage rendered entirely server side --> <!DOCTYPE html><html> <head> <title>LinkedIn Mobile</title> </head> <body> <div class="header"> <img src="http://mobile-cdn.linkedin.com/images/linkedin.png" alt="LinkedIn"/> </div> <div class="body"> Hello John! </div> </body></html>请注意观察这个页面所有的内容,除了用户的名字,其余都是静态内容:对于每个用户和页面重载内容都是一样的。因此更有效的作法是让Node.js仅以JSON形式返回页面需要的动态内容。{"name": "John"} 页面的其余部分—所有静态的HTML标记-能放在JavaScript模板中(比如underscore.js模板):<!-- An example of a JavaScript template that can be rendered client side --> <!DOCTYPE html><html> <head> <title>LinkedIn Mobile</title> </head> <body> <div class="header"> <img src="http://mobile-cdn.linkedin.com/images/linkedin.png" alt="LinkedIn"/> </div> <div class="body"> Hello <%= name %>! </div> </body></html>性能的提升来自于这些地方:如第三点所说,静态JavaScript模板能通过webserver(比如nginx)在服务器端提供,或者用更好的CDN来实现。此外,JavaScript模板能缓存在浏览器中或存储在本地,所有初始页面加载以后,唯一需要发送给客户端的数据就是JSON,这将是最有效果的。这个方法能极大性地减少CPU,IO,和Node.js的负载量。5.使用gzip许多服务器和客户端支持gzip来压缩请求和应答。无论是应答客户端还是向远程服务器发送请求,请确保充分使用它。6.并行化试着让你所有的阻塞操作-向远程服务发送请求,DB调用,文件系统访问并行化。这将能减少最慢的阻塞操作的等待时间,而不是所有阻塞操作的等待时间。为了保持回调和错误处理的干净,我们使用Step来控制流量。7.Session自由化领英移动使用Express框架来管理请求/应答周期。许多express的例子都包含如下的配置:app.use(express.session({ secret: "keyboard cat" })); 默认地,session数据是存储在内存中的,这会给服务器增加巨大的开销,特别是随着用户量的增长。你可以使用一个外部session存储,比如MongoDB或Redis,不过每一个请求将会导致远程调用来取得session数据的开销。在可能的情况下,最好的选择就是在服务器端存储所有的无状态数据。通过不包含上述express配置让session自由化,你会看到更好的性能。8.使用二进制模块如果可能,用二进制模块取代JavaScript模块。例如,当我们从用JavaScript写的SHA模块转换到Node.js的编译版本,我们会看到性能的一个大跃进:// Use built in or binary modulesvar crypto = require('crypto');var hash = crypto.createHmac("sha1",key).update(signatureBase).digest("base64");9.用标准的 V8 JavaScript 取代客户端库许多JavaScript库都是为了在web浏览器上使用而创建的,因为在JavaScript环境不同时:比如,一些浏览器支持forEach,map和reduce这样的函数,但有些浏览器不支持。因此客户端库通常用许多低效的代码来克服浏览器的差异。另一方面,在Node.js中,你能确切地知道哪些JavaScript方法是有效的:V8 JavaScript引擎支撑Node.js实现ECMA-262第五版中指定的ECMAScript。直接用标准的V8 JavaScript函数替代客户端库,你会发现性能得到显著的提高。10.让你的代码保持小且轻使用移动设备会让访问速度慢且延迟高,这告诉我们要让我们的代码保持小且轻。对于服务器代码也保持同样的理念。偶尔回头看看你的决定且问自己像这样的问题:“我们真的需要这个模块吗?”,“我们为什么用这个框架,它的开销值得我们使用吗?”,“我们能用简便的方法实现它吗?”。小轻且的代码通常更高效、快速。试试看我们很努力地让自己的移动应用变得快速。在IPhone应用,Android应用和HTML5移动版本这些平台上尝试一下,让我们知道自己做得怎么样。
2014/7/18 Comments:
在Windows8.1下安装Node.js、npm、express
录一下Node.js在Win8下的安装,NPM是Node.js的包管理工具,Express是Node.js的常用框架。一、安装Node.js:(我用的是下面第二种方法)1.普通安装:在http://nodejs.org/download/处下载对应的msi文件,点击安装,一路到底,结束;2.干净安装:同样是在http://nodejs.org/download/处,下载Windows Binary (.exe
2014/6/24 Comments:
分享Node.js简单的异步操作管理器
最近写nodejs比较多,刚开始的时候碰到的异步的操作比较少,因为想做的东西比较简单,一查api有同步的,为了省事就直接用同步的搞了,慢慢发现这不是个事呀,好好的异步特性不用,非得用同步的,真囧,并且很多东西木有同步的a
2014/6/6 Comments:
使用Yeoman,Grunt和Bower开发AngularJS(译)
主要骨架 使用Grunt加速开发和帮助执行 使用Bower来加入第三方插件和框架——third party plugins/frameworks一、准备工作安装好nodejs和NPM(读者可自己去google)二、安装Yeoman, Grunt and Bower,产生AngularJS的主要骨架2.1 新建一个目录,并进入该目录,执行npm install -g yo g
2014/5/30 Comments:
分享nodejs Express框架中处理404页面一个方式
在用 Express 的时候,路由是我最困惑的事之一。知道用 app.get('*') 可以处理所有页面,但这样除了自定义的其他路由外,静态文件是被忽略的。最近在写一个小工具的时候,找到了一个解决方案:代码如下:var express = require('express'),    router = require('./routes');    var app = module.expo在用 Express 的时候,路由是我最困惑的事之一。知道用 app.get('*') 可以处理所有页面,但这样除了自定义的其他路由外,静态文件是被忽略的。最近在写一个小工具的时候,找到了一个解决方案:代码如下:var express = require('express'),    router = require('./routes');    var app = module.exports = express.createServer();// Configurationapp.configure(function () {    // ...    // 别把顺序写反了    app.use(express.static(__dirname + '/public'));     app.use(app.router);});// 其他 router ...// 404app.get('*', function(req, res){    res.render('404.html', {        title: 'No Found'    })});把通配符放于最后处理。这样没有经过路由的所有页面默认由 404.html 来接管。
2014/5/29 Comments:
Web前端构建工具 GruntJS构建Web程序 (1)
有以下作用 合并JS文件 压缩JS文件 单元测试(基于QUnit) 一句话:完全自动化(automation) 以下是它的安装过程。 一、安装node参考nodejs入门 (最新的node会自动安装npm)二、安装grunt命令行工具grunt-cli使用-g全局安装,这样可以在任何一个目录里使用了。命令: npm install -g grun
2014/5/12 Comments:
Node.js安装入门 第一个程序:Hello World
121107530478.png" alt="" > 一、helloworld在Node.js安装目录中新建一个文件hello.js,里面敲一行代码console.log('hello, nodejs.') ;进入命令行控制台,进入到Node.js目录敲node hello.js控制台输出了“hello, nodejs.” 二、web版的helloworld在Node.js安装目录中新建一
2014/5/12 Comments:
RequireJS和SeaJS区别?AMD 和 CMD 的区别有哪些?CommonJS Modules
ings 规范里,在 BEGIN 处,a 和 b 的 factory 还没未执行,在 END 处时,根据条件,只会执行其中一个。可以看出,Wrappings 规范更“懒”,更节省 CPU. 更符合 nodejs 等环境下的使用习惯。AMD 规范只所以采用提前执行,可以参考作者的说明:Standards and proposals for JavaScript Modules and jQuery, 提到了两点
2014/5/9 Comments:
javascript模块化是什么及其优缺点介绍
也许你用过诸如backbone、emberjs、spinejs、batmanjs 等MVC框架。然而CommonJS、AMD、nodejs、RequireJS、SeaJS、curljs等模块化的JavaScript扑面而来。web前端已经演变成大前端,web前端的发展速度之快。 1)我们来看看什么是模块化? 模块化是一
2014/4/15 Comments:
这些,前端用过吗?高级前端开发都学过哪些东西?
CSS不能编程?用Less、Sass、Stylus、甚至直接用 Absurd,框架除了Bootstrap还有很多。JS写多了很麻烦?jQuery。移动开发?Zepto.js。结构不好?找框架,Backbone.js是MVC,AngularJS和Ember.js是MVVM,Twitter还弄了个事件驱动框架Flight。库多了要优化加载?RequireJS。CSS不能编程?用Less、Sass、Stylus、甚至直接用 Absurd,框架除了Bootstrap还有很多。JS写多了很麻烦?jQuery。移动开发?Zepto.js。结构不好?找框架,Backbone.js是MVC,AngularJS和Ember.js是MVVM,Twitter还弄了个事件驱动框架Flight。库多了要优化加载?RequireJS。代码质量成问题?Jasmine、QUnit、Mocha做单元测试。各种浏览器都要测?用Karma。测试通过了部署还有问题?持续集成,用Travis CI。用户行为也要测?用Selenium 。样式测试还有Viff 。觉得JS都够麻烦的?用CoffeeScript。想做动画?Canvas或SVG还有CSS3帮忙,干掉Flash。SVG太难画?用Snap.svg。想开发游戏?用Canvas。自己写FPS太低?用框架,CreateJS.。2D太幼稚?three.js帮你用WebGL开发3D,还不够给力?asm.js让你在浏览器中拥有虚幻3引擎。这一堆东西都要配置部署,麻烦,用Grunt,库太多?用Bower管理,项目开始要创建各种文件文件夹?用Yeoman。开源项目太多了,GitHub.上找,不会?学Git。顺便用Jekyll托管博客,不是吧还有Ruby这玩意...SASS也是Ruby写的,等等Sublime Text是Python写的,要写插件?也学一下。调试太难?用Chrome开发者工具,一堆API和功能。光在电脑浏览器上跑不给力?移动开发HTML5,离开网络就渣了?HTML5离线应用。不如原生应用?用PhoneGap。想调用原生API?开发Firefox OS应用吧。浏览器应用也得会吧,Chrome Firefox都有自己的文档。接着是不是把后端甩了,自己来,装Node.js,所以还得学点服务器知识,想用npm管理node包?linux技巧shell神马的也得学。想前后端通吃?再看看http协议。Web精通了?node-webkit 让你可以写桌面程序了,继续学吧。想学模块化开发?看看CommonJS和AMD规范。理解JS有偏差?看看ECMA-262,等等不知道什么时候第6版就要出了。浏览器各不相同,弄不清该怎么兼容?看看W3C标准,HTML写出来人看的懂,机器读不懂?要SEO,要支持残障人士?看HTML语义化,全会了但IE就是不支持?叫不出名字的浏览器尼玛连JS都不知道是啥?渐进增强。想一次把各种设备全搞定?响应式设计。然后上面这些不过是一些讨巧的小技术。公司做什么业务的?了解一下行业信息。面向大众的产品?交互设计。美工不给力?UI设计。外包和咨询?设计模式、重构方法、算法、数据结构。知道软件工程吗?了解一下敏捷开发,或许还可以试试TDD、ATDD、BDD。看了这么多东西,第一反应是不是求中文文档?学英语去吧。来源:via
2014/2/17 Comments:
前端开发面试题及答案
http://jsperf.com/nexttick-vs-setzerotimeout-vs-settimeout), Dromaeo十、如果今年你打算熟练掌握一项新技术,那会是什么? nodejs,html5,css3,less十一、请谈一下你对网页标准和标准制定机构重要性的理解。 (google)w3c存在的意义就是让浏览器兼容性问题尽量小,首先是他们对浏览器开发者的约束,然后是对开
2013/12/2 Comments:
前端必备的压缩工具 详述r.js的使用方法
与之异曲同工。 Dean Edwards Packer JSMin UglifyJS下边来介绍一下使用r.js压缩整个项目的JavaScript文件准备条件: 请安装nodejs下载地址(v0.8.16之后集成了npm) 本例中使用的r.js版本是:2.1.8 下载地址:r_2.1.8.jsr.js是RequireJS的一部分(optimizer)。它依赖于UglifyJ
2013/8/9 Comments:
浅析Node.js:一个“编码就绪”服务器
引自:http://sd.csdn.net/a/20110617/299900.html导读:Node是一个服务器端JavaScript解释器,它将改变服务器应该如何工作的概念。它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处理数万条同时连接到一个(只有一个)物理机的连接代码。本文探究了Node.js能解决哪些问题,它如何工作,如何运行一个简单应用程序,最后,Node何时是以及何时不是一个好的解决方案。Node旨在解决什么问题?Node公开宣称的目标是旨在提供一种简单的构建可伸缩网络程序的方法。当前的服务器程序有什么问题?我们来做个数学题。在Java和PHP这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 配套内存。在一个拥有8GB RAM的系统上,理论上最大的并引自:http://sd.csdn.net/a/20110617/299900.html导读:Node是一个服务器端JavaScript解释器,它将改变服务器应该如何工作的概念。它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处理数万条同时连接到一个(只有一个)物理机的连接代码。本文探究了Node.js能解决哪些问题,它如何工作,如何运行一个简单应用程序,最后,Node何时是以及何时不是一个好的解决方案。Node旨在解决什么问题?Node公开宣称的目标是“旨在提供一种简单的构建可伸缩网络程序的方法”。当前的服务器程序有什么问题?我们来做个数学题。在Java和PHP这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 配套内存。在一个拥有8GB RAM的系统上,理论上最大的并发连接数量是4,000个用户。随着您的客户端基础的增长,您希望您的web应用程序支持更多用户,这样,您必须添加更多服务器。当然,这会增加业务成本,尤其是服务器成本、运输成本和人工成本。除这些成本上升外,还有一个技术问题:用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。例如,在Java中,静态变量和缓存需要在每个服务器上的JVMs之间共享。这就是整个web应用程序架构中的瓶颈:一个服务器能够处理的并发连接的最大数量。Node解决这个问题的方法是:更改连接连接到服务器的方式。每个连接都创建一个进程,该进程不需要配套内存块,而不是为每个连接生成一个新的OS线程(并向其分配一些配套内存)。Node声称它绝不会死锁,因为它根本不允许使用锁,它不会直接阻塞I/O调用。Node还宣称,运行它的服务器能支持数万个并发连接。事实上,Node通过将整个系统中的瓶颈从最大连接数量更改到单个系统的流量来改变服务器面貌。现在您有了一个能处理数万条并发连接的程序,那么您能通过Node实际构建什么呢?如果您有一个web应用程序需要处理这么多连接,那将是一件很 “恐怖” 的事!那是一种“如果您有这个问题,那么它根本不是问题” 的问题。在回答上面的问题之前,我们先看看Node如何工作以及它被设计的如何运行。Node肯定不是什么没错,Node是一个服务器程序。但是,它肯定不像Apache或Tomcat。那些服务器是独立服务器产品,可以立即安装并部署应用程序。通过这些产品,您可以在一分钟内启动并运行一个服务器。Node肯定不是这种产品。Apache能添加一个PHP模块来允许开发人员创建动态web页,使用Tomcat的程序员能部署JSPs来创建动态web页。Node肯定不是这种类型。在Node的早期阶段(当前是version 0.4.6),它还不是一个“运行就绪”的服务器程序,您还不能安装它,向其中放置文件,拥有一个功能齐全的web服务器。即使是要实现web服务器在安装完成后启动并运行这个基本功能,也还需要做大量工作。Node如何工作Node本身运行V8 JavaScript。等等,服务器上的JavaScript?没错,您没有看错。服务器端JavaScript 是一个相对较新的概念,这个概念是大约两年前在developerWorks上讨论Aptana Jaxer产品时提到的(参见参考资料)。尽管Jaxer一直没有真正流行,但这个理念本身并不是遥不可及的 — 为何不能在服务器上使用客户机上使用的编程语言?什么使 V8?V8 JavaScript引擎是Google用于他们的Chrome浏览器的底层JavaScript引擎。很少有人考虑JavaScript在客户机上实际做了些什么?实际上,JavaScript引擎负责解释并执行代码。使用V8,Google创建了一个以C++编写的超快解释器,该解释器拥有另一个独特特征;您可以下载该引擎并将其嵌入任何 应用程序。它不仅限于在一个浏览器中运行。因此,Node实际上使用Google编写的V8 JavaScript引擎并将其重建为在服务器上使用。太完美了!既然已经有一个不错的解决方案可用,为何还要创建一种新语言呢?Node对什么有好处?到此为止,应该能够回答“Node是什么” 这个问题了,但您可能还不清楚什么时候应该使用它。这是一个需要提出的重要问题,因为Node对有一些东西有好处,但相反,对另一些东西而言,目前Node可能不是一个好的解决方案。您需要小心决定何时使用Node,因为在错误的情况下使用它可能会导致一个多余编码的 LOT。正如您此前所看到的,Node非常适合以下情况:您预计可能有很高的流量,而在响应客户端之前服务器端逻辑和处理所需不一定是巨大的。Node表现出众的典型示例包括:RESTful API      提供RESTful API的web服务接收几个参数,解析它们,组合一个响应,并返回一个响应(通常是较少的文本)给用户。这是适合Node的理想情况,因为您可以构建它来处理数万条连接。它还不需要大量逻辑;它只是从一个数据库查找一些值并组合一个响应。由于响应是少量文本,入站请求时少量文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的API需求。Twitter队列      想像一下像Twitter这样的公司,它必须接收tweets并将其写入一个数据库。实际上,每秒几乎有数千条 tweets 达到,数据库不可能及时处理高峰时段需要的写入数量。Node成为这个问题的解决方案的重要一环。如您所见,Node能处理数万条入站tweets。它能迅速轻松地将它们写入一个内存排队机制(例如 memcached),另一个单独进程可以从那里将它们写入数据库。Node在这里的角色是迅速收集tweet并将这个信息传递给另一个负责写入的进程。想象一下另一种设计 — 一个常规 PHP 服务器自己试图处理对数据库的写入 — 每个tweet将在写入数据库时导致一个短暂的延迟,这是因为数据库调用正在阻塞通道。由于数据库延迟,一台这样设计的机器每秒可能只能处理2000条入站tweets。每秒100万条tweets需要500个服务器。相反,Node能处理每个连接而不会阻塞通道,从而能捕获尽可能多的tweets。一个能处理50,000 条tweets的Node机器只需要20个服务器。映像文件服务器      一个拥有大型分布式网站的公司(比如 Facebook 或 Flickr)可能会决定将所有机器只用于服务映像。Node将是这个问题的一个不错的解决方案,因为该公司能使用它编写一个简单的文件检索器,然后处理数万条连接。Node将查找映像文件,返回文件或一个404错误,然后什么也不用做。这种设置将允许这类分布式网站减少它们服务映像、.js和 .css文件等静态文件所需的服务器数量。它对什么有坏处?当然,在某些情况下,Node并非理想选择。下面是Node不擅长的领域:动态创建的页      目前,Node没有提供一种默认方法来创建动态页。例如,使用JavaServer Pages (JSP) 技术时,可以创建一个在 <% for (int i=0; i<20; i++) { } %> 这样的JSP代码段中包含循环的index.jsp 页。Node不支持这类动态的、HTML驱动的页面。同样,Node不太适合作为Apache和Tomcat这样的网页服务器。因此,如果您想在Node中提供这样一个服务器端解决方案,必须自己编写整个解决方案。PHP程序员不想在每次部署web应用程序时都编写一个针对Apache的PHP转换器,当目前为止,这正是Node要求您做的。关系数据库重型应用程序      Node的目的是快速、异步和非阻塞。数据库并不一定分享这些目标。它们是同步和阻塞的,因为读写时对数据库的调用在结果生成之前将一直阻塞通道。因此,一个每个请求都需要大量数据库调用、大量读取、大量写入的web应用程序非常不适合Node,这是因为关系数据库本身就能抵销Node的众多优势。(新的NoSQL数据库更适合Node,不过那完全是另一个主题了。)结语问题是“什么是Node.js?” 应该已经得到解答。阅读本文之后,您应该能通过几个清晰简洁的句子回答这个问题。如果这样,那么您已经走到了许多编码员和程序员的前面。我和许多人都谈论过Node,但它们对 Node究竟是什么一直很迷惑。可以理解,他们具有的是Apache的思维方式 — 服务器是一个应用程序,将HTML文件放入其中,一切就会正常运转。而Node是目的驱动的。它是一个软件程序,使用JavaScript来允许程序员轻松快速地创建快速、可伸缩的web服务器。Apache是运行就绪的,而ode是编码就绪的。Node完成了它提供高度可伸缩服务器的目标。它并不分配一个 “每个连接一个线程” 模型,而是使用一个 “每个连接一个流程” 模型,只创建每个连接需要的内存。它使用Google的一个非常快速的JavaScript引擎:V8引擎。它使用一个事件驱动设计来保持代码最小且易于阅读。所有这些因素促成了Node的理想目标 — 编写一个高度可伸缩的解决方案变得比较容易。与理解Node是什么同样重要的是,理解它不是什么。Node并不是Apache的一个替代品,后者旨在使PHP web应用程序更容易伸缩。事实确实如此。在Node的这个初始阶段,大量程序员使用它的可能性不大,但在它能发挥作用的场景中,它的表现非常好。将来应该期望从Node得到什么呢?这也许是本文引出的最重要的问题。既然您知道了它现在的作用,您应该会想知道它下一步将做什么。在接下来的一年中,我期待着Node提供与现有的第三方支持库更好地集成。现在,许多第三方程序员已经研发了用于Node的插件,包括添加文件服务器支持和MySQL支持。希望Node开始将它们集成到其核心功能中。最后,我还希望 Node支持某种动态页面模块,这样,您就可以在HTML文件中执行在PHP和JSP(也许是一个NSP,一个Node服务器页)中所做的操作。最后,希望有一天会出现一个 “部署就绪” 的Node服务器,可以下载和安装,只需将您的HTML文件放到其中,就像使用Apache或Tomcat那样。Node现在还处于初始阶段,但它发展得很快,可能不久就会出现在您的视野中。注:本文内容是根据developerWorks作者Mike Abernethy的文章整理而来的,在Michael Abernethy的13年技术生涯中,他与各种不同的技术和客户打交道。他目前是一名自由程序员,擅长Java高可用性和jQuery。他现在专注于富Internet 应用程序,试图同时实现应用程序的复杂性和简单性。他空闲时常常去打高尔夫球,更确切地说,是在灌木丛中寻找他打飞的高尔夫球。
2011/6/17 Comments: