Skip to content

Instantly share code, notes, and snippets.

@shane-shim
Created January 23, 2026 08:41
Show Gist options
  • Select an option

  • Save shane-shim/0ba529e8932f570906d91a8e2a89433e to your computer and use it in GitHub Desktop.

Select an option

Save shane-shim/0ba529e8932f570906d91a8e2a89433e to your computer and use it in GitHub Desktop.
자바스크립트의 역사: Node.js의 탄생과 서버 사이드 JS의 진화 (Ryan Dahl 강연) - 한글 번역

자바스크립트의 역사: Node.js의 탄생과 서버 사이드 JS의 진화

출처: Ryan Dahl (Node.js 창시자) - "History of Node.js" 강연

이 자료는 브라우저 내 스크립트 언어였던 자바스크립트가 V8 엔진의 등장과 비동기 I/O의 필요성을 만남으로써, 2009년 Node.js를 통해 고성능 서버 사이드 언어로 진화해 나가는 과정을 담고 있습니다.


1. 배경: 웹 개발의 한계와 문제 의식 (2005~2008년)

Node.js와 서버 사이드 자바스크립트가 등장하기 전, 웹 개발 환경은 다음과 같은 한계에 직면해 있었습니다.

기존 웹 서버의 구조

과거의 웹 서버(Apache 등)는 단순히 파일을 저장하는 디렉터리 개념이었으며, 클라이언트의 요청이 오면 파일 시스템에서 파일을 찾아 응답하는 방식이었습니다. PHP나 CGI 스크립트가 주로 사용되었습니다.

Ruby on Rails와 동시성 문제 (상세)

2006년경 Rails가 인기를 끌었으나, 라이언 달은 Rails가 매우 느리고 CPU 부하가 심하다는 것을 발견했습니다.

가장 큰 문제 'Lock' (잠금):

  • Rails는 요청(Request)이 들어오면 해당 요청에 대한 응답(Response)이 완료될 때까지 다른 작업을 전혀 수행하지 않는 구조
  • "거대한 잠금(Big lock)"을 걸어두고 모든 운영을 중단한 채 하나의 요청만 처리
  • 한 번에 정확히 하나의 클라이언트만 처리할 수 있었음 (0에 가까운 동시성)

Ruby 언어 자체의 한계:

  • 'Merb'와 같은 프로젝트가 Rails의 속도를 개선하려고 시도했지만 실패
  • Ruby의 스레딩 시스템은 근본적으로 망가져 있었음 (badly broken)
  • 전역 인터프리터 락(Global Interpreter Lock) 때문에 여러 스레드를 생성해도 실제로는 한 번에 하나만 실행 가능

근본적인 깨달음: 아무리 Rails 구조를 개선해도 언어 자체(Ruby, Python 등)가 병렬 실행을 제대로 지원하지 못하기 때문에 I/O 처리에 한계가 있음을 깨달았습니다.

파일 업로드와 진행률 표시(Progress Bar) 문제

당시 가장 큰 기술적 난제 중 하나는 '파일 업로드 진행률'을 사용자에게 보여주는 것이었습니다.

문제:

  • HTTP는 파일 업로드를 위해 설계되지 않았음
  • DOM은 업로드 상태 정보를 제공하지 않았음

초기 해결책 (Ajax Polling):

  • 파일을 업로드하는 동시에, 1초마다 서버에 작은 Ajax 요청을 보내 "얼마나 업로드됐어?"라고 묻는 방식
  • Mongrel(Zed Shaw가 개발한 루비 웹 서버)은 파일 시스템에 쓰이고 있는 파일 크기를 확인하여 알려주는 플러그인을 통해 이를 가능하게 함

롱 폴링 (Long Polling)의 등장:

  • Ajax 요청을 계속 보내는 것은 서버에 부담
  • 클라이언트가 요청을 보내면, 데이터가 변경될 때까지 서버가 응답을 지연시키는 기법 등장

기존 서버의 한계:

  • Rails나 Mongrel 같은 스레드 기반 서버에서 롱 폴링을 하려면 각 연결마다 큰 리소스(스레드 등)를 점유해야 하므로 매우 비효율적

Node.js의 목표: 연결이 열려 있어도 리소스를 거의 먹지 않는, 즉 롱 폴링과 같은 동작에 최적화된 웹 서버를 만드는 것


2. 자바스크립트의 재발견과 기술적 전환점 (2008~2009년 초)

비동기 처리(Non-blocking)에 대한 탐구

라이언 달은 파일 업로드 문제 해결을 위해 여러 언어를 시도했습니다:

  • C: 생산성이 낮음
  • Lua: 기존의 블로킹 방식 라이브러리 문제
  • Haskell: 마찬가지로 한계

V8 엔진의 등장 (2008년 12월)

구글이 크롬 브라우저를 위해 개발한 초고속 자바스크립트 엔진인 V8이 출시되었습니다.

  • 자바스크립트의 성능을 획기적으로 높임
  • 구글, 애플, 마이크로소프트, 모질라 간의 **자바스크립트 속도 경쟁(Arms race)**을 촉발

자바스크립트의 선택 이유 (2009년 1월)

라이언 달은 자바스크립트가 논블로킹 시스템을 구축하기에 완벽한 언어임을 깨달았습니다:

이유 설명
V8 엔진 강력하고 빠른 엔진이 존재
언어적 특성 익명 함수(Anonymous functions)와 클로저(Closures)가 있어 이벤트 기반 프로그래밍에 적합
I/O 라이브러리의 부재 역설적이게도 파일/소켓 표준 I/O가 없어서, 기존의 잘못된(블로킹) 라이브러리와 호환성을 고려할 필요 없이 처음부터 완벽한 논블로킹 I/O를 설계할 수 있는 기회

3. Node.js의 탄생과 초기 발전 (2009년)

개발 시작 (2009년 초)

V8 엔진을 기반으로 파일 시스템, 소켓 등 OS 관련 기능을 추가하여 자바스크립트로 서버를 만들 수 있는 Node.js 개발을 시작했습니다.

JSConf EU 발표 (2009년 11월, 베를린)

Node.js가 처음으로 대중에 공개된 극적인 순간입니다.

발표 직전의 위기:

  • 6개월 동안 Node.js 개발에만 매달려 돈이 다 떨어지고 지쳐 있었음
  • 가지고 간 리눅스 노트북이 프로젝터와 호환되지 않아 영상이 나오지 않음
  • 마지막 순간에 다른 사람의 맥 노트북을 빌려 발표

심리 상태:

  • 매우 겁을 먹었고(scared), 스스로를 "작동하지도 않는 것을 들고 온 괴짜(crackpot)"라고 생각
  • "그냥 이 방을 나가서 기차를 타고 도망가 버릴까?" 진지하게 고민

데모 시연:

  • 400줄짜리 자바스크립트 코드로 만든 IRC(채팅) 서버 데모를 시연

반응:

  • 데모는 훌륭하게 작동
  • 청중들이 열악한 와이파이 환경에서도 각자의 노트북으로 IRC 서버에 접속해 채팅을 시작
  • 자바스크립트만으로 서버가 돌아간다는 사실에 **"Holy shit(이럴 수가)"**이라며 경악
  • 이 발표가 Node.js가 주목받는 결정적 계기

초기 반응

당시 자바스크립트는 '진정한 프로그래밍 언어'로 취급받지 못했으나, 이 발표를 기점으로 서버 사이드 언어로서의 가능성을 인정받기 시작했습니다.


4. 성장과 기업의 도입 (2010년 이후)

Joyent 합류

프로젝트 자금이 떨어진 라이언 달은 Joyent사에 입사하여 Node.js를 풀타임으로 개발하게 됩니다. Joyent는 데이터 센터 소프트웨어 구축 등을 위해 Node.js를 후원했습니다.

핵심 개발팀 구성

  • npm(Node Package Manager)을 만든 아이작(Isaac) 등 5명의 풀타임 개발자가 핵심(Core) 기능을 개발

마이크로소프트의 참여

  • 마이크로소프트가 Node.js의 윈도우(Windows) 포팅을 돕기 위해 인력을 배정
  • Node.js가 리눅스/유닉스를 넘어 윈도우 서버 환경(Azure 등)으로 확장되는 중요한 계기

기업 도입

링크드인(LinkedIn), 야후(Yahoo) 등의 대기업이 Node.js를 도입하기 시작하면서 기술의 신뢰도가 높아졌습니다.


5. 기술적 이슈와 해결 과정

콜백 지옥 (Callback Soup)

  • 비동기 프로그래밍 방식(콜백 함수 중첩)에 대해 초기에는 개발자들의 거부감이 있었음
  • 점차 익숙해지며 더 이상 큰 불만 사항이 아니게 됨

디버깅과 안정성

  • V8에는 이미 훌륭한 디버거, 프로파일러, 힙 스냅샷(Heap snapshot) 기능이 존재
  • 하지만 Node.js 사용자에게 제대로 노출되지 않았음
  • 메모리 누수(Memory leaks)를 찾기 위해 힙 스냅샷 간의 차이(Diff)를 비교하는 기능 등을 개선 목표로 설정

도메인 (Domains)

문제: 예외(Exception)가 발생하면 프로세스 전체가 죽어버려, 연결된 모든 사용자의 접속이 끊김

해결 개념:

  • I/O 작업들을 하나의 그룹(도메인)으로 묶음
  • 하나의 업로드 작업에서 에러가 발생하면, 서버 전체를 죽이는 대신 해당 도메인(그 업로드 작업)만 깔끔하게 종료
  • 다른 사용자에게 영향을 주지 않도록 하는 기술

멀티 프로세스 (child_process.fork())

  • Node.js 0.6 버전부터 child_process.fork()를 통해 새로운 Node 프로세스를 쉽게 띄우고 JSON 메시지를 주고받을 수 있게 됨

비용 문제:

  • 프로세스 하나를 띄우는 데 약 43ms의 시간과 최소 13MB의 메모리 소요
  • 요청 하나당 프로세스를 띄우는 것은 불가능
  • 멀티 코어 CPU를 활용하기 위해 프로세스 몇 개를 띄워두고 수백 개의 연결을 분산 처리(로드 밸런싱)하는 용도

6. npm과 모듈 시스템

Isaac과 npm

  • npm(Node Package Manager)의 창시자인 **아이작(Isaac)**이 Joyent에서 풀타임으로 Node.js 코어 개발을 담당

표준화된 구조

  • 초기에는 프로젝트를 어떻게 구성해야 할지 막막
  • npm을 통해 모듈을 게시(publish)하고 프로젝트를 구성하는 방법이 표준화
  • 개발자들이 편안함을 느끼기 시작

실제 활용

  • Joyent에서도 Express 프레임워크와 자체 모듈들을 사용하여 웹사이트와 데이터 센터 소프트웨어를 구축

7. 관련 기술 및 프레임워크

프레임워크

프레임워크 설명
Ruby on Rails 당시 웹 개발의 표준이었으나 성능 문제의 원인으로 지목
Mongrel 웹 서버를 라이브러리 형태로 개념화한 선구적인 루비 웹 서버
Express Joyent에서도 웹 사이트 구축에 사용한 Node.js 웹 프레임워크

대안 언어들

CoffeeScript:

  • 라이언 달은 구문론적으로 훌륭하다고 평가
  • 하지만 디버깅 시 복잡성을 증가시킨다는 이유로 Node.js 코어에는 도입하지 않음

Dart:

  • 구글이 발표한 새로운 언어
  • 라이언 달은 브라우저 클라이언트 측(Native Client)을 타깃으로 할 것이라 예상

8. Node.js의 미래에 대한 라이언 달의 견해 (당시 시점)

1.0 버전의 필수 조건

  • Windows 지원: 마이크로소프트의 도움으로 거의 완성 단계
  • 디버깅 도구 강화: V8의 프로파일링 도구를 사용자에게 쉽게 노출

생태계의 성장

  • 초기에는 해커들의 장난감 같았으나, 대기업 채택으로 신뢰성 확보
  • 콜백 지옥 문제는 개발자들의 적응으로 자연스럽게 해소

연대기 요약

연도 사건
2005~2006 Ruby on Rails 인기, 동시성 한계 인식
2008.12 구글 V8 엔진 출시, JS 속도 경쟁 시작
2009.01 라이언 달, JS를 서버 사이드 언어로 선택
2009.02~10 Node.js 개발 (6개월간 집중)
2009.11 JSConf EU 베를린에서 Node.js 최초 공개
2010 Joyent 합류, 풀타임 개발 시작
2010~2011 마이크로소프트 참여, Windows 포팅
2011 LinkedIn, Yahoo 등 대기업 도입
2011 Node.js 0.6 - child_process.fork() 추가

핵심 메시지

"브라우저 내의 스크립트 언어였던 자바스크립트가, V8 엔진의 등장과 비동기 I/O의 필요성을 만남으로써, 2009년 Node.js를 통해 고성능 서버 사이드 언어로 진화했다."

라이언 달이 해결하려 했던 문제는 단순했습니다: "파일 업로드 진행률을 어떻게 보여줄 것인가?" 이 하나의 질문이 웹 서버의 동시성 모델에 대한 근본적인 재고를 이끌었고, 결국 자바스크립트를 서버 사이드의 주류 언어로 만들어낸 것입니다.


이 문서는 Ryan Dahl의 "History of Node.js" 강연 내용을 한글로 번역/정리한 것입니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment