달력

8

« 2019/8 »

  •  
  •  
  •  
  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

늘은 이것 저것 생각하다가, 예전일이 생각이 났다.


내가 nodeJS 처음으로 사용하기 시작한 것은 2년전 어느 이른 봄으로 기억이 된다.

당시의 나는 쏟아져 나오는 새로운 기술들과 Cloud기반의 서버 기술들을 들여다 보면서, 어떤 것을 공부를 해야할지 수 개월째 맴돌고 있었던 시기로 기억된다. 


하루가 다르게  쏟아져 나오는 새로운 기술들이 눈과 귀를 즐겁게 하였지만

   "무엇을 공부해야할까?" 

   "무엇을 배워야 할까?"

 

대해서 나름 심각하게 고민하고 스스로에게 물어 보는 시간이 많았다.

AI와 머신러닝, ReactJava, Java 8, Lamda, 함수형 프로그래밍,  V8 엔진을 기반으로한 Javascript 기반의 서버 프로그래밍 등등 말이다


이러한 고민의 시작은 사실, 90년대에 서버 클라이언트 프로그래밍을 시작으로 2000년대 초반에는 3 Tier기반의 서버 개발로 할 때는, 모든 서버의 설치와 구성 및 설정을 위해 개발자는 당연하게  사전에 검토와 분석을 기반으로 설계를 하고 개발을 하고 운영까지 하였다. 그리고 당연하게 개발을 위한 소프트웨어 스택과 라이브러리에 대한 기능도 세세하게 검토하고, 버전을 확정한후에 개발을 시작하였다.


하지만, 현재의  AWS와 같은 Cloud 환경과 Spring과 같은 휼륭한 Framework를 사용하거나 완성도가 높은 오픈 소스를 사용하게 되면, 수개월에 걸쳐서 검토하고 기능을 익혔던 과정은 불필요한 작업이 되었다.

내 생각을 덧붙이자면, 누구나 쉽게 개발할 수 있는 환경이 된 것이다. 

이전에 MSDN CD 또는 DVD를 통해서 학습했던 내용들은 인터넷을 이용하면 바로 바로 이용가능한 예제와 설명들을 찾을 수 있다. 


새로운 시대가 도래한 것이다.

그런데, 어떻게 나는 무엇부터 시작을 해야 할지, 알수가 없었다. 몇몇 사람들과 이야기를 나누어 보았는데, 나와 비슷한 고민을 하는 사람들이 있었다. 

알파고의 파도가 지나간지 얼마 되지 않았기에 AI를 공부하고 싶다는 생각이 들었지만, 나는 엔지니어적인 관점에서 접근하고 싶었다. 내가 DB엔진을 만지지않고, DB를 사용하는 것과 마찮가지로 AI와 머신러닝이 어는 정도 성숙된 이후에 공부하고 싶었다. (요즘이 그 때인것 같다.) 


이러 저러한 여러 가지 생각을 하다가, 아무것도 시작을 못하고 있었는데,  

그러다가 내린 나의 생각은 이랬다.  

 

결론은


무엇이 되었던, 일단 한가지씩 시작해 보는 것이다


별다른 고민을 하지 않고, 크지 않은 새로운 과제에 nodeJS 사용해 보기로 하였다

마침 VS Code를 사용하면서, NodeJS와도 궁합이 잘 맞는다는 것을 알았기 때문에, 바로 사용을 할 수 있었던 것 같다. 


꼭 NodeJS 사용해서 원하는 작업을 해야만 하는 것은 아니었다. 

Perl 또는 Python 또는 Groovy 이용해서 Batch 스크립트를 만들어도 되는 간단한 작업 이었기 때문에,
그리고, 새로운 언어를 하나 더 배울 수 있다라는 측면과 호기심에서 시작을 하게 되었다.

아~ 갑자기 생각났다. 그때 AWS에 새로운 가능으로 Lamda가 추가되었는데, 지원하는 언어중에 하나가 바로 NodeJS 였다.   


그때 해야 했던 작업은 배치작업을 만들어야 했는데, RestAPI 정기적으로 호출해서 DB 테이블에 비어 있는

필드를 채워서 테이블을 확인하고 업데이트 하는 것이었다.

NodeJS의 비동기적인 동작에 대해서 잘 알지 못하는 상황이어서, Async와 I/O Non-Blocking에 대해서 작업이 필요한 상황이었다. (지금이라면, 굳이 NodeJS를 사용하지 않습니다. ) 


작업순서는 다음과 같았다.

먼저 AWS S3 에서 로그를 다운로드 받는다. 다운로드 받은 로그를 약간의 분석을 위해서 메모리에 Map형태로 잘 말아서 올린다. 그리고, DB Table 비어 있는 필드를 찾아서 업데이트 하는 작업과 Rest API를 호출해서 DB상의 테이블의 구멍난 부분을 찾아서 채워는 작업이었다.


기본적으로 배치로 돌기 때문에, 시간적으로는 제한을 받지 않기 때문에 기존의 Sync 작업으로 진행해도 되었지만, NodeJS 사용한다라는 것은,  Async 대한 기본적이 고민이 선행될 필요가 있다. (물론, 지금이라면 await async 키워드를 이용하거나, Promise 사용하면 되겠지만...)


비동기 처리는 

내가 원하는 작업 순서에 따라서 로그를 찍지 않는다, 파일을 읽어 올때나, DB에서 쿼리를 실행해 결과를 가져올

때나, 서버로 부터 API 호출하고 Response를 받을때도, 비동기로 찍어주는 로그는 내 예상과 다른 순서와 시점에 로그를 까만 화면에 번쩍이면서 찍고내고  있었다.


사실 비동기 프로그램은 비주얼 베이직에서 이벤트를 받아 처리하거나, 콜백 함수를 이용한 메소드의 실행 측면으로 이해한다면, 이해적인 측면에서 쉬울 수 있지만, 순차에 따른 호출을 하고 싶은 경우에는 중복된 콜백 메소드의 호출을 보게된다.  call-back hell이라고 부르는 그것을 말이다. 


Call-Back Hell을 피하기 위해서 메시지 루프와 같은 형태로 Event를 처리하는 방법을 사용해서 피해보기도 하였으나, 마음에 들지 않는 방식이었다. 


그러다가, 네트워크 작업과 DB 쿼리가 비동기로 호출되는 상황에 대해서 고민을 하면서만들어 솔루션은 

 Task 큐에 넣고, 호출하고, 결과를 비교하는 콜백 함수를 이용하는 방식으로 마무리 하였.

 
그리고, 동기처리가 필요한 작업순서를 지정하기 위한 방식으로 Perl 이용했었다.

순전히 Call-Back을 중첩하여 사용하기 싫어서 사용한 방법이었는데, 나름 메시지 큐를 만들고, 들어오는 결과를 처리하는 방식이어서, 간단하지만 좋은 방식이었다.


만약, 지금이라면 다른 방식으로 해결할 것인데, 공부하는 측면에서는 도움이 많이 되었다.

NodeJS는 장점도 많지만, 단점도 많다, 하지만 장점이 워낙 커서 단점을 가릴 정도로 훌륭하다.



Posted by 행복상자
2018.12.18 23:30

nodeJS와 Express 설치하기 공부하는 것/Node Js2018.12.18 23:30

VS Code는 회사에서도, 집에서도 많이 사용하는 IDE이다.

오늘은 간단하게 테스트할 것이 있어서 띄웠는데, MacOS에는 nodeJS가 설치가 되어 있지 않았다.

간단하게, "nodeJS"를 설치하고, 내친김에 Express를 설치하려고 한다.


NodeJS는 "https://nodejs.org/ko/" 또는 "https://nodejs.org/en/" 에서 다은 받아 설치하면, 된다. 
브로우저가 설치되어 있는 OS에 따라서 다운해서 설치할 바이너리가 달라진다. 



위 화면에 두개의 버전이 있는데, "10.14.2 LTS" 버전을 설치하기로 한다.

윈도우즈와 MacOS 버전 모두 바이너리 버전으로 설치하기 때문에, 다운 받아서 실행하면 바로 설치가 가능하다. (다른 방식으로 cli 명령으로 설치도 가능한데, 오늘은 쉽게 가기로 한다.)


설치가 완료되었으면, 설치 버전을 확인해 본다. nodeJS설치할때 같이 설치되는 패키지 매니져인 npm의 버전과 nodeJS의 버전을 아래과 같이 확인해 본다.

mymac$ npm -v

6.4.1

mymac$ node -v

v10.14.2


이번에는 nodeJS를 이용하여 웹을 개발할때 사용하는 Express 라는 Framework을 설치할 차례다.

Express는 "https://expressjs.com/ko/starter"에 나오는 순서대로 설치하면 된다.


아래와 같이 npm을 이용하여 express 패키지를 설치한다.  만약 설치시 권한문제로 설치가 단되면 sudo 명령을 사용해서 "sudo npm install express"와 같이 실행하면 된다.

mymac$ sudo npm install express

...


mymac$ sudo npm install express-generator -g 

...


자 이제 마지막으로, express를  이용하여 web 프로젝트를 생성해 본다.

아래의 "- e" 옵션은 templet엔진을 "ejs"를 사용하겠다는 옵션이다.

mymac$ express -e showdata

   create : showdata/

   create : showdata/public/

   create : showdata/public/javascripts/

   create : showdata/public/images/

   create : showdata/public/stylesheets/

   create : showdata/public/stylesheets/style.css

   create : showdata/routes/

   create : showdata/routes/index.js

   create : showdata/routes/users.js

   create : showdata/views/

   create : showdata/views/error.ejs

   create : showdata/views/index.ejs

   create : showdata/app.js

   create : showdata/package.json

   create : showdata/bin/

   create : showdata/bin/www


프로젝트가 생성이 되었으면 실행을 해보자.

아래와 같이 "showdata" 디렉토리로 이동해 들어가서, npm을 이용하여 기본 패키지를 설치하고, "npm start" 명령으로 서버를 동작시킨다.

mymac$ cd showdata

mymac$ npm install

mymac$ npm start


기본 포트는 3000번 포트를 사용하므로, 브라우저에서 "http://localhost:3000"을 치면 다음과 같은 화면이 나타나게 된다. 


만약, 실행 포트를 바꾸고 싶다면, "showdata/bin/www" 파일을 열어서 변경하면 된다.


 


  


 

Posted by 행복상자

아주 오래전(약 2년 6개월전)에 글을 쓰기는 했는데, 마무리 짓지 못했던 글인데, 요즘은 await과 async 키워드를 통해서 자연스럽게 사용하고 있어서 필요가 없을 수 있다. 이전에 내부에 Timer와 간단한  Queue를 만들어서  batch 작업을 수행하는데 사용했었다. 


(Async와 Awat 키워드를 사용하거나, Promise를 이용해서 제어하는 것이 아래 방식보다는 훌륭하다.)


Node Js를 이용하여, 개발할 경우에 싱글 쓰레드가 하나의 CPU Core에서도 자연스럽고 부드럽고 너무도 가볍게 동작하는 것을 보고 놀랐었다.

I/O에 대한 Blocking 문제를 자체적으로 처리해주는 똘똘한 녀석이라고, 자랑스러워하였지만, Callback hell이라고 불리우는 지저분해지는 코드는 또다른 문제를 안겨주기도 한다. 


개인적으로는 시각적으로 가독성이 떨어지는 코드는 좋아 하지 않기 때문에, 머신의 성능이 보장해주는 한도에서 가능하면 가독성이 좋고, 이해하기 좋은 코드를 쓰는 것을 좋아한다.

그리고, 리펙토링을 꼭 해서 좀 더 중복을 없애고, 보기 좋은 짜임새 있도록 만들고는 혼자 좋아라 한다.


Node Js의 Callback 함수 호출은 굉장히 개발을 쉽게 해주기도 하지만, 중첩된 콜백과 이벤트 방식으로 인해 사용하기가 쉽지 않다. 오히려 UI가 있는 Visual Basic은 event호출에 의한 callback 함수가 UI 개발에 직관성을 높이고 코드를 분리해 줄수 있지만, 스크립트와 같은 순차적인 작업은 불편하기 짝이 없다.


이때문에 node Js에서는 Sync함수들을 별도로 제작해서 제공하고 있는 것으로 보인다.

(→ node의 file system과 관련된 라이브러리 참고: https://nodejs.org/api/fs.html)


아래는 개인적으로 이러한 환경에서 사용할 수 있는 non-sync 환경에서 Timer를 이용한 간단한 Queue 방식으로 실행할 수 있는 코드이다. 예를 들명 파일에서 라인별 데이터를 읽어 들이고, 이을 Mysql과 같은 DB에 쿼리를 실행하여 데이터를 저장하거나, 반대로 데이터를 읽고 이를 분석하는 기능을 동시에 실행할 경우에 이용할 수 있다. 


var count = 10;
var queue = [];

for(var i = 0; i < 3; i++)
{
    queue.push(i+5);
}

var tid = setInterval(function() {
    if(count == 0){
     if(queue.length > 0){
            console.log("queue: " + queue.length )
          count = queue.shift();
            return;
        }

        clearInterval(tid);
    }

console.log("count " + count--);
}, 1000);


Posted by 행복상자

Azuer와 AWS의 가상화된 인스턴스에서는 잘 동작하던 코드가, 사내 또는 특별한 환경에서 동작하지 않을 때가 있는데, 이경우는 보안 강화를 위해 설정된 방화벽과 Proxy 서버를 통해서 외부로 나가는 Traffic의 통제를 받기 때문일 것이다.


node js의 패키지를 설치를 위해서 사용하는 NPM을 사용할 때도 Proxy의 영향을 받아서 Repository에서 다운받을 패키지 설치가 원활하지 않을 수 있을때 다음과 같이 CLI상에서 명령을 실행하여 해결할 수 있다.


예로 proxy 서버의 주소가 '192.168.10.1' 이고 Port가 8080이라고 할때, 다음과 같이 실행하면 된다.

(이미 npm과  nodejs가 설치 되어있는 환경에서 실행)


   npm config set proxy http://192.168.10.1:8080

   npm config set https-proxy http://192.168.10.1:8080

   npm config set strict-ssl false


가장 마지막에 있는 strict-ssl은 HTTP Strict Transport Security(HSTS)를 사용하여 항상 HTTPS  프로토콜을 사용하도록 강제하기 위한 옵녓인데, 여기서는 False로 설정했다. 




Posted by 행복상자

최근에 AWS와 node.js를 이용하여, 프로젝트를 진행하고 있다.

이전에 Azure룰 개인적으로 이용하곤 했는데, AWS는 실제 개발과 운영의 업무가 나누어져 있어서 나는 누군가가 만들어준 인스턴스를 이용하기만 하였지, 직접 하나 하나 건들일 일이 없었다. 

그런데, 지난 1월 7일에 Amazon 한국 리젼이 오픈을 하게되면서, 나도 개인 계정을 만들어 인스턴스를 생성하고, 몇몇 기능들와 서비스들을 이용해 보고 있다. 

최근에는 S3에 파일을 업로드 하거나, 다운 받는 코드를 AWS Lambda를 이용해서 실행하도록 만들었는데, Lambda는 AWS의 S3로 새로운 파일을 올리거나 받을때, 이벤트에 따라 필요한 코드를 실행할 수 있도록 도와주는 기능인데, 따로 서버를 운영하지 않아도(돈을 아낄수 있어서 좋다.) 된다.


아래는 AWS S3로 mytest.txt라는 파이을 zlib를 이용하여 압축을 한후에, S3로 업로드하는 

코드이다.

var AWS = require('aws-sdk');

AWS.config.loadFromPath('./config.json');


var s3 = new AWS.S3({ region: 'ap-northeast-2' }); 

var fs = require('fs');

var zlib = require('zlib');


var body = fs.createReadStream('C:/mytest.txt').pipe(zlib.createGzip());

var s3obj = new AWS.S3({params: {Bucket: 'seoulbucket9999', Key: 'myKey.zip'}});

s3obj.upload({Body: body}).

  on('httpUploadProgress', function(event) { console.log(event); }).

  send(function(err, data) { console.log(err, data) });


간략하세 설명을 하면  첫줄의 'var AWS = require('aws-sdk');'는 aws-sdk 패키지를 npm을 이용해서 설치한 후에 실행할때 넣어주면 된다. 

명령은 다음과 같다.  (사용을 위해서는 윈도우와 리눅스 또는 맥에 node와 npm 패키지가 이미 설치 되어져 있어야 한다.)

npm install aws-sdk

그리고,  'AWS.config.loadFromPath('./config.json');' 는 S3에 필요한 Access-key와 secret key를 별도의 config파일에 저장해서 가져오는 기능이다. 


마지막으로 아래의 코드는 로컬에 있는 mytest.txt 파일을 zlib를 이용하여 압축해서 S3에 올리는 코드이다. 

var body = fs.createReadStream('C:/mytest.txt').pipe(zlib.createGzip());

var s3obj = new AWS.S3({params: {Bucket: 'seoulbucket9999', Key: 'myKey.zip'}});

s3obj.upload({Body: body}).

  on('httpUploadProgress', function(event) { console.log(event); }).

  send(function(err, data) { console.log(err, data) });


Posted by 행복상자