'NodeJS'에 해당되는 글 5건

  1. 2013.01.19 OctoberSkyJs 1차 스터디 후기 4
  2. 2012.11.20 [Node.js] For문과 비동기 Callback
  3. 2012.11.20 Node.js or Javascript Global Scope Test
  4. 2012.11.19 Node.js 비동기 이벤트 실행
  5. 2012.11.18 Node.js 실행스택(Execution Stack) 이벤트 처리 과정

OctoberSkyJs 1차 스터디 후기



OctoberSkyJs 1차 스터디 후기





올해 들어 나름 야심 차게 시작하고 전부터 큰 관심 가졌던 Node.JS 스터디 모임인 "OctoberSkyJs 1차 스터디 후기"를 간단히 제 블로그를 통해 남겨봅니다.


오늘은 개인적인 사정으로 인해 당일 발표 중 첫 번째, 두 번째 발표인 "Buffer"와 "C/C++ Addons"는 아쉽게도 들을 수 없었지만(특히 C/C++ Addons는 꼭 듣고 싶었던 발표이기에 더 큰 아쉬움이 남습니다.;;),


차후 "Groups Mail"을 통해 공개될 "발표 자료"를 기대해 봅니다. plz


그럼 후기의 본론인 스터디 얘기를 하자면, 오늘 제가 들은 발표는 총 2개의 발표였으며, 그 중 세 번째 주제였던 @백정상의 "Cluster"와 당일 발표자분의 부재로 인해 그 자리를 대신 메꿔 주셨던(소위 땜빵 발표?) @채수원님"libuv"에 대한 얘기였습니다.


특히 세 번째 발표인 "Cluster"란 주제는 스터디 예습을 전혀 하지 못한 제겐 시작부터 큰 "멘붕"을 느끼게 했고, 기반 지식(OS, 하드웨어, 엔진(V8)) 또한 그리 깊지 않아 발표 내내 최대한 이해하기 위해 노력했던 시간이었던 거 같습니다.(다행히도 다른 분들의 여러 질문이 이해하는 데 도움이 많이 되었답니다.ㅋㅋ) 


스터디 내용 중 생각나는 내용에 대한 주제를 간단히 적어보자면 Cluster란?적용 시 성능 향상은?(약 20 ~ 40%?)Child-Process 와의 관계? 등의 이야기였고 물론 100% 이해하기 힘들고 제겐 어려운 내용이었지만 성능 향상에 대한 새로운 부분을 알게 되어 아주 유익한 시간이었습니다.


또한 "땜방 발표"를 해주셨던 @채수원님의 "Libuv" 또한 Clouster의 내용과 같이 기반 지식이 부족한 현재로선 100% 이해하기 힘든 내용이었지만 역시 의미 있는 시간이었습니다.


그리고 발표하셨던 내용 중 어느 "한 부분"이 제겐 인상 깊게 남아 아랫글로 옮겨 봅니다.


"Node.JS는 JVM과는 달리 OS와 Machine 간에 최적화 레이어가 존재하지 않는다.(뒤에 따라오는 말은 그에 대한 성능과 관련된 말씀이셨는데 정확히 생각나지 않고 이해 또한 잘 되지 않아 이 글에 옮겨 적지 않겠습니다.(괜찮으시다면 댓글로 직접 남겨 주셔도 좋을 듯합니다.^^;;))



그럼 후기의 끝으로 앞으로 남은 "스터디" 현재 모든 맴버들과 같이 잘 마무리 할 수 있기를 빌며...


1차 후기를 마칩니다.!!




[Node.js] For문과 비동기 Callback




"JS 비동기 이벤트 실행 순서"로 인해 첫 번째 예제의 타이머 이벤트 callback은 for 문이 종료된 후 실행된다.


즉, 이벤트 큐에 쌓인(Event Loop 감지 후) 이벤트 callback들의 실행 시점은 for문 에서 선언된 i 변수가 증감 후 9가 되어 루프를 빠져나온 시점인 것이다.





1. Client-Side 코드 예제



for (var i = 0; i < 10; i++){
	
	this.setTimeout(function(){
		
		console.log(i); // 10
		
	}, 10);
}

// 아래 나머지 예제들은 문법 상 차이만 존재하며, 의미는 동일하다.
// 즉, 타이머 이벤트나 전달되는 callback에 즉시 실행 함수를 랩핑하여 클로저를 발생시켜 위 문제를 해결한다.

for (var i = 0; i < 10; i++){
	
	// 타이머 이벤트에 즉시 실행 함수를 랩핑.
	(function(i){
		this.setTimeout(function(){
			
			console.log(i); // 0 ~ 9
			
		}, 10);
	})(i);
}	

for (var i = 0; i < 10; i++){
	
	// 전달되는 타이머 이벤트의 callback에 즉시 실행 함수를 랩핑.
	this.setTimeout((function(i){
		
		return function(){
			console.log(i); // 0 ~ 9
		}
		
	})(i), 10);
}	






2. Server-Side Node.js 코드 예제


- Server-Side Javascript인 Node.js도 위 동작 방식과 동일하다.



for (var i = 0; i < 10; i++){
	
	// setTimeout 타이머와 같이 비동기로 동작한다
	process.nextTick(function(){
		
		console.log(i); // 10
		
	});
}

for (var i = 0; i < 10; i++){
	
	// 타이머 이벤트에 즉시 실행 함수를 랩핑.
	(function(i){
		process.nextTick(function(){
			
			console.log(i); // 0 ~ 9
			
		});
	})(i);
}	

for (var i = 0; i < 10; i++){
	
	global.setTimeout((function(i){
		
		return function(){
			console.log(i); // 0 ~ 9
		}
		
	})(i), 10);
}	




3.결과




Node.js or Javascript Global Scope Test





1. Client-Side Javascript 전역 객체



// 명시적 전역 변수 선언
var global1 = 'global1';

(function(){
	
	// 암묵적 변수 선언(안티패턴)
	global2 = 'global2';
	this.global3 = 'global3'; 
})();


console.log(typeof window.window.global1); // string
console.log(typeof window.window.global2); // string
console.log(typeof window.window.global3); // string

// delete 연산자로 window 객체의 property 삭제
delete window.window.global1;
delete window.window.global2;
delete window.window.global3;

console.log('');

// 명시적으로 선언된 global1 전역 변수는 엄밀히 말해 아래 결과와 같이 delete 연산자로 객체가 소멸되지 않는다.
// 즉, 객체 속성 및 배열의 요소를 제거하는 delete 연산자로 삭제가 되지 않기 때문에 엄밀히 말해 window 객체의 속성으로 볼 수 없다.
console.log(typeof window.window.global1); // string
console.log(typeof window.window.global2); // undefined
console.log(typeof window.window.global3); // undefined



자바스크립트 변수

http://mohwaproject.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8A%A4%EC%BD%94%ED%94%84-%EA%B4%80%EB%A6%AC-1


자바스크립트 함수 유효범위(Scope)란?

http://mohwaproject.tistory.com/entry/%ED%95%A8%EC%88%98%EC%9D%98-%EC%9C%A0%ED%9A%A8%EB%B2%94%EC%9C%84SCOPE%EB%9E%80






2. Server Side Javascript Node.js 전역 객체




2.1 확장 모듈 helloworldExFn.js 코드


module.exports.helloworldExFn = (function(){
	
	var helloworldEx = function(){
		
		this.id = 'mohwa';
		this.name = 'mohwaName';
		
		return this;
	}
	
	// 전역 속성 선언 및 할당
	global.g_createValue1 = 'g_createValue1';
	this['g_createValue2'] = 'g_createValue2';
	
	return helloworldEx;
	
})();



2.2 호출 페이지 코드


// Node 전역 객체의 Console.log 함수 반환
console.log('1. ' + global.console.log);

// Node 전역 객체의 생성자 함수 반환
console.log('2. ' + global.constructor);

// 빈 전역 객체 반환
console.log('3. ' + this);


// Node.js에서는 Client-Side JS와 달리 함수 밖 "this"는 전역 객체인 global을 가리키지 않는다.

// 빈 전역 객체 생성자 함수 반환
console.log('4. ' + this.constructor);


(function(){
	
	// Node 전역 객체의 Console.log 함수 반환(Client-Side JS와 같이 함수 객체 내부에서는 빈 전역 객체가 아닌 Node 전역 객체 "global"을 반환한다.)
	console.log('5. ' + this.console.log);
	
})();


// 확장 모듈 내부에 전역 변수 생성.

// require(객체) 메서드는 외부 리소스로 제공된 확장 모듈을 가져와 반환({} 타입)한다.
// 그리고 제공된 확장 모듈안 helloworldExFn 맴버는 반환되는 객체의 맴버로 정의된다.

var obj = new require('./helloworldEx.js').helloworldExFn();

// new helloworldExFn() 객체의 id 속성 반환
console.log('6. ' + obj.id);
// new helloworldExFn() 객체의 name 속성 반환
console.log('7. ' + obj.name);


var g_createValue1 = 'g_createValue1';

// 명시적 전역 변수는 g_createValue1를 제거한다.
// 하지만 Client-Side JS와 동일하게 명시적 전역변수는 delete 연산자를 통해 제거되지 않는다.
delete g_createValue1;

// 확장 모듈 내부에서 선언된 암묵적 전역 변수인 g_createValue2를 제거한다.
delete g_createValue2;

// 확장 모듈 내부에서 선언된 암묵적 전역 변수인 g_createValue3를 제거한다.
delete g_createValue3;

console.log('8. ' + typeof g_createValue1);
console.log('9. ' + typeof g_createValue2);
console.log('10. ' + typeof global['g_createValue3']);





3. 결과:




이전 포스트에서 "Node.js 아키텍처 방식"에 대해 간단히 설명한 적이 있다. 


즉, "Node 아키텍처 최 상단 레이어"인 "Node Standard LIbrary"를 통해 기존 Client-Side Javascript 문법이 활용 가능하며, 전체 적인 동작 방식(전역객체, 유효범위 등..)또한, 기존 JS와 많은 부분 흡사하다는 것을 알 수 있다.




Node.js 비동기 이벤트 실행





1. Node.js 비동기 실행 테스트


(function(){
	
	var args = arguments;


	// 첫 번째 비동기 요청
	this.setTimeout(function(){
		
		console.log('1 Async Start=' + new Date().getTime());
		
		// 첫 번째 동기 CallBack(다음 비동기 요청을 지연(대기)시킨다.)
		for (var i = 0; i < 10; i++){
			
			console.log('1 Async Time=' + new Date().getTime());
		}
		
	}, 1001);

	// 두 번째 비동기 요청
	this.setTimeout(function(){
		
		console.log('2 Async Start=' + new Date().getTime());
		
		// 두 번째 비동기 CallBack
		setTimeout(function(){
			
			for (var i = 0; i < 10; i++){
				
				console.log('2 Async Time=' + new Date().getTime());
			}
			
		}, 10);		
	}, 1000);
	
	
	// 세 번째 비동기 요청
	this.setTimeout(function(){
		
		console.log('3 Async Start=' + new Date().getTime());
		
		// 세 번째 비동기 CallBack
		setTimeout(function(){
			
			for (var i = 0; i < 10; i++){
				
				console.log('3 Async Time=' + new Date().getTime());
			}	
			
		}, 10);		
	}, 1000);	
	
})();



2. 결과




1. (두, 세)번째 비동기 요청이 "요청 실행 시점"(1초)에 맞게 먼저 실행된다.(1353241683913, 1353241683915)


2. 첫 번째 비동기 요청이 실행된다.(1353241683915)


3. 첫 번째 요청에 대한 동기 CallBack이 실행된다.(Javascript Code Block(1353241683916))


4. "비동기 이벤트 실행 순서"에 따라 첫 번째 CallBack의 "동기식 Javascript Code Block" 실행 완료 (두, 세)번째 CallBack이 동시 진행 됐다.(1353241683925)


5. (두, 세) 번째 CallBack이 동시 실행 후 완료된다.(1353241683925)





Node.js 비동기 처리의 환상

http://seorenn.blogspot.kr/2011/05/nodejs_26.html


Javascript Single Thread

http://mohwaproject.tistory.com/entry/javascript-single-thead


Node.js 실행스택(Execution Stack) 이벤트 처리 과정




1. Node.js 아키텍처 및 프로세스 모델








1. Node.js는 크게 Javascript 언어 레이어(C, C++) 언어 레이어로 나뉜다.


2.   C++로 작성된 구글의 Javascript 엔진인 "V8"과 이벤트 기반 Non-Blocking I/O(비동기 I/O)를 관리하는 "libero(Thread Poll 담당)"와 이벤트 루프를 담당하는 "libev"가 아키텍처 최하단에 위치한다.


3.  그 위에 Socket 및 Http등에 대한 "node bindings" 레이어(노드에서 작성된 API(C++))는 "Node Standard Library"의 인터페이스 역활을 한다.(Node 저장소에 있는 소스 중 src/*.cc 에 포함되어 있고 Node Standard Library 대부분이 래퍼들과 동작하게 된다.)


4. Node Standard Library 레이어는 Node Bindings 레이어에서 제공되는 Node API(C++)시스템상에서 Javascript 문법을 이용해 I/O 프로그래밍을 할 수 있도록 지원하는 Server Side 라이브러리이다.











2. Node.js 웹 서버 구현 코드:



var server = require('http');

var fs = require('fs');
var url = require('url');

var reqUrl = '';

server.createServer(function(req, res){
	
	fs.readFile('./nodeHtml.html', encoding='utf-8', function(err, data){
		
		if (err){
			throw err;
		}
		else{
			
			res.write(data);
			res.end();
		}
	});
	
}).listen(3000);






3. 실행 스택(Execution Stack) 이벤트 처리 과정



1. 노드는 Single Thread를 사용하므로, 실행 스택(Execution Stack)도 하나만 존재한다.(Stack을 통해 Event Loop가 처리된다.)


2. 한번에 하나의 이벤트(Node API에 포함된 각 이벤트)와 관련된 Stack만 추가된다.


즉, Event Loop를 통한 서로 간의 간섭(Dead Lock(리소스 병목현상))은 일어나지 않는다.(한번에 하나의 이벤트만 추가되기 때문에..) 


"실행 스택 " 최하단 에는 Event Loop를 처리하는 ev_loop()가 존재하며, 계속 실행되고 있다가 이벤트 발생하면 감지 후 필요한 Stack을 실행 스택에 추가시킨다.





3.1 "실행스택" 이 추가되는 이벤트를 처리하는 과정



1. 첫 번째 사용자가 웹 서버(Node.js로 구현된..)에 index.html을 요청한다.


2. 이벤트 루프(Event Loop)는 이를 감지 후 요청 소켓을 읽기 위해 "scket_readble Stack"을 추가한다.(현재 Stack: 1개)


3. HTTP 요청을 해석하는 "http_parse Stack"을 추가 하고(현재 Stack: 2개) index.html 파일에 대한 요청이므로 "load('index.html') Stack"을 추가하고(현재 Stack: 3개) index.html 파일 읽기를 요청한다.



4. index.html을 읽어 들이는 I/O를 요청했으므로 그로 인해 추가된 Stack 3개(scket_readble Stack, http_parse Stack, load('index.html') Stack)를 추가한 순서대로 제거해 나간다.(모두 제거되면 실행스택은 이벤트 루프만 돌고 있는 대기 상태에 있게 된다.)



*** 아직까지는 첫 번째 사용자가 요청한 index.html의 응답을 보내기 위해 파일 I/O를 요청만 완료된 상태이며, 응답을 기다리는 중이다.!!!! ***



5. 이 상태(상황)에서 메모리상에 존재하는 두번째 사용자의 index.html 요청이 들어온다.


6. 두 번째 요청 또한, 첫 사용자와 동일한 과정을 거쳐 실행 스택에 해당 Stack(각 이벤트에 대한 Stack 3개)들을 추가 시켜 나간다.


7. "두 번쨰 요청을 처리하는 중!!" 첫 번째 사용자 요청인 index.html 파일을 읽는 I/O 처리가 완료되었다.!!!!



"해당 이벤트가 발생했지만 현재 두 번째 "요청에 대한 Stack이 존재"하므로 바로 처리되지 않고 이벤트를 대기 시킨다.



설명: 

Non-Blocking I/O 방식은 요청 이벤트를 blocking 하지 않는다.

즉, 두 번째 요청에 대한 Stack이 모두 제거(추가된 순서대로...)돼야 이벤트 루프는 다음 이벤트를 처리해 나간다.



8. 대기 중이던 첫 번째 사용자 요청에 대한 응답(로드된 index.html 파일 읽기 이벤트)을 처리하기 위해 "file_loaded() Stack"을 추가(현재 Stack: 1개)해 I/O가 돌려준 index.html 파일을 받는다.


9. 첫 번째 요청에 응답하기 위해 "http_respond Stack"을 추가 후(현재 Stack: 2) 사용자에게 받은 index.html 파일로 응답을 생성해 사용자에게 응답을 보낸다.



10. 응답이 완료됐으며, 그에 따라 첫 번째 사용자의 응답을 위해 추가된 모든 Stack은 모두 순차적(추가된 순서)으로 제거된다.



11. 두 번째 사용자 또한 이 과정을 통해 해당 사용자 응답을 보낸 후 스택에서 제거된다.



단 비동기 방식(이벤트 방식)은 응답에 대한 순서를 보장하지 않는다

즉, 요청은 순차적으로 이루어지나, 그에 대한 응답은 순서를 보장하지 않는다는 뜻이다.








C++  Addon With Node.js

http://rhio.tistory.com/365


Node.js Ebay

http://www.slideshare.net/rheehot/nodejs-review


Node JS 프로그래밍(책)

http://www.yes24.com/24/goods/6271069



prev 1 next