아무거나

성능 튜닝(keepalive, epoll) 본문

Infra/Nginx

성능 튜닝(keepalive, epoll)

전봉근 2021. 2. 11. 05:09
반응형

Nginx Keepalive

  • TIME_WAIT 소켓이 쌓이는 근본적인 문제 해결 방법
  • Ngnix와 웹 애플리케이션 서버(Tomcat + Spring Boot) 간의 요청이므로 TCP Handshake를 한다. 하지만 빈번하게 통신이 발생하면 응답시간에 대한 레이턴시가 발생할 수 있다. 즉, 모든 요청에 TCP Handshake가 발생하므로 불필요한 리소스 낭비가 생기므로 keepalive가 필요함
  • keepalive란 한번 맺은 세션을 요청이 끝나더라도 유지해주는 기능 -> 매 요청마다 새로운 세션을 만들지 않고, 지정된 숫자만큼의 세션을 연결한 뒤 그 연결을 통해 요청을 처리
  • 설정적용 [/etc/ngnix/nginx.conf]
          ...
          
          map $http_upgrade $connection_upgrade {
            default "upgrade";
          }
          
          upstream springboot_server {
            server 127.0.0.1:9091;
            keepalive 1024;
          }
          
          ...
          
          server {
            ...
            
            location / {
              proxy_pass  http://springboot_server;
              proxy_http_version  1.1;
              proxy_set_header  Connection  $connection_upgrade;
              proxy_set_header  Upgrade $http_upgrade;
              
              ...
            }
          }
          
          ...
        ```
        - upstream springboot_server
          - springboot_server라는 upstream 설정을 생성 및 지정
        - proxy_???
          - 상기 proxy_??? 값에 keepalive 옵션을 적용하기 위한 내용 추가
        - keepalive 1024
          - keepalive 유지 최대 커넥션 갯수(1024개의 세션으로 계속 재활용)
      - 적용확인
        ```
          // 기존보다 소켓이 현저히 줄어든것을 확인할 수 있다.
          $ while true ; do echo -n "$(date) " ; ss -s | grep timewait ; sleep 1 ; done
        ```
    
  • epoll
    • Nginx의 events에 epoll을 선언
    • epoll 이란
        리눅스에선 모든 것이 파일이기 때문에 네트워크 연결조차 내부적으로 파일입니다.
        모든 프로세스마다 유니크한 File Descriptor가 있습니다.
        이 File Descriptor는 어느 것이 읽거나 쓸 준비가 되었는지를 식별하기 위해 자주 Polling 해야합니다.
        앞서 논의한 것처럼 nginx는 싱글 스레드로 Non Blocking I/O를 사용합니다.
        따라서 단일 프로세스는 어떤 연결 파일을 읽거나 쓸 준비가 되었는지 식별해야합니다.
        운영 체제에는 이를 위한 세 가지 방법 (select, poll, epoll)이 있습니다.
        select와 poll을 사용하면 어떤 File Descriptor가 준비 되었는지를 찾기 위해 모든 File을 Polling 합니다. 효율적인 방법이 아닙니다.
        이 두 가지 방법 모두 너무 많은 연결 수가 있을 때 효율적이지 않습니다.
        예를 들어 한 번에 10000 개의 연결을 제공한다고 가정합니다.
        그리고 그들 중 하나만 읽을 준비가 되었습니다.
        하나의 File Descriptor가 읽을 준비가 되었음을 확인하기 위해 프로세스는 나머지 9999 File Descriptor를 계속 스캔해야 합니다.
        select와 Poll 이외의 또 다른 방법은 epoll이 있습니다.
        이것은 2.6 버전 이상의 Linux 커널에서만 사용 가능합니다.
        Epoll은 select 및 poll 에 비해 효율적인 메커니즘을 사용합니다.
        서버에 10000 개의 연결이 있고 그 중 8000 개가 유휴 연결 인 경우 poll과 select를 사용하는 것은 효과적이지 않습니다.
        왜냐하면 epoll은 활성화 된 연결에만 중요성을 부여하기 때문입니다.
        select & poll 및 epoll은 기본적으로 같은 일을 하지만 epoll을 사용하면 수천 개의 연결을 제공해야 할 때 CPU 사용량이 줄어 듭니다.        
      
    • 설정적용 [/etc/ngnix/nginx.conf]
        ...
      
        events {
          use epoll;
          worker_connections  1024;
        }
      
        ...
      
      • ngnix 에서는 보통 worker_connections를 1024 추천

 

참고: jojoldu.tistory.com

반응형
Comments