[[TableOfContents]] * 강의 노트는 날짜나 요일 별로 구분하지 않고 큰 주제별로 분리할 생각입니다. 그렇게 하는 편이 나중에 찾아보기에 좋을것 같습니다 -[안혁준] * 저의 주관적인 부분이 많이 들어 갈수 있으므로 부족하다 생각되는 부분은 채워주세요. * 강의 노트는 같이 만들어 나가는 것이므로 모두들 함께 채워나갑시다. == HTTP == === HTTP Method === ==== POST ==== * uploder에게 리소스를 올릴때 사용 주로 새글을 쓸때 많이 사용한다. ==== PUT ==== * resource에 사용 그 url에 딱 올라갈 때 쓴다. 주로 수정에 사용된다 이미 ID를 알고 있으므로. == JavaScript란? == === Prototype 기반 언어 === * prototype언어? * oop의 흐름은 class와 prototype으로 나늰다. * prototype은 클래스가 들고 있어야하는 함수들을 특정 인스턴스가 들고 있게 만드는 것이다. * 이 특정 인스턴스를 prototype이라 부른다. === 함수형 언어 === * 함수를 일급객체로 다루는 언어 * 일급객체란? * 변수 안에 담을수 있고, * 파라미터로 전달할수 있으며, * 반환값을 사용할수 있고 * 할당된이름과 관계없이 구분할수 있다 * 함수를 마치 일반적인 인스턴스처럼 다루는 언어 == Javascript 문법 == === 클로져 === * 클로져 : 내부의 있는 외부에 있는 함수의 지역 변수를 쓸수 있는것. 때문에 의도하지 않은 결과를 가져올수 있다. 예시추가바람 === Excuteion Context === * this * p.do() 에서 p가 실행문맥이다. 그러나 이 함수를변수로 받으면 var f = p.do; f(); 이런식으로 그러면 f는 실행문맥이 없기 때문에 전역객체가 실행문맥으로 간주된다. * 결론적으로 함수 앞 마지막 . 앞에 있는 것이 중요하다. * func.apply(ec, arguments) 나 func.call(ec, arg1, arg2, ... )으로 func안에서의 실행문맥(this)를 명시적으로 변경할수 있다. === new의 동작 === * new Person(); * 1. create instance * 2. instance.__proto__ = Person.prototype; * 이때의 __proto__는 프로토타입 체인이라 할수있다.(엔진별로 다를수 있다.) * 3. 실행문맥을 instance로 한 생성자를 호출한다. === prototype === ==== Class vs Prototype ==== * Class : 함수와 맴버 변수가 각각 class와 인스턴스에 나누어 져있는것. * prototype : 함수와 맴버 변수 모두 인스턴스에 저장되있는것 * 단지 함수는 다른 인스턴스에 존재한다. * 그 다른 인스턴스는 prototype이라 부른다. || class || <-----------------> || prototype || || VTable || <-----------------> || prototype chain (__proto__) || ==== dispatch ==== * 실제 호출해야 하는 함수를 찾는 과정 * javascript에서는 실행시간에 프로토타입 체인에 의해 실행한다. * instance의 __proto__에서 찾고 없으면 그위에 __proto__에서 찾고... * 코드로 나타내보면.. {{{ for (var _proto = a; _proto; _proto = _proto.__proto__) { if (("f" in _proto) && typeof _proto["f"] === "function") _proto["f"].apply(a, arguments]); } }}} * 자바스크립트는 함수와 일반 변수와의 구분이 없기때문에 변수 또한 dispatch가 된다. ==== 상속 ==== * 상속을 위해서는 prototype chain에 등록하면 된다. {{{ function People(){}; function Man(){}; Man.prototype = new People(); m = new Man(); }}} === same origin policy === * 자바 스크립트에서는 XSS를 막기(?)위해 동일한 도메인이 아니면 javascript문맥에 접근할수 없다. * iframe이나 XHR요청은 이것의 적용을 받는다. * document.domain 을 조정함으로써 동일한 도메인의 범위를 바꿀수 있다. * wiki.zeropage.org 와 www.zeropage.org 를 동일한 도메인으로 취급하기 위해 document.domain을 zeropage.org로 설정할수 있다. * 단, 이것을 하위 도메인. 앞에서 부터만 짜를수 있으며 붙이는 것은 허용되지 않는다. ==== Same Origin Policy를 극복하기 위한 방법 ==== * proxy * 다른 도메인에 접근하기 위해 동일 도메인 서버에 다른 페이지의 결과를 그대로 읽어와 내려주는 proxy를 설치한다. * 부하가 많이 걸리고(요청마다 서버에 요청을 보내고 그걸 다시 내려주므로 네트워크 비용및 기타 비용이 증가) * 인증 문제가 걸릴경우 보안이 약화될수 있다. * Image * 원래 same origin policy를 적용받지 않음으로 극복할수 있으나 바이너리므로 애시당초 우리가 쓸수 없다. * Ifreame * 내부에서 다른 자바스크립트 코드가 작동할수 있으나 다른 도메인이라면 접근이 불가하다. * 플래쉬로 극복할수 있으나 클라이언트에 부하가 있고 자바스크립트 고유한 방식으로 해결하는것이 아니라서 좋지않다. * Script tag * Same origin policy를 적용받지 않고 자바스크립트를 불러올수 있으나 바로 실행이 되므로 다른 방식을 써야한다. * script tag를 읽어 로딩이 끝나면 바로 실행 하기 때문에 여러개를 동시에 불러올경우 전역변수를 이용한 방식은 불가. * 따라서 callback함수로 해결한다. * 이때 내려줄 응답은 JSON과는 조금 다르다. {{{ __callback({ "json" : "data"}); }}} * 위와 같은 형식으로 내려줄경우 클라이언트(요청한 쪽)에서 _callback함수만 정의해두면 로딩이 끝남과 동시에 불리게 된다. * 이 응답은 마치 JSON에 함수만 감싼형식이기 떄문에 JSON with Padding, JSONP라 부른다. == server == === 종류 === * Apache http server (httpd) * 널리 쓰이고 있는 서버이고 가장 안전성이 뛰어나다. * IIS * windows 에서 쓰이고 역시 안정성이 뛰어나고 GUI관리가 가능하다. * lighttpd * event driven 방식의 서버 * nginx * evnet driven 방식이며 nodejs 때문에 유명해졌다. === 초기의 웹서버 === * static 한 파일을 내려준다. * 확장자를 파악해서 또는 파일의 헤더를 읽어 맞는 MIME TYPE를 헤더에 적어준다. * static 한 파일을 업로드 받는다. === 조금 나은 웹서버 === * 뭔가 다이나믹하게 만들어보자. ==== Unix File ==== * Unix에서 File이라함은 다음을 모두 의미한다. * 우리가 알고 있는 그 파일 (Process - Disk) * 프로세스간 통신에 사용되는 Pipe * 원격 머신에 존재하는 프로세스와 통신하는 Socket * 기계장치와 통신하는 드라이버 * Unix는 C임에도 불구하고 강력한 추상화를 통해 뭔가를 읽고 쓰는 것으로 File을 만들었다. * 마치 다음과 같은 느낌이다. {{{ FILE f = new Pipe(); }}} ==== CGI ==== * Common Gateway Interface * Unix에서는 Pipe도 File이므로 static한 file 대신 Pipe를 쓰면 뭔가 다이나믹한게 되지않을까? * 웹서버는 두고 거기에 다른 프로세스를 실행해서 그 실행 결과를 읽어들이자. * 이때의 규약을 CGI라 부른다. * standard Input에는 request body을 준다. * standard Output에는 response body를 넘긴다. * 그외에 기타 등등의 정보는 환경변수로 넘긴다. * 표준은 RFC3875이며 IETF에서 관리한다. * 매 실행시마다 새로운 프로세스를 생성하기때문에 메모리 소모가 심하고 disk접근이 많다. === 좀 괜찮은 웹 서버 === * 새로운 프로세스를 만드는 비용을 줄여보자. * 공용라이브러리는 프로세스가 실행될때 한번만 불러와진다. * ISAPI(ISS) : DLL이용) * mod (apache : so이용) * 현재 가장 많이 사용되는 방식 * process per request 방식이어서 fork 비용은 여전히 존재하고 요청마다 메모리를 많이 먹는다. * 하지만 모듈을 요청마다 디스크에서 읽지 않기 때문에 조금은 나아졌다. === 많이 괜찮은 웹서버 === * fork비용을 없애자 * 답은 Thread ==== MPM ==== * fork하는 부분을 module로 만들어 여러 방식을 선택할수 있다. * fork 대신 Thread를 쓸수도 있고 운영체제별로 다른 방식을 쓸수도 있고 fork를 그대로 쓸수도 있다. * 기존에 하던 방식은 pre-fork방식 * mpm-worker 방식은 프로세스 대신에 쓰레드를 쓰는 방식이다. * 하나의 프로세스에 여러개의 쓰레드를 만들어 대기하다가 요청이 오면 하나씩 대응하는 방식 * thread per request 방식 * 다만 모듈이 Thread안전해야 한다. * 여전히 CPU 자원을 많이 쓴다. * Servlet도 같은 방식이다. * context switch가 많이 일어나서 효율적이지 않고 평균 응답시간이 길어진다. ==== MPM + Queue ==== * 큐를 만들어서 context switch비용을 줄여보려고 노력했다. * connection을 큐에 쌓아두고 worker가 하나씩 꺼내어 처리 * 기존에도 하고 있는 방식이긴 하나 여전히 context switch는 일어난다. === 정말 미치도록 괜찮은 웹서버 === * 한 커넥션 (=job)을 자세히 살펴보았더니...File I/O DB접근 등등 대기만 하는 시간이 길더라. * 그럼이 I/O부분만 비동기로 처리합시다. * 로직이 최소 단위로 나뉘어지고 시간이 오래 걸리는 작업은 비동기 처리. * 순서는 존재해야하기 때문에 Event-driven의 탄생. * 시간이 오래걸리는 작업은 비동기로 처리해야 하기 때문에 시간이 오래 걸리는 작업은 다른 프로세스로 넘기는것이 낫다. * 그래서 fork의 악몽이 시작되는 줄 알았으나. ==== fast CGI ==== * 그 프로세스를 demon으로 만듭시다! * 이전에는 CGI들도 단독 실행이 가능했다! * fast CGI는 단독실행 대신 deamon(service)로 실행된다. * 한번 실행되어 대기하기 때문에 프로세스를 매 요청마다 다시 디스크에서 불러오지 않아도 된다. * 통신방식은 socket * 따라서 프로세스가 무엇이던 간에 소켓만 만드면 되므로 웹서버의 모듈갯수가 확연히 줄어든다. * 소켓이므로 CGI가 다른 서버에 존재해도 된다. * 로드밸런싱이 편해진다. (CGI가 다른데 있어도 되니까.) * 각 CGI모듈이 따로 따로 있어도 된다. * 이건 엄연히 다른 프로세스이므로 모듈이 쓰레드 안전 하지 않아도 된다! * 현존하는 가장 빠른 방식. event-driven 방식의 웹서버와 event-driven방식의 WAS가 만나면 nginx + nodejs 더이상의자세한설명은생략한다.