Nginx란?
Nginx는 웹 서버 소프트웨어이다.
웹 서버는 클라이언트의 HTTP 요청을 받아 HTML 문서나 다른 파일들을 반환하는 역할을 수행한다.
Nginx는 이런 웹 서버의 기능을 수행할 뿐만 아니라, 리버스 프록시, 로드 밸런서, 메일 프록시 등의 기능도 제공한다.
- 웹 서버
- Nginx는 빠르고 안정적인 웹 서버로 알려져 있다.
- 정적 파일을 효율적으로 처리할 수 있으며, 동시에 수많은 연결을 처리할 수 있는 능력이 있다.
- 리버스 프록시
- 클라이언트가 요청을 보냈을 때, 이 요청을 실제 서버에게 전달하고, 실제 서버의 응답을 클라이언트에게 다시 전달하는 역할을 한다. 이를 통해 서버의 보안을 강화하거나, 클라이언트에게는 하나의 서버로 보이게 하면서 실제로는 여러 서버에 요청을 분산시키는 등의 기능을 구현할 수 있다.
- 로드 밸런서
- 여러 대의 서버가 서비스를 제공하는 환경에서, 각 서버에게 부하가 고르게 분산되도록 요청을 배분하는 역할을 한다. 이를 통해 시스템의 가용성을 높이고, 성능을 향상시킬 수 있다.
- 메일 프록시
- 메일 관련 프로토콜을 지원하여, 메일 서버의 기능도 수행할 수 있다.
- Nginx는 C로 작성되었으며, 이벤트 드리븐 구조를 가지고 있어, 동시에 많은 요청을 효율적으로 처리할 수 있다.
- 이러한 특성 덕분에 대규모 트래픽을 처리하는 환경에서 많이 사용된다. 또한, 설정이 비교적 간단하고, 확장성이 좋아서 개발자들 사이에서도 인기가 많다.
설정파일
- 설정파일은 /etc/nginx/nginx.conf에 위치한다.
- 설정파일은 디렉티브(directives)로 관리된다.
- 간단(simple) 디렉티브와 블럭 디렉티브로 분류된다.
- 설정 끝은 세미클론으로 표시한다.
- include를 사용해서 설정파일을 분리해서 관리한다.
디렉티브
- 블럭으로 감싸져 있으면 블럭 디렉티브 (server, location)
- 안감싸져 있으면 simple 디렉티브 (root)
섹션
Nginx 설정 파일은 여러 개의 섹션으로 구성되어 있다.
가장 중요한 섹션은 'http', 'server', 'location' 이다.
http 섹션
- 전체 HTTP 서버에 대한 설정을 포함한다.
- 파일 업로드의 최대 크기, 로그 형식, 연결 시간 초과 설정 등이 포함될 수 있다.
server 섹션
- 특정 도메인에 대한 설정을 포함한다.
- 리스닝하는 포트, 서버 이름, SSL 설정 등이 포함될 수 있다.
location 섹션
- 특정 URI에 대한 설정을 포함한다.
- 프록시 설정, URI에 대한 리디렉션 설정, 특정 파일에 대한 접근 제어 등이 포함될 수 있다.
각 섹션은 중괄호({})로 묶여 있으며, 섹션 내부에는 다양한 지시어(directive)들이 포함될 수 있다.
지시어는 특정 설정 값을 지정하는 역할을 한다. 예를 들어, 'listen' 지시어는 서버가 리스닝할 포트를 지정하며, 'root' 지시어는 웹 서버의 루트 디렉토리를 지정한다.
Nginx의 설정 파일은 매우 유연하며, 각각의 요구사항에 맞게 세부적으로 조정할 수 있다. 그러나 잘못된 설정은 서버의 성능을 저하시키거나, 예기치 않은 문제를 발생시킬 수 있으므로 주의가 필요하다.
설정 변경 후에는 반드시 Nginx를 재시작하거나 리로드해야 변경 사항이 적용된다.
Server block
- 서버 기능을 설정하는 블록
- 일반적으로 Nginx 설정에서 server 블록은 특정 도메인에 대한 설정을 포함한다.
- 특정 프로토콜(HTTP, HTTPS 등)에 대한 리스닝 포트, 서버 이름 등을 정의한다.
server {
listen 80;
server_name example.org www.example.org;
...
}
server {
listen 80;
server_name example.net www.example.net;
...
}
server {
listen 80;
server_name example.com www.example.com;
...
}
- 각 `server` 블록은 각각의 도메인에 대한 설정을 가진다.
- 각 블록 내부에는 해당 도메인에 대한 웹 서버의 동작을 제어하는 설정들이 위치하게 된다.
- 첫 번째 `server` 블록은 "example.org" 및 "www.example.org" 도메인에 대한 설정을 담당한다.
- `listen 80;`은 해당 서버 블록이 80번 포트에서 들어오는 요청을 처리하도록 설정한다.
- 두 번째 `server` 블록은 "example.net" 및 "www.example.net" 도메인에 대한 설정을 담당한다.
- 마찬가지로 이 블록도 80번 포트를 사용하여 요청을 처리한다.
- 세 번째 `server` 블록은 "example.com" 및 "www.example.com" 도메인에 대한 설정을 담당한다.
- 이 블록 역시 80번 포트를 사용하여 요청을 처리한다.
- 첫 번째 `server` 블록은 "example.org" 및 "www.example.org" 도메인에 대한 설정을 담당한다.
위 구조를 통해, Nginx는 하나의 서버에서 여러 도메인을 처리할 수 있다.
이를 가상 호스팅(Virtual Hosting)이라고 한다. 클라이언트가 요청을 보낼 때 사용하는 도메인 이름에 따라, Nginx는 적절한 `server` 블록의 설정에 따라 요청을 처리하게 된다. 물론 각 `server` 블록 내부에는 더 많은 설정이 있을 수 있다. 예를 들어, 특정 URL 경로에 대한 처리 방식, 프록시 설정, 로깅 설정 등을 추가할 수 있다. 이 설정들은 각 도메인에 대해 개별적으로 적용된다.
실습
helloworld.conf
우리가 직접 생성한 파일을 적용하려면 nginx를 재실행해야 한다.
systemctl restart nginx
재실행 후 /etc/hosts 파일에 다음 내용을 추가한다.
127.0.0.1 helloword.com
- /etc/hosts: 시스템의 네트워크 이름 해석을 돕는 파일
- IP 주소와 해당 IP 주소에 매핑되는 호스트 이름이 표시된다.
- ex) 127.0.0.1 helloworld.com은 `helloworld.com`이라는 도메인 이름을 `127.0.0.1`이라는 IP 주소에 연결하겠다는 의미이다.
- `127.0.0.1`은 로컬호스트(localhost) 주소로, 자신의 컴퓨터를 가리킨다.
- 즉, 이 설정은 사용자가 브라우저나 다른 클라이언트에서 `helloworld.com`을 입력하면, 실제로는 인터넷을 통해 다른 서버를 찾아가는 대신 자신의 컴퓨터(localhost)로 요청을 보내게 된다.
curl helloworld.com:82
- `curl`은 다양한 프로토콜을 지원하는 커맨드라인 툴로, 웹 서버와 상호작용하는 데 주로 사용된다.
- 주로 HTTP GET, POST 요청을 보내거나, 웹 페이지의 내용을 가져오는 등의 용도로 사용한다.
- 위의 `curl helloworld.com:82` 명령은 `helloworld.com` 도메인의 82번 포트에 HTTP GET 요청을 보내는 것을 의미한다.
- `helloworld.com`: 이 부분은 요청을 보낼 대상 서버의 도메인 이름을 지정한다.(도메인 이름은 위 helloworld.conf 파일에서 작성하였다)
- `:82`: 대상 서버에서 열려있는 특정 포트를 지정한다.
- 따라서 이 명령은 `helloworld.com` 도메인의 82번 포트에 HTTP GET 요청을 보내는 것을 의미하며, 서버가 정상적으로 응답하면 그 응답 내용이 터미널에 출력된다.
팁(Tip)!!
nginx -t
- nginx 설정파일이 문법에 맞게 작성 되어있는지 검사한다.
테스트를 위해 기존 helloworld.conf 파일 내용을 다음과 같이 수정한다.
helloworld.com 뒤에 세미콜론(;)을 생략하였다.
nginx -t
- 4번째 라인에서 오류가 발생한 것을 확인 가능하다.
Nginx는 설정 파일에 문법 오류가 있는지 검사하는 'nginx -t' 명령을 제공하므로, 설정 변경 후에는 반드시 이 명령을 이용해 설정 파일을 검사하는 것이 좋다.
http block
- http 프로토콜 사용
현재 우리가 생성한 helloworld.conf 파일은 '/etc/nginx/nginx.conf' 파일 내부에서 include 되어 사용된다.
그리고 nginx.conf 파일 내부는 다음과 같다.
우리가 생성한 helloworld.conf 파일이 nginx.conf 파일의 http block 안에서 include 되어 사용되고 있다.
참고
helloworld.conf 파일의 내용을 nginx.conf 파일 내부의 http block 바깥에 위치시키면 82 포트의 helloworld.com은 동작하지 않는다.
location block
실습
helloworld.conf
server {
listen *:82;
server_name "helloworld.com";
location / {
return 200 "helloworld";
}
location /a/ {
return 200 "helloworld-a";
}
location /b/ {
return 200 "helloworld-b";
}
}
curl helloworld.com:82
curl helloworld.com:82/a
curl helloworld.com:82/b
이때 결과는 모두 "helloworld"만 출력된다.
server {
listen *:82;
server_name "helloworld.com";
location / {
return 200 "helloworld";
}
location /a/ {
return 200 "helloworld-a";
}
location /b/ {
return 200 "helloworld-b";
}
location /a {
return 200 "helloworld-a";
}
location /b {
return 200 "helloworld-b";
}
}
curl helloworld.com:82
curl helloworld.com:82/a
curl helloworld.com:82/b
이 경우 우리가 원하는 대로 "helloworld", "helloworld-a", "helloworld-b"가 출력된다.
문제
- prefix만 맞으면 뒤에 문자열이 있어도 동작한다.
문제 - 해결방안
exact match 방식으로 변경한다.('='을 추가한다)
server {
listen *:82;
server_name "helloworld.com";
location = / {
return 200 "helloworld";
}
location = /a/ {
return 200 "helloworld-a";
}
location = /b/ {
return 200 "helloworld-b";
}
location = /a {
return 200 "helloworld-a";
}
location = /b {
return 200 "helloworld-b";
}
}
위와 같이 exact match 방식을 사용하면 기존 문제가 되던 다음 명령어 입력 시 Not Found가 발생한다.
http://helloworld.com:82/22bcde
http://helloworld.com:82/documents/a/aaa
http://helloworld.com:82/images/b/bbb
File return
Nginx에서 파일 반환은 클라이언트의 요청에 대해 특정 파일의 내용을 응답으로 제공하는 것을 의미한다.
`return` 또는 `try_files` 같은 지시어(directive)를 사용해서 설정할 수 있다.
`return` 지시어
- 클라이언트에게 특정 HTTP 상태 코드와 함께 메시지를 반환한다.
- 이를 사용해 특정 파일의 내용을 반환하려면 다음과 같이 설정해야 한다.
nginx location = /path/to/request { return 200 "Hello, World!"; }
위 설정은 클라이언트가 `/path/to/request`로 요청을 보낼 때 "Hello, World!"라는 메시지와 함께 200 상태 코드를 반환하도록 설정한다.
`try_files` 지시어
- 요청에 대응하는 파일이나 디렉토리를 검색하는 순서를 지정한다.
- 만약 클라이언트가 요청한 파일이나 디렉토리가 존재하지 않을 경우, 마지막에 지정한 URI로 내부 리디렉션을 수행하게 된다.
- 이를 사용해 특정 파일의 내용을 반환하려면 다음과 같이 설정해야 한다.
nginx location /path/to/request { try_files $uri /path/to/file; }
위 설정은 클라이언트가 `/path/to/request`로 요청을 보낼 때, 해당 요청과 일치하는 파일이나 디렉토리를 찾아 반환하도록 설정한다.
만약 요청과 일치하는 파일이나 디렉토리가 없을 경우, `/path/to/file`의 내용을 반환하도록 설정한다.
`root` 지시어
- 클라이언트의 요청을 처리할 때 해당 요청에 대응하는 파일이나 디렉토리를 찾을 기본 디렉토리를 지정한다.
- 예를 들어, 아래와 같이 설정했다고 가정한다.
nginx location /images/ {
root /data;
}
위 설정에서, 클라이언트가 `http://server.com/images/example.jpg`로 요청을 보내면, Nginx는 `/data/images/example.jpg` 파일을 찾아서 반환한다. 즉, `root` 지시자 뒤에 오는 경로(`/data`)와 `location` 블록에 지정된 URI(`/images/`)가 합쳐져서 실제 파일 경로(`/data/images/example.jpg`)가 된다. 만약 해당 파일이 존재하지 않는다면, 404 Not Found 에러가 반환된다.
`root` 지시어는 `server` 블록 또는 `location` 블록 내에서 사용할 수 있으며, `location` 블록 내의 `root` 지시어가 `server` 블록의 `root` 지시자보다 우선순위가 높다. 따라서 특정 URI에 대해서만 다른 root 디렉토리를 지정하려면 `location` 블록 내에서 `root` 지시어를 사용하면 된다.
이후 공부 내용
- location 우선순위
- rewrite
- error page 설정
- log
- 프록시 기능
- 로드밸런서 기능
- 서버튜닝
- 등등
참고
https://www.youtube.com/watch?v=hA0cxENGBQQ&t=818s
'기타' 카테고리의 다른 글
MSA 멀티 모듈 설정 (0) | 2024.04.24 |
---|---|
성능 테스트 관련 개념 정리(작성 중) (1) | 2024.03.22 |
Grafana (0) | 2023.12.17 |
시계열 데이터베이스 InfluxDB (0) | 2023.12.17 |
[우아한테크코스 웹 백엔드 6기] 미션 - 숫자 야구 회고 (2) | 2023.10.23 |