서문: 이 글을 쓴 출처:
1. 얼마 전, 유닛에서 새로운 프로젝트가 시작되었습니다. 서버 측에서 수행해야 할 작업은 그리 많지도 않았고 그다지 번거롭지도 않았습니다. 우리 팀은 JavaScript를 알고 있었기 때문에 리더는 JavaScript를 시도하기로 결정했고 운이 좋게도 며칠 동안 Node를 공부하게 되었고, 치킨 젤리 같은 느낌으로 node.js의 장을 시작했습니다. 요즘 연구 요약.
2. JavaScript 엔지니어가 node.js에 대해 들어본 적이 없다면 뭔가를 놓친 것 같습니다. 모든 우수한 프런트엔드 엔지니어는 백그라운드 처리 프로세스를 이해해야 합니다. 따라서 JavaScript에서 시작할 수 있다면 그렇지 않을 것입니다. 정말 멋진 일이군요.
3. 인터넷의 인기로 인해 JavaScript는 무한히 대중화되었으며, 서버측 JavaScript는 새로운 기술이 아니지만 node.js의 성공으로 인해 우리 눈에 폭발적으로 등장하게 되었습니다. 프론트엔드 엔지니어들은 프론트엔드에서 백엔드로 작성하는 또 다른 희망을 보았습니다. 참고: node.js는 개발자가 JavaScript 언어를 사용하여 서버측 코드를 작성할 수 있는 프레임워크입니다.
4. 올해 8월 한 대기업의 최종(5차) 면접에서 Node.js에 대한 질문을 받았는데, 그에 대한 답변이 상당히 안 좋았습니다. 실패의 원인 중... 그 회사는 제가 대학시절 동경했던 회사였습니다. 지금 그 경험과 과정을 돌이켜보면 아쉽다는 말조차 할 수 없습니다. 정말 최선을 다했습니다. 사실 이 기사는 내 마음의 작은 매듭을 완성하는 것에 관한 것입니다...좋아, 다시 주제에서 벗어나겠습니다.
5. 모든 전재를 환영합니다. 단, 출처를 밝혀주시면 감사하겠습니다.
노드란 무엇인가요?
글을 쓸 때는 최대한 포괄적으로 작성하는 것이 좋기 때문에 인터넷에서 몇 가지 기본 개념을 선별적으로 따왔고, 일부 내용은 내 이해에 맞게 변경해도 괜찮습니다. 이 섹션을 건너뛰려면 선택하세요.
1. Node는 서버사이드 자바스크립트 인터프리터인데 정말 자바스크립트를 잘하는 학생도 Node를 배우면 쉽게 마스터할 수 있다고 생각한다면 착각이다. 깊든 그렇지 않든, 실제로는 얕지 않습니다.
2. Node의 목표는 프로그래머가 확장성이 뛰어난 애플리케이션을 구축하고 물리적 시스템에 대한 수만 개의 동시 연결을 처리할 수 있는 연결 코드를 작성하도록 돕는 것입니다. 높은 동시성과 비동기 I/O를 처리하는 것은 Node가 개발자의 관심을 끄는 이유 중 하나입니다.
3. Node 자체는 Google V8 JavaScript 엔진을 구동하기 때문에 크롬을 보면 알 수 있듯이 속도와 성능이 매우 좋고, Node가 이를 캡슐화하면서 바이너리 데이터 처리 능력도 향상됩니다. 따라서 Node는 단순히 V8을 사용하는 것뿐만 아니라 이를 최적화하여 다양한 환경에서 더욱 강력하게 만들어줍니다. (V8 JavaScript 엔진이 무엇인가요? "Baidu는 알고 있습니다" 부탁드립니다)
4. 타사 확장 및 모듈은 Node.js 사용에 중요한 역할을 합니다. 다음은 npm 다운로드에 대해서도 소개합니다. npm은 모듈 관리 도구입니다. 이를 사용하여 다양한 Node 소프트웨어 패키지(예: express, redis 등)를 설치하고 Node.js용으로 작성한 소프트웨어 패키지를 게시합니다.
노드 설치
여기에서는 window7과 Linux 환경 모두에서 Node를 설치하는 방법에 대해 간략하게 설명하겠습니다. 설치 시 Python 버전에 주의하세요. Python 버전 문제로 인해 설치가 여러 번 실패했습니다. 버전 2.6을 사용하는 것이 좋습니다. Python 버전을 쿼리하려면 다음을 입력하세요. pyhton -v
터미널에서.1. 먼저 Linux에서의 설치를 소개하겠습니다. Node는 Linux 환경에서 설치하고 사용하는 것이 매우 편리합니다. ^_^...저는 Ubuntu11.04를 사용하고 있습니다.
a. 종속 패키지 설치: 50-100kb/s, 각 패키지는 약 1분 안에 다운로드 및 설치 가능
sudo apt-get install g++ curl libssl-dev apache2-utils sudo apt-get install git-core
git clone git://github.com/joyent/node.git cd node ./configure make sudo make install
安装顺利的话到这一步Node就算安装成功了,2M的网络用了共计12分钟。
注:如果不用git下载也可以直接下载源码,不过这样下载安装需要注意Node版本问题。使用git下载安装是最方便的,所以推荐之。
2.在Windows下使用Cygwin安装Node,这个方式不太推荐,因为真的需要较长时间和较好的人品。我的系统是 win7旗舰版
Cygwin是一个在windows平台上运行的unix模拟环境,下载地址:http://cygwin.com/setup.exe。
下载好Cygwin后开始安装,步骤:
a.选择下载的来源 - Install from Internet
b.选择下载安装的根目录
c.选择下载文件所存放的目录
d.选择连接的方式
e.选择下载的网站 - http://mirrors.163.com/cygwin
f.麻烦就麻烦在这步,考验人品的时候到了。需要的下载安装时间不确定,反正需要比较长的时间(超过20分钟),偶尔会出现安装失败的情况。单击一下各个程序包前面的旋转箭头图标选择你想要的版本,选中时会出现了"x"号表示已经选中了该程序包。选择需要下载的程序包:
Devel包:
gcc-g++: C++ compiler
gcc-mingw-g++: Mingw32 support headers and libraries for GCC C++
gcc4-g++: G++ subpackage
git: Fast Version Control System – core files
make: The GNU version of the ‘make' utility
openssl-devel: The OpenSSL development environment
pkg-config: A utility used to retrieve information about installed libraries
zlib-devel: The zlib compression/decompression library (development)
Editor包:vim: Vi IMproved – enhanced vi editor
Python包:把Default切换成install状态即可
Web包:
wget: Utility to retrieve files from the WWW via HTTP and FTP
curl: Multi-protocol file transfer command-line tool
上个截图,以下载zlib-devel为例:
其上几步走完才算把环境搭建完成,可是现在还没有到安装Node,还需要在Cywgin的ASH模式下执行rebaseall,步骤如下:
a. cmd命令行
b. 进入cygwin安装目录下的bin子目录
c. 运行ash进入shell模式
d. ./rebaseall -v
e. 没有错误就关闭命令行窗口
好了,现在到下载安装Node了,启动Cygwin.exe后输入:
$ wget http://nodejs.org/dist/node-v0.4.12.tar.gz
$ tar xf node-v0.4.12.tar.gz
$ cd node-v0.4.12
$ ./configure
$ make
$ make install
3.直接下载node.exe文件
nodejs.org下载较慢所以我在网盘上传了一个,下载地址:http://www.everbox.com/f/VhyL6EiGF5Lm3ZSRx85caFDIA5
听说有不太稳定的问题,不过你假如只是想先在windows下了解Node,个人感觉这个方法比你装个Cygwin好很多。
注:原本不太想写安装Node这段,可是为了这篇文章的全面性还是写了,没想到一写就是那么长一段了...茶几了
“Hello World” - 为什么每次见到这句心情都会小激动,不解...
首先,创建个hello.js的文件,在文件中copy如下代码:
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(1337, "127.0.0.1"); console.log('Server running at http://127.0.0.1:1337/');
代码逻辑:
a. 全局方法require()是用来导入模块的,一般直接把 require() 方法的返回值赋值给一个变量,在 JavaScript 代码中直接使用此变量即可 。require("http") 就是加载系统预置的 http 模块
b. http.createServer 是模块的方法,目的就是创建并返回一个新的web server对象,并且给服务绑定一个回调,用以处理请求。
c. 通过 http.listen() 方法就可以让该 HTTP 服务器在特定端口监听。
d. console.log就不用多说了,了解firebug的都应该知道,Node实现了这个方法。
注: 想了解具体细节请查看文档 cnodejs.org/cman/all.html#http.createServer
接着运行Node服务器,执行hello.js代码,成功启动会看见console.log()中的文本。有图有真相:
npm的下载和使用
除Node本身提供的API外,现在有不少第三方模块可极大的提高开发效率,npm就是Node的软件包管理器,可以用它安装所需软件包并发布自己为nodejs写的软件包。官网地址:npmjs.org
安装只需要在终端写入一行代码:
npm安装node扩展包同样是一行代码:
//例:npm install express
注:如果安装模块的过程中报域名错误的话,请清空缓存 >npm cache clean 或重启计算机即可。
理解Node的模块概念
在Node中,不同的功能组件被划分成不同的模块。应用可以根据自己的需要来选择使用合适的模块。每个模块都会暴露一些公共的方法或属性。模块的使用者直接使用这些方法或属性即可,对于内部的实现细节就可以不用了解。除了Node本身提供的API外,开发人员也可以利用这个机制来将应用拆分成多个模块,以提高代码的可复用性。
1.如何使用模块?
在Node中使用模块是非常方便的,在 JavaScript 代码中可以直接使用全局函数 require() 来加载一个模块。
在刚刚”Hello World"的例子中,require("http") 可以加载系统预置的 http 模块;模块名称以 "./" 开始的,如 require("./myModule.js") 用来加载与当前 JavaScript 文件同一目录下的 myModule.js 模块。
2.自己如何开发模块?
刚刚介绍使用require()导入模块的时候,模块名称以 "./" 开始的这种,就是自己开发的模块文件。需要注意的就是JS文件的系统路径。
代码中封装了模块的内部处理逻辑,一个模块一般都会暴露一些公开的方法或属性给其他的人使用。模块的内部代码需要把这些方法或属性给暴露出来。
3.来一套简单的例子。先创建一个模块文件如myModule.js,就一行代码
console.log('Hi Darren.')
然后创建一个test.js文件,导入这个JS文件,执行node看到结果
现在Node社区中已有不少第三方的模块,希望能有更多人通过学习Node,加入到这个大家庭中,为Node社区来添砖加瓦。先谢谢之,咱们继续。
4.来一个深点的例子。这个例子中将会针对 私有和共有 进行介绍。先创建一个myModule.js,代码如下:
var name = "Darren"; this.location = "Beijing"; this.showLog = function(){ console.log('Hi Darren.') };
代码中出现了三种类型,分别是: 私用属性,共有属性和共有方法,再创建一个test.js,执行Node
结果高亮的地方很清楚的告诉我们,私有方法我们在模块以外是取不到的,所以是undefined。共有属性和共有方法的声明需要在前面加上 this 关键字。
Node能做什么和它的优势
Node核心思想: 1.非阻塞; 2.单线程; 3.事件驱动。
在目前的web应用中,客户端和服务器端之间有些交互可以认为是基于事件的,那么AJAX就是页面及时响应的关键。每次发送一个请求时(不管请求的数据多么小),都会在网络里走一个来回。服务器必须针对这个请求作出响应,通常是开辟一个新的进程。那么越多用户访问这个页面,所发起的请求个数就会越来越多,就会出现内存溢出、逻辑交错带来的冲突、网络瘫痪、系统崩溃这些问题。
Node的目标是提供一种构建可伸缩的网络应用的方案,在hello world例子中,服务器可以同时处理很多客户端连接。
Node和操作系统有一种约定,如果创建了新的链接,操作系统就将通知Node,然后进入休眠。如果有人创建了新的链接,那么它(Node)执行一个回调,每一个链接只占用了非常小的(内存)堆栈开销。
举一个简单的异步调用的例子,把test.js和myMydule.js准备好了,^_^。把以下代码拷贝到test.js中并执行:
var fs = require('fs'); fs.readFile('./myModule.js', function (err, data) { if (err) throw err; console.log('successfully'); }); console.log('async');
所谓的异步,大家应该都能想得到运行时会先打先显示"async",再显示"successfully"。
Node是无阻塞的,新请求到达服务器时,不需要为这个请求单独作什么事情。Node仅仅是在那里等待请求的发生,有请求就处理请求。
Node更擅长处理体积小的请求以及基于事件的I/O。
Node不仅仅是做一个Web服务的框架,它可以做更多,比如它可以做Socket服务,可以做比方说基于文件的,然后基于像一些比方说可以有子进程,然后内部的,它是一个很完整的事件机制,包括一些异步非注射的解决方案,而不仅仅局限在网络一层。同时它可能,即使作为一个Web服务来说,它也提供了更多可以深入这个服务内核、核心的一些功能,比方说Node使用的Http Agent,这块就是它可以更深入这个服务内核来去做一些功能。
Node事件流概念
因为Node 采用的是事件驱动的模式,其中的很多模块都会产生各种不同的事件,可由模块来添加事件处理方法,所有能够产生事件的对象都是事件模块中的 EventEmitter 类的实例。代码是全世界通用的语言,所以我们还是用代码说话:
var events = require("events"); var emitter = new events.EventEmitter(); emitter.on("myEvent", function(msg) { console.log(msg); }); emitter.emit("myEvent", "Hello World.");
简单的分析这段:
1. 使用require()方法添加了events模块并把返回值赋给了一个变量
2. new events.EventEmitter()这句创建了一个事件触发器,也就是所谓的事件模块中的 EventEmitter 类的实例
3. on(event, listener)用来为某个事件 event 添加事件处理方法监听器
4. emit(event, [arg1], [arg2], [...]) 方法用来产生事件。以提供的参数作为监听器函数的参数,顺序执行监听器列表中的每个监听器函数。
EventEmitter 类中的方法都与事件的产生和处理相关:
1. addListener(event, listener) 和 on(event, listener) 这两个方法都是将一个监听器添加到指定事件的监听器数组的末尾
2. once(event, listener) 这个方法为事件为添加一次性的监听器。该监听器在事件第一次触发时执行,过后将被移除
3. removeListener(event, listener) 该方法用来将监听器从指定事件的监听器数组中移除出去
4. emit(event, [arg1], [arg2], [...]) 刚刚提到过了。
在Node中,存在各式各样不同的数据流,Stream(流)是一个由不同对象实现的抽象接口。例如请求HTTP服务器的request是一个流,类似于stdout(标准输出);包括文件系统、HTTP 请求和响应、以及 TCP/UDP 连接等。流可以是可读的,可写的,或者既可读又可写。所有流都是EventEmitter的实例,因此可以产生各种不同的事件。
可读流主要会产生以下事件:
data 当读取到流中的数据时,此事件被触发
end 当流中没有数据可读时,此事件被触发
error 当读取数据出现错误时,此事件被触发
close 当流被关闭时,,此事件被触发,可是并不是所有流都会触发这个事件。(例如,一个连接进入的HTTP request流就不会触发'close'事件。)
还有一种比较特殊的 fd 事件,当在流中接收到一个文件描述符时触发此事件。只有UNIX流支持这个功能,其他类型的流均不会触发此事件。
相关详细文档:http://cnodejs.org/cman/all.html#events_
强大的File System 文件系统模块
Node 中的 fs 模块用来对本地文件系统进行操作。文件的I/O是由标准POSIX函数封装而成。需要使用require('fs')访问这个模块。所有的方法都提供了异步和同步两种方式。
fs 模块中提供的方法可以用来执行基本的文件操作,包括读、写、重命名、创建和删除目录以及获取文件元数据等。每个操作文件的方法都有同步和异步两个版本。
异步操作的版本都会使用一个回调方法作为最后一个参数。当操作完成的时候,该回调方法会被调用。而回调方法的第一个参数总是保留为操作时可能出现的异常。如果操作正确成功,则第一个参数的值是 null 或 undefined 。
同步操作的版本的方法名称则是在对应的异步方法之后加上一个 Sync 作为后缀。比如异步的 rename() 方法的同步版本是 renameSync() 。下面列出来了 fs 模块中的一些常用方法,都只介绍异步操作的版本。
test.js和myModule.js文件准备好了木?把下面这段代码copy到test.js中执行一次
var fs = require('fs'); fs.unlink('./myModule.js', function (err) { if (err) throw err; console.log('successfully deleted myModule.js'); });
오류가 보고되지 않으면 myModule.js가 삭제됩니다. 간단합니다.
이것은 단순한 예일 뿐입니다. 관심이 있으시면 직접 해보고 진실을 실천하십시오. 공간상의 이유로 사례가 많지 않습니다. ^_^
학습 노드 요약:
1. Linux 명령과 셸에 대한 지식이 거의 없는 저는 이 기간 동안 Linux에 대해 많은 것을 배웠습니다. vim은 정말 강력한 편집기이며 마우스를 사용하지 않는 것이 정말 좋습니다. 나에게 매우 중요한 것은 Linux에서의 프로그래밍이 매우 멋지다는 것입니다. 특히 Windows를 사용하는 팀에서는 Linux를 설치하는 것이 더 건강합니다^_^.
2. 성공적인 서버측 JavaScript 프레임워크인 Node와 그 장점 및 사용 방법을 이해하세요. 물론 이것은 시작에 불과합니다.
3. 사실 그런 꿈의 회사에 들어가지 못한 게 조금 아쉽지만, 인생은 우여곡절도 있어야 하는데 이게 바로 나에게 필요한 일이고 기대되는 일이다... 계속해야 합니다. 스스로 조타수가 되어 자신의 방향을 파악하고 과거를 지나가게 하십시오.
여러분에게 전하고 싶은 말:
1. 여기서 몇몇 사람들을 낙담시켜야 합니다. 백그라운드 기술에 대해 잘 모르거나, 서버사이드 언어를 접해본 적도 없고, I/O 지식도 없고, 백그라운드 처리 프로세스에 대한 개념도 없다면...Node는 a가 아닙니다. 진입에 적합한 서버사이드 기술. 왜 이런 말을 하는가:
A. 중국어로 된 예문과 글이 거의 없다는 점이 시스템을 체계적으로 익히기에는 번거로울 것 같아서, 사용하다 보면 늘 미숙한 느낌이 들곤 합니다. 그것에 익숙합니다. 실제로 중국에서는 Node를 사용하는 회사가 많지 않습니다. 물론 해외에는 아직 많은 회사가 있습니다. cnodejs.org에서 사진을 가져왔습니다.
b. 경험이 없는 친구에게는 노드가 실제로 시작하기 쉽지 않습니다. 가장 간단한 "Hello world"에서 볼 수 있습니다(다양한 운영 환경 및 설치 세부 사항을 이해하는 데 약간의 노력이 필요함). 비교를 위한 것인데 다루는 내용이 다르고 학습 비용도 다릅니다. 따라서 서버 측 언어인 PHP와 PHP를 배우고 싶다면 초보자가 서버 측 기술로 시작하는 것은 권장되지 않습니다. Python은 둘 다 좋은 선택입니다. 책에 다양한 예제가 있고 시작하기 쉽고 이해하기 쉽고 설정하기 쉬운 다중 프레임워크...
c. 위 내용은 제 개인적인 선의의 제안입니다. 제 수준이 부족하므로 조언을 부탁드립니다.
2. Node의 작성 표준과 구체적인 기술을 보여주지는 않겠습니다. 제가 직접 Node 코드를 많이 작성하지는 않지만 객체지향 프로그래밍 아이디어는 어디에나 적용 가능합니다.
위 콘텐츠는 편집자가 소개한 nodejs의 예비 경험입니다. 마음에 드셨으면 좋겠습니다.