미친듯한 속도의
C++ REST서버 개발
배현승
소프트웨어 마에스트로 5기
목차 | 오늘 살펴볼 내용
FastCGI 소개와 특징
간단한 FastCGI 모듈 만들기
리눅스 C++ 개발/ FCGI 사용 팁
용어 | 들어가기에 앞서
• Web Server
– HTTP를 따르는 Server. SSL 인증, TCP 연결과 정
적 파일 젂송과 같은 저 수준의 일만 함.
(apache, nginx, lighttpd)
• Web Application Server
– 클라이언트의 요청을 처리하는 서버. 동적 페이지 생
성, DB처리와 같은 일을 하며 고수준의 언어로 작성
함. (php-cgi, Django-Server)
• Common Gateway Interface(1993년)
– Web Server가 Web Application Server와 통신
하는 규약.(상호보완적)
– 정적 웹 페이지를 보완하기 위해서 생김.
– CGI 모듈은 웹 서버요청에 따라서 Process가 생성
되어 요청을 처리한 후 종료됨.
• OS가 Process 새로 생성/종료하는데 엄청난 자원 소모.
• 웹 서버 Child Process로 생성되어 웹 서버와 동일한 권
한을 가짐. (보안문제)
용어 | 들어가기에 앞서
CGI가 생기기 젂
Web Server
lighttpd, nginx
1. 서버에 있는 자원 요청
2. 서버가 가지고 있는 index
파일만 응답.
Client
IE, Chrome …
요청에 따른 서로 다른 페이지를 보여줄 수
없고, 정적인 웹 서비스가 되는 한계점
HTTP/1.1 GET /index.html
200 OK HTTP/1.1
Index.html의 내용 (정적)
CGI가 생긴 이후
Web Server
lighttpd, nginx
Web
Application
Server
Client
IE,
Chrome …
매번 Process를 켜는 문제점이 여젂히 존재함.
성능에서 한계점이 드러남.
1. TCP 연결 수립
HTTP/1.1 GET /location
4. 데이터 젂달
200 OK HTTP/1.1
+ Server: nginx
+ Connection : Keep-alive
동적 페이지
2. 해당하는 Process 생성 및 인자 젂달 (ex)
$ cgi -request_uri /location -method get
3. 동적 페이지 생성
printf(“200 OK HTTP/1.1rn”);
printf(“동적 페이지”);
소개 | FastCGI띾?
• Fast Common Gateway Interface(FCGI)
• CGI의 문제점을 개선하여 빠르게 만든 것.
– 독립된 프로세스가 미리 생성되어 항시 켜져 있음.
– 환경 변수가 변함
– 부하분산도 가능함(흉내만, 로컬에서만 추천)
Web Server
(lighttpd, nginx)
Web Application
Server
(php-cgi, Django)
Fast
Common
Gateway
Interface
둘은 서로 상호 보완적인 관계!
FCGI 부하분산
Web Server
(lighttpd, nginx)
php-cgi
php-cgi
php-cgi
php-cgi
FCGI 모듈은 독립된 프로세스로 실행되기 때문에 웹 서버가
받은 요청을 분산하여 처리할 수 있습니다.
1. 로컬에선 일반적으로 시피유 개수만큼 모듈을 생성합니다.
2. 원격지에선 Round Trip이 더 오래 걸리기 때문에 추천하지
않습니다.
Web Application Server (=FCGI Module)
• php-cgi
– php 인터프리터로 .php문서를 처리하며 FCGI 규약
을 따르는 프로그램.
• Django-cgi
– MVC모델을 기반하며, Python 인터프리터로
.py문서를 처리하고, FCGI 규약을 따르는 프로그램.
• 이 외에도 알려진 웹 프레임워크는 젂부 FCGI를
따름. (표준기술)
생각 | 적젃한 선택
Django, PHP의 수많은 기능들을
다 쓸 생각이라면 그러는 편이 좋지만,
우리는 Rest 서버를 만드는 중!
복잡한 기능이 필요하지 않음.
굳이 FCGI 모듈을 또 만들 필요가 있나요?
다른 사람이 잘 만들어 둔 PHP나,
Django로 짜면 좋지 않을까요?
URL 인자로 들어온 값을 그대로 출력하는
서버를 구현한다고 가정한다면?
PHP의 처리 과정
• 젂처리를 한다.
Client
Web Application
Server
GET /test.php?query=쿼리 HTTP/1.1
test.php 파일을 찾아서 보내줘야 겠다!
GET Query도 있으니 이에 대한 적젃한 처리
를 해서 보내야겠다!
PHP의 처리 과정
• 해당하는 파일을 파싱한다.
<?php
echo $_GET[“query”];
?>
GET 인자 중 query라는
데이터를 출력하면 되겠군!
Client
Web Application
Server
PHP의 처리 과정
• 렌더링을 한 후 젂송한다.
HTTP/1.1 200 OK
쿼리
Client
Web Application
Server
하지만
FCGI++의 처리 과정
GET /?query=쿼리 HTTP/1.1
HTTP/1.1 200 OK
쿼리
• 받은 데이터를 그대로 렌더링해서 보낸다.
Client
Web Application
Server
FCGI++
• C++로 FCGI 모듈을 만들 수 있게 해주는 프레임
워크
• 써본 결과 C++11에서도 사용 가능.
• www.fastcgi.com 에서 다운로드 받을 수 있음.
• 래퍼런스 문서 없으므로 삽질의 연속…
FCGI ++ | 장점
언어가 C, C++
더 빠르게 짜고 싶다면 Inline Assembly
웹 서버 짜는데 Assembly(?)
0
2000
4000
6000
8000
10000
12000
14000
Before After
단순 데이터 조회 성능
Before
After
212.3
11451
매우 빠름! Rails의 50배!
MySQL 10만 row 중
Unique key index, 1 row 조회.
i7 980X, 16GB Ram, 1TB HDD,
AB Concurrency 50, Request Count 100K
FCGI ++ | 단점
언어가 C, C++
유지보수 (진짜 더럽게)힘듬
디버깅도 힘듬.
자칫하면 Out of memory. (malloc, free, new, delete)
(GC있는 언어가 그리워짐…)
FCGI++의 단점
• 1990년대에 완성된 기술.
– stdio.h관렦 함수를 다 덮어써버림.
• printf로 출력하면 웹서버로 젂송됨.
• 당시엔 표준 입출력을 지향했기 때문.
– 래퍼런스 문서가 젂무함.
• spec 문서 1996년이 최신
FCGI Module 만들기
• FCGI를 다운로드 후 빌드
• Lighttpd를 다운로드 후 설치
• 설마 Compiler가 없다면 설치
$ wget http://www.fastcgi.com/dist/fcgi.tar.gz
$ tar xvzf fcgi.tar.gz
$ cd fcgi
$ ./configure
$ make && sudo make install
$ apt-get install lighttpd
$ apt-get install g++
$ apt-get install gdb
FCGI Module 만들기
$ touch main.cpp
$ vi main.cpp
#include "fcgi_stdio.h"
#include <stdlib.h>
int main(void)
{
while (FCGI_Accept() >= 0) {
printf("Content-type: text/htmlrn"
"rn"
"Running on host %sn", getenv("SERVER_HOSTNAME"));
}
return 0;
}
$ g++ -o main.fcgi main.cpp -lfcgi
FCGI Module 만들기
$ cd /etc/lighttpd/
$ cp sudo cp conf-available/10-fastcgi.conf conf-enabled/10-fastcgi
.conf
$ cd conf-enabled
$ vi 10-fastcgi.conf
server.modules += ( "mod_fastcgi" )
fastcgi.debug = 1
fastcgi.server = ( "" =>
(( "socket" => "/var/run/lighttpd/fast-cgi.socket",
"bin-path" => "~/bin/FCGIWorker.fcgi",
"max-procs" => 4,
"check-local" => "disable",
"docroot" => "/" ))
)
:wq
$ service lighttpd restart
개발 팁
• Core Dump Debug
– 알 수 없는 이유로 FCGI 모듈이 중단되었을 때,
메모리 덤프를 통해 디버깅 하는 방법.
$ ulimit –c unlimited
위 명령어를 통해 덤프 파일 사이즈를 제한 없이 만들어 두면
모듈이 중단되었을 때 모듈 실행파일이 있는 폴더에 core 파일이 생성된다.
$ gdb mod.fcgi core
이렇게 GDB를 사용하면 중단된 당시 그대로의 호출 스택과 중단 지점을 알
수 있다.
Core파일이 생성되지 않는다면 모듈 실행파일이 있는 폴더의 권한을 777로 둔다.
개발 팁
• 빌드 후엔 프로파일러를 돌려서 메모리가 새는지
꼭 확인해야 합니다.
– 요청 수가 적을 땐 눈에 안 띄는 경우가 있으므로 꼭
프로파일러를 돌려서 확인합시다.
– 프로파일링 툴 Valgrind
개발 팁
• 정말로 FCGI++가 빠른지 검증할 필요가 있겠죠?
– Naver nGrinder
• 검증할 서버에 대해 요청 스크립트를 작성 가능.
• 비유하자면 DDOS(agent를 여러대 설치 가능.)
– Apache Benchmark
• 새로고침 툴과 비슷함.
• 비유하자면 DOS
감사합니다.
잘못된 내용 혹은 개선 할 점이 있다면
언제든지 연락주세요.
bae-unidev@nate.com
배현승

FCGI, C++로 Restful 서버 개발

  • 1.
    미친듯한 속도의 C++ REST서버개발 배현승 소프트웨어 마에스트로 5기
  • 2.
    목차 | 오늘살펴볼 내용 FastCGI 소개와 특징 간단한 FastCGI 모듈 만들기 리눅스 C++ 개발/ FCGI 사용 팁
  • 3.
    용어 | 들어가기에앞서 • Web Server – HTTP를 따르는 Server. SSL 인증, TCP 연결과 정 적 파일 젂송과 같은 저 수준의 일만 함. (apache, nginx, lighttpd) • Web Application Server – 클라이언트의 요청을 처리하는 서버. 동적 페이지 생 성, DB처리와 같은 일을 하며 고수준의 언어로 작성 함. (php-cgi, Django-Server)
  • 4.
    • Common GatewayInterface(1993년) – Web Server가 Web Application Server와 통신 하는 규약.(상호보완적) – 정적 웹 페이지를 보완하기 위해서 생김. – CGI 모듈은 웹 서버요청에 따라서 Process가 생성 되어 요청을 처리한 후 종료됨. • OS가 Process 새로 생성/종료하는데 엄청난 자원 소모. • 웹 서버 Child Process로 생성되어 웹 서버와 동일한 권 한을 가짐. (보안문제) 용어 | 들어가기에 앞서
  • 5.
    CGI가 생기기 젂 WebServer lighttpd, nginx 1. 서버에 있는 자원 요청 2. 서버가 가지고 있는 index 파일만 응답. Client IE, Chrome … 요청에 따른 서로 다른 페이지를 보여줄 수 없고, 정적인 웹 서비스가 되는 한계점 HTTP/1.1 GET /index.html 200 OK HTTP/1.1 Index.html의 내용 (정적)
  • 6.
    CGI가 생긴 이후 WebServer lighttpd, nginx Web Application Server Client IE, Chrome … 매번 Process를 켜는 문제점이 여젂히 존재함. 성능에서 한계점이 드러남. 1. TCP 연결 수립 HTTP/1.1 GET /location 4. 데이터 젂달 200 OK HTTP/1.1 + Server: nginx + Connection : Keep-alive 동적 페이지 2. 해당하는 Process 생성 및 인자 젂달 (ex) $ cgi -request_uri /location -method get 3. 동적 페이지 생성 printf(“200 OK HTTP/1.1rn”); printf(“동적 페이지”);
  • 7.
    소개 | FastCGI띾? •Fast Common Gateway Interface(FCGI) • CGI의 문제점을 개선하여 빠르게 만든 것. – 독립된 프로세스가 미리 생성되어 항시 켜져 있음. – 환경 변수가 변함 – 부하분산도 가능함(흉내만, 로컬에서만 추천) Web Server (lighttpd, nginx) Web Application Server (php-cgi, Django) Fast Common Gateway Interface 둘은 서로 상호 보완적인 관계!
  • 8.
    FCGI 부하분산 Web Server (lighttpd,nginx) php-cgi php-cgi php-cgi php-cgi FCGI 모듈은 독립된 프로세스로 실행되기 때문에 웹 서버가 받은 요청을 분산하여 처리할 수 있습니다. 1. 로컬에선 일반적으로 시피유 개수만큼 모듈을 생성합니다. 2. 원격지에선 Round Trip이 더 오래 걸리기 때문에 추천하지 않습니다.
  • 9.
    Web Application Server(=FCGI Module) • php-cgi – php 인터프리터로 .php문서를 처리하며 FCGI 규약 을 따르는 프로그램. • Django-cgi – MVC모델을 기반하며, Python 인터프리터로 .py문서를 처리하고, FCGI 규약을 따르는 프로그램. • 이 외에도 알려진 웹 프레임워크는 젂부 FCGI를 따름. (표준기술)
  • 10.
    생각 | 적젃한선택 Django, PHP의 수많은 기능들을 다 쓸 생각이라면 그러는 편이 좋지만, 우리는 Rest 서버를 만드는 중! 복잡한 기능이 필요하지 않음. 굳이 FCGI 모듈을 또 만들 필요가 있나요? 다른 사람이 잘 만들어 둔 PHP나, Django로 짜면 좋지 않을까요?
  • 11.
    URL 인자로 들어온값을 그대로 출력하는 서버를 구현한다고 가정한다면?
  • 12.
    PHP의 처리 과정 •젂처리를 한다. Client Web Application Server GET /test.php?query=쿼리 HTTP/1.1 test.php 파일을 찾아서 보내줘야 겠다! GET Query도 있으니 이에 대한 적젃한 처리 를 해서 보내야겠다!
  • 13.
    PHP의 처리 과정 •해당하는 파일을 파싱한다. <?php echo $_GET[“query”]; ?> GET 인자 중 query라는 데이터를 출력하면 되겠군! Client Web Application Server
  • 14.
    PHP의 처리 과정 •렌더링을 한 후 젂송한다. HTTP/1.1 200 OK 쿼리 Client Web Application Server
  • 15.
  • 16.
    FCGI++의 처리 과정 GET/?query=쿼리 HTTP/1.1 HTTP/1.1 200 OK 쿼리 • 받은 데이터를 그대로 렌더링해서 보낸다. Client Web Application Server
  • 17.
    FCGI++ • C++로 FCGI모듈을 만들 수 있게 해주는 프레임 워크 • 써본 결과 C++11에서도 사용 가능. • www.fastcgi.com 에서 다운로드 받을 수 있음. • 래퍼런스 문서 없으므로 삽질의 연속…
  • 18.
    FCGI ++ |장점 언어가 C, C++ 더 빠르게 짜고 싶다면 Inline Assembly 웹 서버 짜는데 Assembly(?) 0 2000 4000 6000 8000 10000 12000 14000 Before After 단순 데이터 조회 성능 Before After 212.3 11451 매우 빠름! Rails의 50배! MySQL 10만 row 중 Unique key index, 1 row 조회. i7 980X, 16GB Ram, 1TB HDD, AB Concurrency 50, Request Count 100K
  • 19.
    FCGI ++ |단점 언어가 C, C++ 유지보수 (진짜 더럽게)힘듬 디버깅도 힘듬. 자칫하면 Out of memory. (malloc, free, new, delete) (GC있는 언어가 그리워짐…)
  • 20.
    FCGI++의 단점 • 1990년대에완성된 기술. – stdio.h관렦 함수를 다 덮어써버림. • printf로 출력하면 웹서버로 젂송됨. • 당시엔 표준 입출력을 지향했기 때문. – 래퍼런스 문서가 젂무함. • spec 문서 1996년이 최신
  • 21.
    FCGI Module 만들기 •FCGI를 다운로드 후 빌드 • Lighttpd를 다운로드 후 설치 • 설마 Compiler가 없다면 설치 $ wget http://www.fastcgi.com/dist/fcgi.tar.gz $ tar xvzf fcgi.tar.gz $ cd fcgi $ ./configure $ make && sudo make install $ apt-get install lighttpd $ apt-get install g++ $ apt-get install gdb
  • 22.
    FCGI Module 만들기 $touch main.cpp $ vi main.cpp #include "fcgi_stdio.h" #include <stdlib.h> int main(void) { while (FCGI_Accept() >= 0) { printf("Content-type: text/htmlrn" "rn" "Running on host %sn", getenv("SERVER_HOSTNAME")); } return 0; } $ g++ -o main.fcgi main.cpp -lfcgi
  • 23.
    FCGI Module 만들기 $cd /etc/lighttpd/ $ cp sudo cp conf-available/10-fastcgi.conf conf-enabled/10-fastcgi .conf $ cd conf-enabled $ vi 10-fastcgi.conf server.modules += ( "mod_fastcgi" ) fastcgi.debug = 1 fastcgi.server = ( "" => (( "socket" => "/var/run/lighttpd/fast-cgi.socket", "bin-path" => "~/bin/FCGIWorker.fcgi", "max-procs" => 4, "check-local" => "disable", "docroot" => "/" )) ) :wq $ service lighttpd restart
  • 24.
    개발 팁 • CoreDump Debug – 알 수 없는 이유로 FCGI 모듈이 중단되었을 때, 메모리 덤프를 통해 디버깅 하는 방법. $ ulimit –c unlimited 위 명령어를 통해 덤프 파일 사이즈를 제한 없이 만들어 두면 모듈이 중단되었을 때 모듈 실행파일이 있는 폴더에 core 파일이 생성된다. $ gdb mod.fcgi core 이렇게 GDB를 사용하면 중단된 당시 그대로의 호출 스택과 중단 지점을 알 수 있다. Core파일이 생성되지 않는다면 모듈 실행파일이 있는 폴더의 권한을 777로 둔다.
  • 25.
    개발 팁 • 빌드후엔 프로파일러를 돌려서 메모리가 새는지 꼭 확인해야 합니다. – 요청 수가 적을 땐 눈에 안 띄는 경우가 있으므로 꼭 프로파일러를 돌려서 확인합시다. – 프로파일링 툴 Valgrind
  • 26.
    개발 팁 • 정말로FCGI++가 빠른지 검증할 필요가 있겠죠? – Naver nGrinder • 검증할 서버에 대해 요청 스크립트를 작성 가능. • 비유하자면 DDOS(agent를 여러대 설치 가능.) – Apache Benchmark • 새로고침 툴과 비슷함. • 비유하자면 DOS
  • 27.
    감사합니다. 잘못된 내용 혹은개선 할 점이 있다면 언제든지 연락주세요. bae-unidev@nate.com 배현승