Nginx 기본 개념

steve·2023년 10월 19일
0

Backend

목록 보기
5/17

Nginx 사용 목적

  1. 웹서버와 웹 서비스의 기능적 분리
  2. 대량의 트래픽으로 인한 충격을 백엔드 서버나 DB서버로 전달하지 않는 완충 장치로 활용
  3. Queing 및 Buffering (대량 유입 트래픽을 일정하게 유지)
  4. 설정에 따라 worker process를 셋팅하고 이벤트 기반으로 클라이언트의 request를 queue로 처리하여 context switching(request connection이 발생할 때마다 프로세스가 매번 생성/초기화 되는 현상)을 최소화하여 성능을 최적화 함 (동시 커넥션 처리를 Apache 웹 서버보다 10배 이상 효율적으로 처리)
  5. Queue로 처리 시 시간이 오래걸리는 작업 (Disk I/O)은 Thread pool로 인해 자동으로 별도 처리되며 queue는 지연되지 않고 동시 처리 가능
  6. SSL 터미네이션 - 서버가 복호화 과정을 감당하지 않고 비즈니스 로직 처리에 리소스를 사용할 수 있도록 부담을 덜어줌

서버 구성

  1. 기존 api 서버를 로컬 docker container로 올리기

    $ docker build --platform linux/amd64 -f Dockerfile.test -t po-test .

    FROM node:lts-alpine AS builder
    WORKDIR /usr/src/app
    
    COPY package*.json .
    COPY . .
    
    RUN npm ci
    
    ENV NODE_ENV development
    
    EXPOSE 3000 3001 3002 3003

    $ docker run -itd -p 3000:3000 -p 3001:3001 -p 3002:3002 -p 3003:3003 --name api-nginx po-test

    $ docker exec -it api-nginx /bin/sh

  2. Nginx 및 openrc(서비스 관리) 패키지 설치

    $ apk add nginx openrc

  3. Nginx config 설정

    • 3000포트로 받고 3001, 3002포트로 로드밸런싱하도록 설정

    $ vi /etc/nginx/nginx.conf

    user nginx;
    worker_processes auto;
    pcre_jit on;
    error_log /var/log/nginx/error.log warn;
    include /etc/nginx/modules/*.conf;
    include /etc/nginx/conf.d/*.conf;
    
    events {
            worker_connections 1024;
    }
    
    http {
            **upstream backend {
                    server localhost:3001;
                    server localhost:3002;
            }
    
            server {
                    listen 3000;
    
                    location / {
                            proxy_pass http://backend;
                            proxy_set_header Host $host;
                            proxy_set_header X-Real-IP $remote_addr;
                    }
            }**
    
            include /etc/nginx/mime.types;
            default_type application/octet-stream;
    
            server_tokens off;
    
            client_max_body_size 1m;
    
            sendfile on;
    
            tcp_nopush on;
    
            ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    
            ssl_prefer_server_ciphers on;
    
            ssl_session_cache shared:SSL:2m;
    
            ssl_session_timeout 1h;
    
            ssl_session_tickets off;
    
            gzip_vary on;
    
            map $http_upgrade $connection_upgrade {
                    default upgrade;
                    '' close;
            }
    
            log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';
    
            access_log /var/log/nginx/access.log main;
    
            include /etc/nginx/http.d/*.conf;
    }
  4. upstream의 지정 포트 서비스 활성화

    $ npm run start (api 인스턴스 실행 시 config의 포트 변경하여 3001, 3002 포트로 실행)

  5. Nginx 서비스 자동 재시작 설정 및 실행

    $ rc-update add nginx default

    $ rc-service nginx start

    5-1. nginx.conf reloading

    $ rc-service nginx reload

  6. Nginx 로그

    $ less /var/log/nginx/error.log

    $ less /var/log/nginx/access.log

로드밸런싱 설정 (upstream에서 옵션 설정)

  1. IP 해시 방식 (ip_hash)
  2. 가중치 설정 (weight)
    • 서버 별 사양이 다를 때
  3. 최소 연결 방식 (least_conn)
    • 가장 적은 connection인 서버에 트래픽 우선 분배 (세션이 길어지는 경우 사용)

보안 설정

  1. Request 요청 수 제한
  2. 연결 수 제한
  3. 느린 연결 닫기
  4. 특정 IP 주소 차단
  5. 백엔드 서버에 대한 연결 수 제한 (초과한 경우 대기열 queue 설정)
  6. 범위 기반 공격 차단 (헤더의 Range 바이트 범위가 큰 HTTP 요청 시 파라미터 자리 수 체크)

로깅 최적화

  1. 정적 리소스 요청 로깅 해제
  2. 로그 버퍼링(버퍼 설정, flush, 압축률 설정)
  3. 성공한 요청 로깅 해제 (불필요한 로그인 경우, 2xx, 3xx 로그를 쌓지 않거나..)

성능 최적화

  1. 네트워크 대역폭 관련
    • 특정 URL에 대한 대역폭 제한
      (첫 xxxKB까지는 최대속도로 다운, 이후는 yyyKB 속도로 균등하게 다운)
  2. 캐싱 (브라우저 캐싱 / 마이크로 캐싱 / 메모리(Redis..) 캐싱)
    • 웹 리소스와 같은 정적 컨텐츠(이미지, css 등) 반복적으로 요청되는 데이터 호출이나 일정 기간동안 동일한 내용으로 유지되는 컨텐츠(실시간 인기검색어)를 일시적으로 캐싱
    • ex) 항공권 좌석 예약 조회에 1만명 이상이 동시에 잔여 좌석을 조회하는 경우
    • 마이크로캐싱 90ms → 5ms 단축

리소스 관리

  • CPU, Memory 튜닝
    • Nginx는 기존 멀티쓰레드 방식이 아닌 이벤트 기반 처리 방식임
    • 연결은 worker라고 하는 단일 프로세스의 실행 루프에서 이벤트 처리됨
    • worker_processes : 프로세스 관리 (기본 auto를 권장)
    • worker_connection : 보통 CPU 코어 수 * 1024 권장

운영 관련

  1. HSTS (HTTP Strict Transport Security)
  2. CORS 처리
  3. TCP/UDP 커넥션 부하 분산
  4. HTTP/2

nginx.conf 테스트 파일

    # /etc/nginx/nginx.conf
    
    user nginx;
    
    # Set number of worker processes automatically based on number of CPU cores.
    **worker_processes auto;
    # worker_rlimit_nofile 204800;
    # worker_cpu_affinity auto;**
    
    # Enables the use of JIT for regular expressions to speed-up their processing.
    pcre_jit on;
    
    # Configures default error logger.
    error_log /var/log/nginx/error.log warn;
    
    # Includes files with directives to load dynamic modules.
    include /etc/nginx/modules/*.conf;
    
    # Include files with config snippets into the root context.
    include /etc/nginx/conf.d/*.conf;
    
    events {
    	# The maximum number of simultaneous connections that can be opened by
    	# a worker process.
    	worker_connections 1024; 
    #	multi_accept on;
    #	use epoll;	
    }
    
    http {
    	**limit_req_zone $binary_remote_addr zone=zone_one:10m rate=5r/s;**
    	# limit_conn_zone $binary_remote_addr zone=perip:10m;	
    	# limit_conn_zone $server_name zone=perserver:10m;
    
    	**upstream backend {
        		ip_hash;
    		server localhost:3001; # max_fails=1 fail_timeout=10s;
        		server localhost:3002;
    	}**
    
    	**proxy_cache_path /nginx.cache/data1/cache levels=1:2 keys_zone=my_cache_d1:10m 
    		max_size=1g inactive=1m use_temp_path=off;
    	proxy_cache_path /nginx.cache/data2/cache levels=1:2 keys_zone=my_cache_d2:10m
                    max_size=1g inactive=1m use_temp_path=off;
    	split_clients $request_uri $my_cache {
    		50% "my_cache_d1";
    		50% "my_cache_d2";
    	}**
    
    	server {
    		**listen 3000;**
    		**# health_check interval=2s fails=2 passes=5 uri=/ match=welcome;**		
    
    		**location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
    			access_log off;
    			expires 1M;
    			add_header Cache-Control "public";
    		}**
    
    		**location ~* \.(?:css|js)$ {
    			access_log off;
    			expires 1y;
    			add_header Cache-Control "public";
    		}**
        
    		**location / {
    			limit_req zone=zone_one;
    			# limit_conn perip 2;
    			# limit_conn perserver 3;
    			limit_rate_after 1k;
    			limit_rate 1k;
            		proxy_pass http://backend;
            		proxy_set_header Host $host;
            		proxy_set_header X-Real-IP $remote_addr;
    			# health_check interval=2s fails=2 passes=5 uri=/ match=welcome;
    		}**
    
    		**location /adminWebPerformance/header {
    			proxy_cache my_cache_d1;
    			proxy_cache_methods GET HEAD;
    			proxy_cache_key "$scheme$request_method$host$uri$is_args$args";
    			# proxy_cache_key "$host$request_uri$cookie_user";
    
    			proxy_cache_bypass $cookie_nocache $arg_nocache $http_pragma;
    			proxy_cache_min_uses 3;
    
    			# proxy_cache_lock on;
    			proxy_cache_valid 200 302 1m;
    			proxy_cache_valid 404 1m;
    			add_header X-Cache-Status $upstream_cache_status;
    
    			# cache PURGE
    			# proxy_cache_purge $purge_method;
    			proxy_pass http://backend;
    		}**
    
    	}
    
    #	match welcome{
    #		status 200;
    #		header Content-Type = text/html;
    #		body ~ "Welcome to nginx!";
    #	}
    
    	# Includes mapping of file name extensions to MIME types of responses
    	# and defines the default type.
    	include /etc/nginx/mime.types;
    	default_type application/octet-stream;
    
    	# Name servers used to resolve names of upstream servers into addresses.
    	# It's also needed when using tcpsocket and udpsocket in Lua modules.
    	#resolver 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001;
    
    	# Don't tell nginx version to the clients. Default is 'on'.
    	server_tokens off;
    
    	# Specifies the maximum accepted body size of a client request, as
    	# indicated by the request header Content-Length. If the stated content
    	# length is greater than this size, then the client receives the HTTP
    	# error code 413. Set to 0 to disable. Default is '1m'.
    	client_max_body_size 1m;
    
    	# Sendfile copies data between one FD and other from within the kernel,
    	# which is more efficient than read() + write(). Default is off.
    	sendfile on;
    
    	# Causes nginx to attempt to send its HTTP response head in one packet,
    	# instead of using partial frames. Default is 'off'.
    	tcp_nopush on;
    
    	# Enables the specified protocols. Default is TLSv1 TLSv1.1 TLSv1.2.
    	# TIP: If you're not obligated to support ancient clients, remove TLSv1.1.
    	ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    
    	# Path of the file with Diffie-Hellman parameters for EDH ciphers.
    	# TIP: Generate with: `openssl dhparam -out /etc/ssl/nginx/dh2048.pem 2048`
    	#ssl_dhparam /etc/ssl/nginx/dh2048.pem;
    
    	# Specifies that our cipher suits should be preferred over client ciphers.
    	# Default is 'off'.
    	ssl_prefer_server_ciphers on;
    
    	# Enables a shared SSL cache with size that can hold around 8000 sessions.
    	# Default is 'none'.
    	ssl_session_cache shared:SSL:2m;
    
    	# Specifies a time during which a client may reuse the session parameters.
    	# Default is '5m'.
    	ssl_session_timeout 1h;
    
    	# Disable TLS session tickets (they are insecure). Default is 'on'.
    	ssl_session_tickets off;
    
    	# Enable gzipping of responses.
    	#gzip on;
    
    	# Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'.
    	gzip_vary on;
    
    	# Helper variable for proxying websockets.
    	map $http_upgrade $connection_upgrade {
    		default upgrade;
    		'' close;
    	}
    
    	# Specifies the main log format.
    	log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    			'$status $body_bytes_sent "$http_referer" '
    			'"$http_user_agent" "$http_x_forwarded_for"';
    
    	# Sets the path, format, and configuration for a buffered log write.
    	access_log /var/log/nginx/access.log main;
    
    	# Includes virtual hosts configs.
    	include /etc/nginx/http.d/*.conf;
    }

참고 사이트

  • Nginx 공식 문서

nginx documentation

  • nginx 설명 블로그

Nginx Archives - TechExpert

  • Nginx Config Template

https://github.com/h5bp/server-configs-nginx

0개의 댓글

관련 채용 정보