Transfer-Encoding 헤더

  • 안전한 전송을 위해 어떤 인코딩이 메시지에 적용되었는지 수신자에게 알려줌
  • Transfer-Encoding 헤더는 hop-by-hop 헤더로, 리소스 자체가 아닌 두 노드 사이에 메시지를 적용 
  • 다중 노드 연결의 각각의 세그먼트는 Transfer-Encoding의 값을 다르게 사용 가능

    ※ 참고
    • 전체 연결에 있어 데이터를 압축하고자 한다면, Content-Encoding 헤더를 대신 사용하는 것을 추천
    • HEAD 요청에 대한 응답은 GET 요청에 적용될 값을 출력해줌

 

Transfer-Encoding 헤더 지시자

1. chunked

  • Chunked 인코딩 전송방식은 HTTP 1.1에서 사용가능한 스트리밍 데이터 전송 방식
  • 데이터가 일련의 청크(Chunked Message) 내에서 전송
  • Content-Length 헤더는 생략
  • 각 청크의 앞부분에 현재 청크의 길이가 16진수 형태로 오고 그 뒤에는 '\r\n'이 오고 그 다음에 청크 자체가 오며, 그 뒤에는 다시 '\r\n'이 옮
  • 종료 청크는 길이가 0인 것을 제외하면 일반적인 청크와 다르지 않음
  • (비어있을수도 있는) 연속된 엔티티 헤더 필드로 구성된 트레일러(Trailer)가 옮

 

2. compress

  • Lempel-Ziv-Welch (LZW) 알고리즘을 사용하는 형식
  • compress 값의 이름은 알고리즘을 구현한 UNIX compress 프로그램에서 차용된 것
  • compress는 대부분의 UNIX 배포판에서 제외된 압축 프로그램
  • content-encoding에서 compress는 특허 문제로 인해 오늘날 거의 대부분의 브라우저에서 사용되지 않고 있


3. deflate

  • (RFC 1951에 정의된) deflate 압축 알고리즘과 함께 (RFC 1950에서 정의된) zlib 구조체를 사용

 

4. gzip

  • 32비트 CRC를 이용한 Lempel-Ziv coding (LZ77)을 사용하는 형식
  • gzip은 근본적으로 UNIX gzip 프로그램의 형식
  • HTTP/1.1 표준에서 gzip을 content-encoding을 지원하는 서버는 호환성 목적을 위해 x-gzip을 별칭으로 인지할 것을 권고

 

5. identity

  • 압축이나 수정이 없는 정체성 기능을 나타냄 
  • 명시적으로 지정되는 경우를 제외하고 항상 허용 가능한 것으로 간주

 

 

Transfer-Encoding: chunked 헤더 사용 설명

  • Chunked 방식은 전달하려는 컨텐츠의 사이즈가 큰 경우 서버의 처리 지연을 보완할수 있는 방법
  • Transfer-Encoding 헤더는 Chunked 전송방식으로 데이터를 전달하려 할때 주로 사용되는 헤더
  • HTTP 1.1에서는 Content-Length라는 헤더로 전달하고자 하는 컨텐츠의 사이즈 표시 필요
  • 하나의 TCP 커넥션에 여러개의 요청이 가능하기 때문에 클라이언트는 요청마다 전달될 컨텐츠의 데이터 사이즈를 미리 알고 있어야 함 

 

  • Content-Length 헤더로 웹서버에 데이터 처리 과정 → 컨텐츠의 사이즈가 엄청 큰 경우 문제가 발생
    1. 웹서버가 클라이언트의 요청을 받음
    2. 웹서버는 클라이언트에게 전달해 줄 컨텐츠의 사이즈를 먼저 계산 
    3. 계산된 컨텐츠의 전체 사이즈와 함께 데이터를 전달

      ※ 주의
      • 2번 과정에서 컨텐츠의 사이즈가 엄청 큰 경우 문제가 발생 가능
      • 컨텐츠가 큰 경우 전체 사이즈를 계산하는 과정이 오래 걸림 → 클라이언트가 느끼는 지연시간에 반영됨
      • 컨텐츠 사이즈가 큰 경우, 더 효율적인 다른 방식이 필요

 

  • 컨텐츠의 사이즈가 매우 큰 경우 Content-Length 헤더 문제가 발생 가능 → "Chunked" 전송(청크 인코딩; Chunked transfer encoding))
    • Chunked 전송 방식 개념
      • 전체 Chunk를 한번에 주지 않고, Chunked 방식으로 조금씩 조금씩 전송하는 방식
      • 웹서버는 Chunked 방식으로 데이터를 전송하는 경우에는 전체 사이즈를 한번에 계산할 필요가 없음 
      • 보내려는 Chunked만 먼저 클라이언트에게 알리고 데이터를 보냄 → 본문이 동적으로 생성됨에 따라, 서버는 일부를 버퍼에 담은 뒤 한 청크를 크기와 함께 청크 메시지 전송
          
    • Chunked 전송 방식 설명
      • 클라이언트가 이미지를 요청하면, 웹서버는 전체 이미지의 일부분을 전달
      • 전체 이미지의 일부분 사이즈만 알려주면 되기 때문에 전체 사이즈를 계산하지 않아도 됨으로 기존 전송방식의 단점을 극복한 방식
      • 컨텐츠의 마지막 부분을 전송하고 나서는 "0" 을 보내어 데이터가 모두 전송되었음을 알림
      • Chunked 전송방식에는 Content-Length 헤더가 존재하지 않음
         
    • Chunked 방식의 장점
      • 큰 데이터 전송에도 HTTP 연결이 중간에 끊어지지 않게 유지할 수 있음 → HTTP 1.1 연결 유지(Connection: keep-alive, 지속 커넥션)가 활성화
      • Content-Length가 필요 없음 → 크기가 가변적인 데이터 전송에 유리(DB 쿼리 결과를 출력하는 HTML 테이블 / 큰 이미지 등에 사용)
      • 전체 컨텐츠를 생성할 때까지 대기하지 않음
         
    • Chunked 방식을 통해 데이터 전송 과정
      1. Transfer-Encoding: Chunked를 통해 Chunked 전송 방식으로 데이터를 전송할 것을 알림 
      2. Transfer-Encoding: Chunked를 보낸 이후 전송하려는 데이터의 부분적인 사이즈를 16진수로 표시하여 알림
      3. 실제 데이터에 16진수로 표시한 데이터양만큼 보냄 
      4. 위 2~3번 과정을 반복하여 전체 데이터를 전송
      5. 데이터의 마지막 끝부분에 "0" 을 표시하여 데이터 전송이 완료되었음을 알림 
        ### HTTP 응답
        HTTP/1.1 200 OK\r\n
        Content-type: text/plain\r\n
        Transfer-encoding: chunked\r\n
        \r\n
        
        ### 청크 #1
        9\r\n
        HI, Hippo\r\n
        
        ### 청크 #2
        25\r\n
        My name is Hippo. byebye~\r\n
        
        ### 마지막 청크
        0\r\n
        \r\n​
 

 

 

참고 자료 : 분도랑: [HTTP 프로토콜 강좌]#20 HTTP 일반 헤더 II - Transfer-Encoding, Upgrade, Warning, Trailer (withbundo.blogspot.com)

참고 자료 : Transfer-Encoding - HTTP | MDN (mozilla.org)

참고 자료 : 청크 인코딩(Chunked transfer e.. : 네이버블로그 (naver.com)

 

'HTTP > HTTP 헤더' 카테고리의 다른 글

HTTP 프로토콜 Vary 헤더  (0) 2022.06.25
HTTP 프로토콜 server 헤더  (0) 2022.06.25
HTTP 프로토콜 Range 헤더  (0) 2022.06.25
HTTP 프로토콜 Pragma 헤더  (0) 2022.06.25
HTTP 프로토콜 Last-Modified 헤더  (0) 2022.06.25

1. openSSL 사이트에 들어가서 원하는 버전을 다운로드

1.1. 다운로드 경로 : https://www.openssl.org/source/

 

[ Downloads ] - /source/index.html

Downloads The master sources are maintained in our git repository, which is accessible over the network and cloned on GitHub, at https://github.com/openssl/openssl. Bugs and pull patches (issues and pull requests) should be filed on the GitHub repo. Please

www.openssl.org

 

1.2. 원하는 버전에 tar.gz 파일이 다운로드

 

 

2. 다운로드 받은 openssl-X.X.X.tar.gz 파일을 압축 해제(openssl-3.0.13)

## openssl 3.0.13 버전 다운로드
## 형식 tar -xvf openssl-X.X.X.tar.gz
$ tar xvfz openssl-3.0.13.tar.gz

 

 

3. 압축 해체 이후, openssl-X.X.X 폴더 진입(openssl-3.0.13)

## 형식 : cd openssl-X.X.X
$ cd openssl-3.0.13;

 

 

4. openssl-X.X.X 폴더로 진입하여 ls 명령어를 입력, config 실행

4.1. 사용 가능한 패키지들 업데이트 및 필수 패키지 설치

$ sudo apt-get update;
$ sudo apt-get install build-essential -y;​

 

4.2. openssl-X.X.X 폴더 내 ls 명령어 확인

$ ~/openssl-3.0.13# ls
ACKNOWLEDGEMENTS.md  demos        ms                 README-FIPS.md
apps                 doc          NEWS.md            README.md
AUTHORS.md           engines      NOTES-ANDROID.md   README-PROVIDERS.md
build.info           e_os.h       NOTES-DJGPP.md     ssl
CHANGES.md           external     NOTES-NONSTOP.md   SUPPORT.md
config               FAQ.md       NOTES-PERL.md      test
config.com           fuzz         NOTES-UNIX.md      tools
configdata.pm        HACKING.md   NOTES-VALGRIND.md  util
configdata.pm.in     include      NOTES-VMS.md       VERSION.dat
Configurations       INSTALL.md   NOTES-WINDOWS.md   VMS
Configure            LICENSE.txt  os-dep             wycheproof
CONTRIBUTING.md      Makefile     providers
crypto               Makefile.in  README-ENGINES.md

 

4.3. openssl-X.X.X 폴더 내 config 명령어 실행

$ ./config
Configuring OpenSSL version 3.0.13 for target linux-x86_64
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created Makefile.in
Created Makefile

**********************************************************************
***                                                                ***
***   OpenSSL has been successfully configured                     ***
***                                                                ***
***   If you encounter a problem while building, please open an    ***
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL.md file first)      ***
***                                                                ***
**********************************************************************

 

 

5. make 명령어를 사용해 소스를 컴파일

5.1. 컴파일(소스파일을 사용자가 실행 가능한 파일로 만들어 주는 과정) 진행(대략 5분 정도 소요)

$ make
...생략...

 

5.2. 컨파일 완료 후 실행 가능한 파일 생성 확인 → 완료 시 아래와 같이 출력

$ make
...생략...
make[1]: Leaving directory '/home/~/openssl-3.0.13'

 

 

6. 실행 가능한 파일 생성 후 설치 진행

$ make install
...생략...
install doc/html/man7/provider-rand.html -> /usr/local/share/doc/openssl/html/man7/provider-rand.html
install doc/html/man7/provider-signature.html -> /usr/local/share/doc/openssl/html/man7/provider-signature.html
install doc/html/man7/provider-storemgmt.html -> /usr/local/share/doc/openssl/html/man7/provider-storemgmt.html
install doc/html/man7/provider.html -> /usr/local/share/doc/openssl/html/man7/provider.html
install doc/html/man7/proxy-certificates.html -> /usr/local/share/doc/openssl/html/man7/proxy-certificates.html
install doc/html/man7/ssl.html -> /usr/local/share/doc/openssl/html/man7/ssl.html
install doc/html/man7/x509.html -> /usr/local/share/doc/openssl/html/man7/x509.html



7. 설치한 openssl 명령어 버전 확인 후 조치

7.1. openssl 명령어 버전 조회 시 에러 메시지 발생

$ openssl version
openssl: /lib/x86_64-linux-gnu/libcrypto.so.3: version `OPENSSL_3.0.9' not found (required by openssl)

 

7.2. 조치 사항

$ echo "/usr/local/lib64" > /etc/ld.so.conf.d/openssl-3-0-13.conf
$ openssl version
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)

 

 

참고 자료 : [Linux] OpenSSL을 Ubuntu에서 설치하고 업데이트하는 방법 — hyun 공부 학습 공간 (tistory.com)

 

 

  • Ubuntu에서 /etc/resolv.conf 파일이 초기화되는 현상이 발생 → Ubuntu 기본 세팅
  • /etc/resolv.conf 초기화되지 않도록 하기 위해 조치사항

 

1. apt install 패키지 설치를 위해 /etc/resolve.conf에 nameserver 8.8.8.8 추가

$ vi /etc/resolv.conf
...생략...
nameserver 8.8.8.8

 

 

2. resolvconf 패키지 설치

$ apt install resolvconf -y

 

 

3. resolvconf 확인

  • /etc/resolvconf 디렉토리 확인
  • /run/resolveconf/resolv.conf 파일에 소프트링크
    $ ls -al /etc/resolv.conf
    lrwxrwxrwx 1 root root 29 Apr  1 02:44 /etc/resolv.conf -> ../run/resolvconf/resolv.conf​

 

4. head 파일 수정

  • resolve.conf 파일은 위에서부터 읽어들임
  • nameserver 8.8.8.8이 /etc/resolv.conf 파일의 최하단에 위치하면 다른 nameserver 설정의 IP을 먼저 DNS 서버로 사용하고, 위 DNS가 비정상일 경우에 8.8.8.8을 통해 질의함
    $ vi /etc/resolv.conf
    ...생략...
    nameserver 8.8.8.8​

 

5. 서버 재부팅 후 재확인 → 정상적으로 유지 확인

$ vi /etc/resolv.conf
...생략...
nameserver 8.8.8.8​

 

 

참고 자료 : [Solved][Ubuntu18.04] 서버 재부팅시 resolv.conf 초기화되는 문제 해결 :: Devader (tistory.com)

 

  • nginx는 새로 들어오는 모든 요청에 대해 upstream(backend) 서버에 대한 새 연결(incoming request)→ 안전하지만 비효율적
    1. nginx와 upstream(backend) 서버가 연결을 설정하려면 패킷 3개를 교환
    2. nginx와 upstream(backend) 서버가 연결을 종료하려면 패킷 3~4개를 교환

 

  • 트래픽이 많을 경우 모든 요청에 대해 새 연결을 열면 시스템 리소스가 고갈되어 연결을 열지 못 함
  • nginx에서 upstream 서버로 연결하는 경우 source address, destination address, and destination port 는 고정되어 있고 source port만 변수
  • nginx 연경은 source address, source port, destination address, and destination port 4가지 요소로 구성

 

  • nginx에서 upstream 서버와 연결이 닫히면 linux 소켓은 2분 동안 TIME-WAIT 상태가 됨
    • 트래픽이 많으면 사용 가능한 source port가 소진될 가능성이 높아짐 → nginx는 upstream 서버에 대한 새 연결을 열 수 없는 상태가 됨
    • source port가 고갈되는 것을 막기 위해 요청이 완료되면 연결이 닫히는 대신 추가 요청에 사용할 수 있도록 연결을 열어두는 keep-alive 연결을 nginx와 upstream 간에 활성화

 

  • 각 worker process의 캐시에 보존되는 upstream 서버에 대한 idle keep-alive 연결 수를 설정하려면 upstream{} 블록에 keepalive 지시어 사용
    • keepalive 지시어는 worker process가 열 수 있는 upstream 서버에 대한 총 연결 수(total number of connections)를 제한하지 않음
    • keepalive 지시어는 upstream{} 블록에 나열된 서버 수의 두 배로 설정하는 것이 좋음
    • 두배 설정은 nginx가 upstrem 모든 서버와의 keep-alive 연결을 유지하기에 충분히 크며, upstream 서버에 새로 들어오는 연결도 처리 가능하도록 작음
       
    • upstream{} 블록에서 hash, ip_hash, least_conn, least_time, random 지시어를 사용하여 load‑balancing algorithm 을 지정
    • hash, ip_hash, least_conn, least_time, random 지시어가 keepalive 지시어 위에 표시 필요(필수) 

 

  • 요청을 upstream으로 전달하는 location{} 블록에 proxy_pass 지시어와 함께 아래 지시어를 포함
    • nginx는 upstream 서버에 대한 연결에 HTTP/1.0을 사용 → 서버로 전달되는 요청에 Connection: close 헤더를 추가
    • upstream{} 블록에 keepalive 지시어가 있음에도 불구하고 요청이 완료되면 각 연결이 닫힘
    • proxy_http_version 지시어는 nginx가 HTTP/1.1을 대신 사용하도록 지시 → proxy_set_header Connection "" 헤더를 통해서 close 값을 제거함
      proxy_http_version 1.1;
      proxy_set_header Connection "";
       
  • proxy_http_version 지시자
    • 프록시 서버를 위한 HTTP 프로토콜 버전을 설정
    • 기본적으로 버전 1.0이 사용
    • keep-alive 연결 및 NTLM 인증과 함께 사용하려면 버전 1.1을 사용하는 것이 좋음
      구문 :	proxy_http_version 1.0 | 1.1;
      기본 :	proxy_http_version 1.0;
      문맥 :	http, server, location​
       
  • proxy_set_header Connection "" 설정
    • nginx서버에서 upstream으로 요청을 프록시할 때 HTTP 버전을 1.0으로, Connection 헤더를 close로 바꿔서 보냄
    • upstream으로 keepalive 커넥션을 사용하기 위해서는 프록시 HTTP 버전을 1.1로 변경해야 한다고 권장
    • 추가적으로 proxy_set_header Connection "" 설정을 통해 Connection 헤더를 없애주는 설정 진행

    • upstream 서버로 HTTP 버전을 1.0, Connection 헤더를 close으로 전송
    • upstream 서버로 HTTP 버전을 1.1, Connection 헤더를 초기화하여 전송

 

 

참고 자료 : Avoiding the Top 10 NGINX Configuration Mistakes - NGINX

참고 자료 : https://seungtaek-overflow.tistory.com/10

 

  • error_log off 지시문으로는 로깅을 비활성화 불가 → access_log 지시어와 달리 error_log는 off 매개 변수를 사용하지 않음
  • 만약 nginx에 error_log off 지시어를 포함하면 nginx 구성 파일의 기본 디렉토리(/etc/nginx)에 off라는 이름의 에러 로그 파일을 생성됨
     
  • error_log 로그는 nginx의 문제를 디버깅할 때 중요한 정보 소스이므로 비활성화하지 않는 것이 좋지 않음
  • 만약 스토리지가 너무 제한적이어서 사용 가능한 디스크 공간을 모두 소진할 정도의 경우 오류 로깅을 비활성화하는 것이 좋음

  • main 설정에 error_log 지시어 사용 예시
    error_log /dev/null emerg;​

 

  • error_log 지시어
    • 여러 개의 로그를 지정 가능 
    • main configuration 수준에서 로그를 쓰는 것이 명시적으로 정의되어 있지 않으면 기본 파일이 사용
      구문 :	error_log file [level];
      기본 :	error_log logs/error.log error;
      문맥 :	main, http, mail, stream, server, location​
       
  • error_log 지시어의 매개변수
    1. error_log 첫 번째 매개변수
      • 로그를 저장할 파일을 정의
      • stderr 특수 값은 표준 오류 파일(standard error file)을 선택 
      • "syslog:" 접두사를 지정하여 syslog에 로깅하도록 구성 가능 
      • "memory: size" 접두사와 버퍼 크기를 지정하여 순환 메모리 버퍼에 로깅 구성 가능. 일반적으로 디버깅에 사용
         
    2. erorr_log 두 번째 매개변수
      • 로깅 수준을 결정
      • debug, info, notice, warn, error, crit, alert 중 하나가 될 수 있음
      • 로그 수준(Log levels)은 심각도가 높아지는 순서대로 나열
      • 특정 로그 수준(certain log level)을 설정하면 지정된 로그 수준보다 더 심각한 로그 수준의 모든 메시지가 기록됨 → 예시) 오류 로그(error log)는  error, crit 및 alert  메시지가 기록됨
      • error_log 매개 변수를 생략하면 error가 사용

 

  • error_log 지시어는 nginx가 구성을 읽고 유효성을 검사할 때까지 적용되지 않는다는 점에 유의
  • nginx가 시작하거나 구성이 다시 로드될 때마다 구성의 유효성이 검사 → 기본 error log(/var/log/nginx/error.log) 로깅
  • 로그 디렉터리를 변경하려면 nginx 명령에 -e <error_log_location> 파라미터를 포함

 

참고 자료 : Avoiding the Top 10 NGINX Configuration Mistakes - NGINX

 

  • worker_connections 지시어는 nginx의 worker process가 열 수 있는 최대 동시 연결 수를 설정(기본값은 512). 
  • 클라이언트 연결뿐만 아니라 모든 유형의 연결(프록시 서버와의 연결)이 최대 연결 수에 포함 → proxy_pass도 포함
  • worker당 동시 연결 수에는 다른 제한이 있음 → 각 프로세스에 할당된 File Descriptors(파일 설명자)의 최대 수에 대한 OS 제한 
  • 최신 UNIX 배포판에서  File Descriptors(파일 설명자)의 최대 수에 대한 기본 제한은 1024개
  • 가장 작은 규모의 nginx 배포를 제외한 모든 배포에서 worker당 512개의 연결 제한은 너무 작을 수 있음 
  • 이 문제를 해결하려면 기본 구성 컨텍스트에서 worker_rlimit_nofile 지시어를 사용하여 설정

 

  • worker_rlimit_nofile 지시자
    • worker process의 최대 파일 열기 수 제한(RLIMIT_NOFILE)을 변경 
    • Main Process를 다시 시작하지 않고 제한을 늘리는 데 사용
      구문 :	worker_rlimit_nofile number;
      기본 :	—
      문맥 :	main​

 

  • 더 많은 File Descriptors(파일 설명자)가 필요한 이유
    • nginx worker process에서 클라이언트 또는 업스트림 서버로의 각 연결은 File Descriptors를 소비 
    • nginx가 웹 서버로 작동하는 경우, 클라이언트 연결에 하나의 File Descriptors를 사용하고 제공되는 파일당 하나의 File Descriptors를 사용하여 클라이언트당 최소 2개의 File Descriptors를 사용
    • 프록시 서버로 작동하는 경우, nginx는 클라이언트 및 업스트림 서버 연결에 각각 하나의 File Descriptors 사용(2개 사용)하고, 서버의 응답을 임시로 저장하는 데 사용되는 파일에 세 번째 File Descriptors를 사용
    • nginx가 캐싱 서버로 작동하는 경우, 캐시된 응답에 대해서는 웹 서버처럼 작동하고 캐시가 비어 있거나 만료된 경우에는 프록시 서버처럼 작동
    • nginx는 로그 파일당 File Descriptors를 사용하고 Master 프로세스와 통신하기 위해 몇 개의 File Descriptors를 사용 → 일반적으로 몇 개의 File Descriptors 숫자는 연결 및 파일에 사용되는 File Descriptors의 수에 비해 작음

 

  • UNIX는 프로세스당 File Descriptors 수를 설정하는 몇 가지 방법을 제공
    1. nginx를 시작하는 경우 ulimit 명령어
      • ulimit 명령어는 프로세스가 사용하는 자원에 대한 제어 및 관리할 수 있게 해줌
      • ulimit 명령어는 하나의 유저(쉘,프로세스)에 대해서 할당할 자원량의 한계를 정하는 것으로서 리눅스 시스템에서 과부하를 막아주는 방패가 되어 주는 유용한 설정
      • ulimit는 일시적 설정
        $ ulimit -n 65536
         
      • soft와 hard 두 가지 타입
        • soft → 새로운 프로그램을 생성하면 기본으로 적용되는 한도
        • hard → soft 한도에서 최대로 늘릴 수 있는 한도
           
    2. nginx를 서비스로 시작하는 경우 init 스크립트 또는 systemd 서비스 manifest 변수 사용
      $ vi /etc/systemd/system/nginx.service
      [Unit]
      Description=The NGINX HTTP and reverse proxy server
      After=syslog.target network.target remote-fs.target nss-lookup.target
      
      [Service]
      Type=forking
      PIDFile=/run/nginx.pid
      ExecStartPre=/usr/local/nginx/sbin/nginx -t
      ExecStart=/usr/local/nginx/sbin/nginx
      ExecReload=/usr/local/nginx/sbin/nginx -s reload
      ExecStop=/bin/kill -s QUIT $MAINPID
      PrivateTmp=true
      LimitNOFILE=65535
      LimitNOFILESoft=65535
      
      [Install]
      WantedBy=multi-user.target​​
       
    3. /etc/security/limits.conf 파일 → 유저의 프로세스별 file open을 설정
      • /etc/security/limits.conf 파일은 유저의 프로세스별 사용하는 자원에 대한 제어 및 관리할 수 있게 해줌
      • 할당할 자원량의 한계를 정함으로 리눅스 시스템에서 과부하를 막아줌

      • /etc/security/limits.conf 파일은 영구적 설정
        $ vi /etc/security/limits.conf
        
        ## nginx 사용자 계정에 수치를 지정
        nginx   soft  nofile  1048576
        nginx   hard  nofile  1048576
        nginx   soft  nproc   1048576
        nginx   hard  nproc   1048576
        
        ## *를 사용하여 모든 계정에 수치를 지정
        *   soft  nofile  1048576
        *   hard  nofile  1048576
        *   soft  nproc   1048576
        *   hard  nproc   1048576​
       
    4. sysctl.conf 의 file open 확인 및 커널 설정
      • sysctl.conf에서 시스템 전체에 대한 file open 개수를 설정
        $ cat /proc/sys/fs/file-nr
        3072    0       300000
        |         |       |
        |         |       |
        |         |       최대 오픈 파일 디스크립터 수(fs.file-max)
        |        할당되지 않은 파일 디스크립터 수 (2.6 커널에서는 항상 0으로 표기되며 이는 에러 아님)
        할당된 파일 디스크립터 수
         
      • 커널의 fs.file-max 파라미터는 시스템 전체에서 최대로 열 수 있는 파일 개수
      • 커널의 fs.file-max 파라미터는 시스템의 메모리를 KB로 표현한 값의 10%가 적당
      • 커널의 fs.nr_open 파라미터는 하나의 프로세스가 열 수 있는 최대 파일 개수
      • 커널의 fs.nr_open 파라미터는 기본값은 1024*1024 (1048576) → 대부분의 머신에서 충분(Actual limit depends on RLIMIT_NOFILE resource limit.)
         
      • 커널의 fs.file-max 파라미터와 fs.nr_open 파라미터 설정 확인 및 변경
        ## 기존 설정값 확인
        $ sysctl -a | grep fs.file-max
        fs.file-max = 300000
        
        $ cat /proc/sys/fs/file-max
        300000
        
        ## 기존 파라미터 값 수정
        $ vim /etc/sysctl.conf
        fs.file-max = 1048576
        
        ## 설정 값 적용
        $ sysctl -p
        
        
        ## 변경 설정값 확인
        $ sysctl -a | grep fs.file-max
        fs.file-max = 300000
        
        $ cat /proc/sys/fs/file-max
        300000
        
        $ cat /proc/sys/fs/file-nr
        3008    0       1048576

 

  • 시스템 전체에 File Descriptors 수에 대한 제한이 있으며, OS의 sysctl fs.file-max 명령으로 설정 가능
  • nginx를 시작하는 방법에 따라 다르지만, worker_rlimit_nofile은 nginx를 시작하는 방법에 작동
  • 모든 nginx worker process가 사용할 수 있는 최대 파일 설명자 수(worker_rlimit_nofile * worker_processes)가 fs.file-max보다 훨씬 적은지 확인 필요
  • nginx가 사용 가능한 모든 File Descriptors를 사용하는 경우(예: DoS 공격), 문제를 해결하기 위해 컴퓨터에 로그인하는 것조차 불가능해짐

 

 File Descriptor(파일 디스크립터)

  • 리눅스 혹은 유닉스 계열의 시스템에서 프로세스(process)가 파일(file)을 다룰 때 사용하는 개념
  • 프로세스에서 특정 파일에 접근할 때 사용하는 추상적인 값
  • File Descriptor(파일 디스크럽터)는 일반적으로 0이 아닌 정수값을 갖음

 

참고 자료 : 가장 많이 실수하는 NGINX 설정 에러 10가지 - NGINX STORE

참고 자료 : file open 확인 및 커널 설정 : 네이버 블로그 (naver.com)

 

D state란

  • process 상태(STAT)가 D로 표시되는 process는 "uninterruptible sleep" 상태를 의미
  • 일반적으로 I/O에 대해 대기하는 것으로 다른 어떤 일도 할 수 없는 상태 → I/O operation이 완료되기 전까지는 죽은 상태
  • D 상태인 process들은 operation이 완료되어 R/S(Run/Sleep)에 돌아가기 전까지 보통 작은 시간동안(a fraction of a second)만 거기에 있음
     
  • 서버가 I/O 집약적인 작업(intensive operations)을 수행할 때 프로세스가 "D" 상태로 표시되는 것은 정상 
  • 성능이 문제가 되는 경우 디스크의 상태를 확인 필요
  • 펌웨어 및 커널 디스크 드라이버가 업데이트되었는지 확인필요

 

  • process가 D 상태에 빠지는 경우
    1. 연결될 수 없는 NFS나 다른 원격 파일시스템과 통신하려는 경우
    2. 문제가 있는 하드 드라이브에 접근하려는 경우
    3. 비정상적인 device 드라이버를 이용해 하드웨어를 사용하려고 경우

 

  • D state process는 uninterruptible sleep으로 I/O를 대기 중 상태
    • ps 명령어는 uninterruptible sleep의 process에 대해 "D"를 표시 
    • vmstat 명령어는 "blocked" 상태이거나 "waiting on I/O" process를 표시 
    • "D" state Process는 SIGKILL 또는 kill -9를 사용해도 중단할 수 없음 → 서버를 재부팅하거나 I/O가 응답할 때까지 기다려야만 지울 수 있음

 

  • Uninterruptible sleep 상태는 D state의 process로 아무것도 할 수 없는 상태
    • process는 일반적으로 D State를 오래 유지하지 않음
    • D State process가 쌓여 있으면 시스템의 일부 로직이 중단됨
    • ps 명령어에 l 옵션 추가하여 긴 포맷으로 출력 → 우선순위와 관련된 PRI와 NI값 확인 가능  
    • WCHAN 열에는 process가 sleeping인 커널 함수의 이름이 표시
      $ ps axl | awk '$10 ~ /D/'
      F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
      vass     13478  7.2  0.0   1732   624 pts/1    D+   17:36   0:00 find ./​

 

process STAT(프로세스 상태)

  • Linux의 process는 running, sleeping 등 여러 가지 상태가 될 수 있음
  • Running process는 방금 CPU에서 실행 중이고, Sleeping process는 CPU가 켜지거나 다른 이벤트가 발생할 때까지 기다리는 상태를 의미
  • ps 명령어를 사용하면 시스템에서 각 process의 상태에 대한 정보를 얻을 수 있음
     
  • ps 명령어의 STAT 열에 표시
    • 큰 S는 Sleeping을 의미
    • 작은 s는 process이 session leader을 의미 → process가 새로운 session을 생성하면 해당 process는 session leader가 됨(Session Process의 PID = Session ID)
    • 큰 R은 Running을 의미
    • +는 foreground process를 의미
      $ ps a
        PID TTY      STAT   TIME COMMAND
       4975 tty1     Ss+    0:00 /sbin/mingetty tty1
       4976 tty2     Ss+    0:00 /sbin/mingetty tty2
       6202 pts/0    Ss+    0:01 -bash
      10312 pts/1    Ss     0:00 -bash
        639 pts/1    R+     0:00 ps a​

 

참고 자료 : Processes in D state - OpenVZ Virtuozzo Containers Wiki

참고 자료 : [Linux] Uninterruptible sleep 프로세스 상태 D :: TOP GUN (tistory.com)

참고 자료 : Processes in an Uninterruptible Sleep (D) State | Support | SUSE

 

OMSA 패키지 설치

$ apt-get update
$ apt-get install gpg libssl-dev
$ echo 'deb http://linux.dell.com/repo/community/openmanage/11000/jammy jammy main' > /etc/apt/sources.list.d/linux.dell.com.sources.list
$ wget https://linux.dell.com/repo/pgp_pubkeys/0x1285491434D8786F.asc
$ apt-key add 0x1285491434D8786F.asc
$ apt-get update
$ apt-get install srvadmin-all

 

 

OMSA 관련 명령어 소프트 링크 설정(omreport, racadm 명령어)

$ ln -s /opt/dell/srvadmin/sbin/omreport /usr/bin/omreport
$ ln -s /opt/dell/srvadmin/sbin/racadm /usr/bin/racadm


$ ls -al /usr/bin/omreport
lrwxrwxrwx 1 root root 32 Sep  8 15:19 /usr/bin/omreport -> /opt/dell/srvadmin/sbin/omreport


$ ls -al /opt/dell/srvadmin/sbin/racadm
lrwxrwxrwx 1 root root 21 Mar 15 04:43 /opt/dell/srvadmin/sbin/racadm -> racadm-wrapper-idrac7
 
 

3. OMSA 설치 확인(https:[서버IP]:1311 접속)

 

 

수동 설치 가이드 : https://www.dell.com/support/kbdoc/ko-kr/000185829/openmanage-server-administrator-on-linux-%EC%84%A4%EC%B9%98-%EB%B0%A9%EB%B2%95

모델/OS 버전별 OMSA Version 가이드 : https://linux.dell.com/repo/community/openmanage/

 

 

+ Recent posts