역 자: Alfredcheung
Nginx와 Node.js는 높은 처리량 웹 응용 프로그램의 주제에 자연스럽 게 결합 된다. 그들은 모두는 이벤트 구동 모델에 기반 하 고 전통적인 웹 서버 아파치 등의 c10k 병목 현상을 통해 쉽게 휴식 하도록 설계 되었습니다. 미리 설정 된 구성 높은 동시 수 있지만 여전히 수천 저렴 한 하드웨어에 초 당 요청 수 보다는 더 하 고 싶은 경우에 할 일이 있다.
이 문서에서는 독자 node.js 업스트림 서버에 대 한 역방향 프록시 역할 Nginx의 httpproxymodule을 사용 하는 가정 합니다. Node.js 응용 프로그램으로 우분투 10.04 시스템 Sysctl, 튜닝 및 Nginx 튜닝을 소개 합니다. 물론, 데비안 시스템을 사용 하는 경우 같은 목표를 달성할 수 있습니다 하지만 튜닝 하는 방법은 다르다.
네트워크 튜닝
만약 우리가 nginx와 node.js를 기본 전송 메커니즘을 이해 하지 먼저 특정 최적화를 확인, 쓸데 두를 세밀 하 게 조정할 수 있습니다. 일반적으로, Nginx는 TCP 소켓을 통해 업스트림 응용 프로그램 클라이언트를 연결합니다.
우리의 시스템에 많은 임계값 및 커널 매개 변수에 의해 설정 되는 TCP에 대 한 제한이 있습니다. 이러한 매개 변수에 대 한 기본값은 종종 일반적인 목적을 위해 설정 하 고 높은 트래픽, 웹 서버에 필요한 짧은 인생 요구 사항을 충족 하지 않는.
여기에 후보로 TCP 튜닝에 대 한 매개 변수 중 일부입니다. 적용 그들을 위해 a/etc/sysctl.conf 파일에 넣어 또는 새 프로필, 그런 as/etc/sysctl.d/99-tuning.conf에에서 넣어 고 sysctl-p를 실행를 커널 로드 하 게 됩니다. Sysctl-요리 책이 실제 일을 사용 합니다.
여기에 나열 된 값을 사용 하려면 안전는 하지만 부하, 하드웨어, 및 사용에 따라 적절 한 값을 선택 하려면 각 매개 변수의 의미를 봐 하는 것이 좋습니다.
Net.ipv4.ip_local_port_range= ' 1024 65000 '
Net.ipv4.tcp_tw_reuse= '1'
net.ipv4.tcp_fin_timeout= '15'
net.core.netdev_max_backlog= '4096'
net.core.rmem_max= '16777216'
net.core.somaxconn= '4096'
net.core.wmem_max= '16777216'
net.ipv4.tcp_max_syn_backlog= '20480'
net.ipv4.tcp_max_tw_buckets= '400000'
Net.ipv4.tcp_no_metrics_save= '1'
net.ipv4.tcp_rmem= ' 4096 87380 16777216 '
Net.ipv4.tcp_syn_retries= '2'
Net.ipv4.tcp_synack_retries= '2'
net.ipv4.tcp_wmem= ' 4096 65536 16777216 '
vm.min_free_kbytes= '65536'
이러한 중요 한 몇 가지 강조 표시 합니다.
Net.ipv4.ip_local_port_range
다운스트림 클라이언트 업스트림 응용 프로그램에 대 한 봉사, Nginx 두 개의 TCP 연결, 하나의 연결 클라이언트, 하나의 연결 응용 프로그램을 열어야 합니다. 서버는 많은 연결을 받으면, 시스템의 사용 가능한 포트 고갈 신속 하 게 됩니다. Net.ipv4.ip_local_port_range 매개 변수를 수정 하 여 사용할 수 있는 포트 범위를 변경할 수 있습니다. 오류에 / var/로그/로그를 발견 하 고 경우: "가능한 SYN 홍수 포트 80에서." 보내는 쿠키 "시스템 사용 가능한 포트를 찾을 수 없습니다 것을 의미 합니다. Net.ipv4.ip_local_port_range 매개 변수를 늘리면이 오류를 줄일 수 있습니다.
Net.ipv4.tcp_tw_reuse
서버는 많은 수의 TCP 연결 간에 전환 하는 경우 많은 수의 연결이 TIME_WAIT 상태에 생성 합니다. Time_wait 자체 연결이 닫힌 리소스 해제 되지 의미 합니다. 연결을 새 연결을 다시 설정 하는 것 보다 훨씬 싸게 가능한 안전 하 게 재활용 하는 커널입니다는 Net_ipv4_tcp_tw_reuse를 1로 설정.
Net.ipv4.tcp_fin_timeout
TIME_WAIT 상태에 있는 연결을 재활용 하기 전에 기다려야 하는 최소 시간입니다. 그것은 재활용 가속화할 수 있다.
연결 상태를 확인 하는 방법
Netstat를 사용 하 여:
Netstat-탄 | awk '{print $}' | 정렬 | 고유-c
또는 SS를 사용 하 여:
Ss-s
NginX
웹 서버의 부하 증가, 우리 nginx의 이상한 몇 가지 제한 사항이 발생 하기 시작. 연결이 삭제 되 고 커널 SYN 홍수를 보고 계속. 이 시점에서, 평균 부하와 CPU 사용량은 매우 작은, 서버는 명확 하 게 더 많은 연결의 상태를 처리할 수, 절망적 이다.
조사 후, 그것은 많은 연결이 TIME_WAIT 상태에 있는 것으로 밝혀졌다. 이 서버 중 하나에의 출력은:
Ss-s
총: 388 (커널 541)
TCP: 47461 (estab 311, 닫힌된 47135, 고아 4, synrecv 0, timewait 47135 / 0), 포트 33938
전송 총 IP ipv6
* & N bsp; 541-& NBSP
원시 & NBS P; 0 0 0 & nbsp
UDP & nbsp; 13 10 3 & NBSP
TCP & NBSP ; 326 325 1 & NBSP
네트 339 & N Bsp; 335 4 & NBSP
Frag 0 0 0
47,135 time_wait 연결! 그리고, SS에서 볼 수 있습니다, 그들은 모두 닫힌된 연결. 즉, 서버는 사용 가능한 포트의 대부분을 소모 했다 그리고 그것은 또한 서버 각 연결에 대 한 새로운 포트를 할당은 의미. 이 질문에 네트워크 튜닝문제는 약간의 도움, 하지만 포트 여전히 충분 하지 않습니다.
후 연구를 계속, 내가 읽는 업링크 연결 keepalive 지시문에 문서를 발견:
작업자 프로세스의 캐시에 보관 된 업스트림 서버에 유휴 활성 연결의 최대 수를 설정 합니다.
Interesting。 이론에서는,이 설정은 캐시 된 연결을 통해 요청을 전달 하 여 연결의 낭비를 최소화 하기 위해입니다. 문서는 또한 우리가 "1.1" proxy_http_version를 설정 하 고 "연결" 머리를 맑게 한다 언급 한다. 더 연구 후 http/1.1 HTTP1.0에 비해 크게 TCP 연결 사용률을 최적화 하 고 기본적으로 Nginx http/1.0은 하기 때문에 이것이 좋은 아이디어 것이 나타났습니다.
문서에서 권장 하는 대로 우리의 업링크 구성 파일은이:
업스트림 Backend_nodejs 없음
서버 nodejs-3:5016 max_fails 0 fail_timeout = = 초;
서버 nodejs-4:5016 max_fails 0 fail_timeout = = 초;
서버 nodejs-5:5016 max_fails 0 fail_timeout = = 초;
서버 nodejs-6:5016 max_fails 0 fail_timeout = = 초;
KeepAlive 512;
}
나는 또한 권장 서버 섹션에서 프록시 설정 변경. 같은 시간에 P Roxy_next_upstream 오류가 발생 한 서버 클라이언트의 keepalive_timeout, 조정 건너뛰고 닫습니다 액세스 로그에 추가 됩니다. 구성 됩니다이:
서버 {server_name fast.gosquared.com 들어
client_max_body_size 16 M;
Keepalive_timeout 10; < br > 위치 / {
Proxy_next_upstream 오류 시간 초과 http_500 http_502 http_503 http_504;
Proxy_set_header Co Nnection "";
Proxy_http_version 1.1;
Proxy_pass Http://backend_nodejs;
}
Error_log/dev/null 크리; Access_log}
새 구성 서버에서 사용 하는 소켓 90%로 감소 했다 발견. 이제 훨씬 적은 연결 전송 요청 수 있습니다. 새 출력은 다음과 같습니다:
Ss-s
총: 558 (커널 604)
tcp:4675 (estab 485, 닫힌된 4183, 고아, 0 synrecv 0, timewait 4183/0), 포트 2768
총 IP IPv6 전송
* 604-
원시 0 0 0
UDP 13 10 3
TCP 492 491 1
네트 505 501 4
이벤트 기반 디자인, 많은 수의 연결 및 i/o,node.js 풀고 비동기적으로 요청을 처리할 수 있습니다. 튜닝의 다른 방법이 있다, 하지만이 기사는 node.js 프로세스에 집중할 것 이다.
노드 단일 스레드 이며 자동으로 멀티 코어를 사용 하지 않습니다. 즉, 응용 프로그램 서버 전체 기능을 자동으로 취득 하지 않습니다.
클러스터링 노드 프로세스 구현
우리 여러 스레드를 포크 하 고 다중 코어에 걸쳐 부하를 가능 하 게 동일한 포트에서 데이터를 수신 응용 프로그램을 수정할 수 있습니다. 노드에이 목표를 달성 하는 데 필요한 모든 도구를 제공 하는 클러스터 모듈 하지만 응용 프로그램에 추가 하려면 실제 일을 많이 걸립니다. 익스프레스,이 베이, 사용 하는 경우에 사용할 수 있는 Cluster2 라는 모듈입니다.
컨텍스트 전환 방지
여러 프로세스를 실행할 때 각 CPU 코어는 한 번에 프로세스 하나만으로 바쁜 확인 해야 합니다. 일반적으로 CPU의 코어가 n 경우 우리 N-1 응용 프로그램 프로세스를 생성 해야 합니다. 이렇게 하면 각 프로세스는 적절 한 시간 슬라이스, 잔여 하는 동안 하나는 다른 작업을 실행 하려면 커널 스케줄러에 남아 있습니다. 또한 그 서버는 기본적으로 수행 되지 CPU 충돌이 발생을 방지 하기 위해 node.js 작업 보다 다른 되도록 하겠습니다.
우리는 실수 두 node.js 응용 프로그램 서버에 배포 하 여 그리고 각 응용 프로그램은 N-1 과정. 결과적으로, 그들은 서로 다른 CPU를 로드할 시스템 날치기. 우리의 서버는 8 코어 시스템, 우리 여전히 컨텍스트 스위칭으로 인 한 성능 오버 헤드의 명확한 감각을가지고. 컨텍스트 전환 하는 것은 다른 작업을 수행 하려면 현재 작업을 중단 하는 CPU의 현상 이다. 때, 커널 고 해야 합니다 현재 프로세스의 모든 상태를 일시 중단 하 고 로드 다른 프로세스를 실행. 이 문제를 해결 하려면 우리의 수를 감소 프로세스 각 응용 프로그램에 대 한 오픈 상당히, CPU를 공유할 수 있도록 감소 시스템 부하에 결과:
부하 감소
시스템 부하 (파란 선) CPU 코어 (레드 라인)의 수에서 떨어지면 어떻게 볼 수 위의 그림 note 다른 서버에 우리는 똑같은 참조 하십시오. 때문에 전반적인 작업 그대로, 위의 그림에서 성능 향상 인할 수 있다만 컨텍스트 전환에서 감소.