새로운 장고 프로젝트

공부해야지…

머신러닝 스터디도 끝났고 애매한 시기…

퇴사 후 python 공부겸 이직 준비겸 fascrap이라는 프로젝트를 할 예정

대략 말하자면, 일정 주기마다 facebook API에서 글을 스크랩하여

유저 간의 필요한 데이터만 수집하여 대시보드를 다시 만들어주는 서비스이다.

지난 1년간 전 회사에서 node, php를 썼는데…

node 창시자도 node는 노답이라고 도망친 마당에 굳이 더 해야할 필요도 못느끼겠고
Farewell node.js(블로그 글)

npm의 거지같은 방식과 폐해들(대표적인 kik)
kik left npm(블로그 글)

간단히 말하자면

  • Kik라는 회사에서 npm에 등록된 오픈소스인 kik모듈의 이름을 바꿔달라고 했지만
  • kik의 소유자는 이를 받아드리지 않았고 Kik에서 npm에 중재를 요청하자 Kik 편을 들어줬고
  • npm이 오픈소스에 적합하지 않다고 판단한 kik는 npm에 등록된 자신의 모든 오픈 소스를 삭제
  • kik 모듈에 의존성이 있던 모든 모듈들은 깨져버렸고
  • 결국 npm에서 같은 기능을 하는 모듈을 같은 이름으로 올려서 해결했다.

심지어 js를 조금 공부해본 사람이라면 들어봤을 babel에도 kik이 사용되었고

이처럼 많이 사용하는 대형 모듈들도 박살이 나버렸다.(즉, npm install, update가 되지 않았다!)

중요한건 문제의 코드는 단 17줄이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports = leftpad;

function leftpad (str, len, ch) {
str = String(str);

var i = -1;

if (!ch && ch !== 0) ch = ' ';

len = len - str.length;

while (++i < len) {
str = ch + str;
}

return str;
}

단순히 글자수를 맞추기 위해서 글자 왼쪽에 임의의 글자를 덧대는 함수이다.

즉, leftpad(“123”, 5, 0) === 00123 이란 것이다.

새삼 느낌점은

우린 오픈소스라고 생각하면 되게 대단한 모듈이나 프로젝트를 생각하지만

사실 저렇게 간단한 것도 만들어서 올려두면 누군가는 쓴다는 것이다.

아무튼, 전 회사에서 생겼던 문제가 있었는데(올해 겪었던 어이없던 일…)

node-request모듈(http client)을 사용했었다.

의존성이 있던 hawk 모듈에서 node version 6에서 사용할 수 없는 코드가 있었고

이를 확인하지 못하고 request 모듈에서 hawk 버전을 업데이트를 했고

하루동안 지옥이 펼쳐졌다……

결국 hawk 버전 업데이트했던 커밋을 Revert했다가
Revert 커밋

local에서 hawk을 직접 구현해서 사용하기에 이르렀다.
hawk local implemenation

그래서 전 회사에서 생겼던 문제는…

아직도 끔직한 기억인데

당시에 ^(캐럿)으로 “request”: “^2.8x.0” 이렇게 모듈을 사용하고 있었는데
(정확히 몇버전인지 기억이 안나네….)

  • package.json에서 패키지 버전 관리 설명
    • SemVer
      • npm은 모듈이 따르고 있는 방식
        • 0.1.1 -> Major.Minor.Patch
      • Major 버전은 호환성에 문제가 있는 변경(0.1 -> 1.0)
      • Minor 버전은 호환성에 문제가 없는 변경(0.1 -> 0.2)
      • Patch 버전은 버그 수정(0.1.1 -> 0.1.2)
    • 틸드(~)
      • ~0.0.1 : >=0.0.1 <0.1.0
      • ~0.1.1 : >=0.1.1 <0.2.0
      • ~0.1 : >=0.1.0 <0.2.0
      • ~0 : >=0.0 <1.0
    • 캐럿(^)
      • ^1.0.2 : >=1.0.2 <2.0
      • ^1.0 : >=1.0.0 <2.0
      • ^1 : >=1.0.0 <2.0

너무 생각없이 package를 관리했던 것 같다….

그래서 생겼던 문제는

  • AWS에서 elastic beanstalk을 사용 중인데 이게 오토스케일링(스케일업) 될때마다 npm install을 하는데
  • 회사에서는 node version 6을 사용 중이었고
  • npm에서 캐럿은 해당 모듈의 Minor 버전 중 가장 최근껄로 install/update된다.
    • 즉, 저때 문제는 ^2.82.0 -> 2.85.0 으로 적용됨
  • 하필 저 request 모듈이 node version 6에서 문제가 생겨서 스케일업하는데 에러가 발생하고
  • 당연히 트래픽이 몰려서 스케일업되는건데 스케일업된 서버는 npm install이 되지 않아서 사용되지 못하고
  • 트래픽 과다로 cpu는 100%로 뛰고 접근은 되지도 않고 elastic beanstalk 자체에서 제공해주는 log 또한 볼 수도 없고
  • 결국 직접 접근해서 log를 보니 npm install Fail…
  • request 버전만 일단 Fix해서 캐럿을 제거하고 다시 릴리즈하고 리스타트…
  • 살아나길 기도하는 서버 개발자(나)와 대표님….
  • 꼭 장애는 집에 가면 터지더라

그 외 문제점?

아무튼 위에서 경험한 큰 일도 있고

node 자체도 callback 지옥과 비동기처리 그리고 지옥의 디버깅…

class 개념이 있지만 애초에 스크립트로 쓰는게 대부분이라 디자인패턴 같은 것도 이론화된걸 찾기 어렵고

로그 조차 확실하게 남길 수 없다는 문제도 있다;;
(object를 JSON.stringify로 변환했을때 안되는 경우도 있다는거… = 순환의존 문제)

1년간 써왔지만 적응이 안된다고 해야되나 간단하게는 쓸 수 있지만

로직이 복잡해지면 일단 코드가 더러워지고

특히 비동기 코드가 들어있다하면 callback 지옥으로 코드를 애초에 간결하게 하기 어렵고

안그래도 callback이 많아지면 code depth가 깊어져서 점점 코드 보기 어려운데

접근제한도 없으니 scope 조절하는 걸로 대신하는데

문제는 특정 변수의 scope를 알려면 함수 간의 관계를 어느정도 확인해야된다는 것이다.

그리고 기본적으로 node는 단일 스레드 구조인데

cpu 코어가 2개 이상인 서버에서는 fork해서 최대한 cpu를 활용해야되는데

비동기처리에는 유리하지만 cpu를 많이 써야하는 작업에는 많이 불리해서

만약 cpu를 좀 써야될 이슈라면 골치가 아파지는 문제가 있다.

이 것 외에도 많은 문제가 있는데 적자면 밑도 끝도 없으니 여기까지…

결론?

결국 말하고자 하는건 node를 공부하는건 더 이상 큰 이득이 없다는 것이다.

부수적인 문제가 너무 많고(위에서 언급한 모듈, 스레드 문제 등등)

커뮤니티도 좀 정치가 있어서 node 레포를 fork 떠서 다른 이름으로 독립하고 이런 문제들도 있다.

개발하는데 뭘 이렇게 신경쓸게 많아야 하는지;;

그리고 학생일때는 간단해서 쓰기 편하다고 생각했는데

많이 배워갈수록 “왜 이런건 없지?”, “아 이런 부분은 크리티컬하구나” 같은 언어 레벨의 문제를 겪다보니
(예를 들어 한글 인코딩 처리, console.log의 비동기처리, 멀티프로세싱, 기본적인 디자인패턴, 모듈화 문제 등)

다른거에 눈이 돌아간다.(python, go ㅎㅎ)

머신러닝을 하면서 python을 사용했는데, 일단 python을 좀 더 고급지게 써보고

다음은 go를 파볼 예정이다.

그러니 fascrap 프로젝트를 꼭 성공적으로 완성해야지 ㅎㅎ