← go back

Web에 관한 필수 지식들


— 네트워크
HTTP와 HTTPS에 대해
쿠키(Cookie)와 세션(Session)에 대해
REST와 RESTful API에 대해
OSI7계층에 대해
TCP-프로토콜에-대해
3-way-handshake에 대해
4-way-handshake에 대해
UDP-프로토콜에-대해
포워드 프록시와 리버스 프록시에 대해
— OS
프로세스와 스레드에 대해
세마포어에 대해
뮤텍스에 대해
— DevOps
CI/CD에 대해

HTTP와 HTTPS에 대해


HTTP(HyperText Transfer Protocol)는 웹에서 데이터를 전송하는 프로토콜입니다. HTTPS(HyperText Transfer Protocol Secure)는 HTTP에 데이터 암호화를 추가한 프로토콜입니다.


HTTP는 클라이언트와 서버 간의 요청-응답 프로토콜입니다. 클라이언트가 요청을 보내면 서버는 요청된 데이터를 응답으로 보냅니다. 하지만 HTTP는 암호화가 없어 데이터가 네트워크를 통해 전송될 때 제3자에 의해 도청이나 변조될 위험이 있습니다.

HTTPS는 HTTP와 동일한 요청-응답 방식을 따르지만, SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security) 프로토콜을 사용하여 전송되는 데이터를 암호화함으로써 보안을 강화합니다. 따라서 HTTPS는 민감한 정보(예: 신용카드 정보, 로그인 자격 증명 등)를 전송할 때 사용되며, HTTP에 비해 보안성이 높습니다.

HTTPS를 사용하는 웹 사이트는 주소창에 ‘https://’로 시작하며, 대부분의 웹 브라우저는 안전한 연결이 설정된 것을 사용자에게 알리기 위해 락 아이콘이나 다른 시각적 표시를 제공합니다. 이러한 보안 기능 덕분에 HTTPS는 점차 더 많은 웹 사이트에서 기본 프로토콜로 사용되고 있습니다.

쿠키(Cookie)와 세션(Session)에 대해


쿠키(Cookie)와 세션(Session)은 모두 HTTP 프로토콜의 무상태성을 보완하기 위한 방법입니다. 쿠키는 클라이언트(일반적으로 사용자의 브라우저)에 저장되는 작은 데이터 조각이며, 세션은 서버 측에서 클라이언트를 식별하는데 사용되는 정보입니다.


HTTP는 무상태(stateless) 프로토콜로, 각각의 요청이 서로 독립적이라는 의미입니다. 이는 서버가 이전 요청의 정보를 기억하지 않음을 의미하며, 따라서 이러한 문제를 해결하기 위해 쿠키와 세션이 도입되었습니다.

쿠키는 클라이언트 측에 저장되는 작은 텍스트 파일입니다. 웹사이트는 쿠키를 사용하여 사용자에 관한 정보(로그인 정보, 사이트 선호 설정 등)를 기록하고, 사용자가 사이트를 재방문할 때 이 정보를 읽어 사용자 경험을 개인화하는데 사용합니다.

세션은 서버 측에서 관리되며, 사용자의 요청에 대한 정보를 임시로 저장합니다. 세션 ID는 쿠키를 통해 클라이언트에 전송되어, 서버는 이 ID를 이용해 클라이언트를 식별하고 사용자 세션을 유지합니다.

이 두 가지 기술의 주요 차이점은 저장 위치와 보안입니다. 쿠키는 클라이언트에 저장되기 때문에 상대적으로 취약할 수 있으나, 세션은 서버 측에서 관리되므로 상대적으로 안전합니다. 그러나 세션은 서버의 리소스를 사용하므로 대량의 사용자가 연결되는 경우 서버에 부하를 줄 수 있습니다. 이러한 특성에 따라 상황에 맞게 쿠키와 세션을 적절하게 사용하게 됩니다.

REST와 RESTful API에 대해


REST API는 네트워크 상에서 클라이언트와 서버 간의 통신을 위한 아키텍처로, 자원을 URI로 표현하고 HTTP Method(GET, POST, PUT, DELETE 등)를 통해 자원에 대한 행위를 정의합니다.

즉, 클라이언트는 URI를 통해 특정 자원을 식별하고, HTTP Method를 통해 해당 자원을 조작합니다. 서버는 클라이언트의 요청을 받아 적절한 응답을 반환합니다.


REST는 네트워크 아키텍처 원칙의 집합으로, 웹 서비스를 개발할 때의 일종의 가이드라인을 제공합니다. RESTful API는 이러한 REST 원칙에 기반해 만들어진 웹 서비스 API를 말합니다.

RESTful API의 주요 특징은 다음과 같습니다:

자원 지향적 구조 (Resource Oriented Architecture): RESTful API에서 각각의 URL은 특정한 자원을 나타내며, 이 자원에 대한 CRUD (생성, 읽기, 수정, 삭제) 연산은 HTTP 메서드 (GET, POST, PUT, DELETE 등)를 통해 이루어집니다.

상태 전달 (Stateless): RESTful API는 클라이언트와 서버 간의 상태를 공유하지 않습니다. 각 요청은 별개의 것으로 간주되며 이전 요청이 후속 요청에 영향을 미치지 않습니다. 이러한 성질로 인해 RESTful API는 확장성이 높아집니다.

캐시 가능 (Cacheable): RESTful API는 HTTP의 기능을 이용해 요청을 캐시할 수 있습니다. 이를 통해 서버 부하를 줄이고 응답 시간을 단축시킬 수 있습니다.

자체 표현 구조 (Self-descriptive): RESTful API 메시지는 자체 표현 구조를 가지고 있어, 메시지만 보고도 처리 방법을 쉽게 이해할 수 있습니다.

RESTful API는 이런 특성들 덕분에 웹 서비스의 개발 및 유지보수를 용이하게 해줍니다. 그래서 웹, 모바일 앱, 분산 시스템 등 다양한 환경에서 널리 사용되고 있습니다.

OSI7계층에 대해


OSI 7계층(OSI 7 Layer)은 네트워크 통신을 7개의 계층으로 분리하여 설명한 모델입니다.


  1. 애플리케이션 계층 (Application layer) → HTTP, FTP, SMTP, DNS (사용자와 직접 상호작용하는 응용프로그램)
  2. 프레젠테이션 계층 (Presentation layer) → MIME, SSL (데이터의 인코딩, 암호화, 변환)
  3. 세션 계층 (Session layer) → TLS, SSL (연결 설정 및 유지)
  4. 트랜스포트 계층 (Transport layer) → TCP, UDP (신뢰성 있는 데이터 전송)
  5. 네트워크 계층 (Network layer) → IP, ICMP, ARP (논리 주소와 경로 설정)
  6. 데이터 링크 계층 (Data link layer) → MAC 주소(물리 주소), ARP, PPP (논리적 연결 구성)
  7. 물리 계층 (Physical layer) → Ethernet, Wi-Fi (물리적 전송 매체)

TCP 프로토콜에 대해


TCP (Transmission Control Protocol)는 네트워크 통신에서 가장 널리 사용되는 프로토콜 중 하나로, 두 호스트 사이에서 신뢰할 수 있는 연결을 만들고, 데이터를 순서대로 오류 없이 전달하는 것을 보장하는 프로토콜입니다.


TCP는 IP (Internet Protocol)와 함께 사용되며, 둘을 합쳐 TCP/IP라고도 부릅니다. TCP는 다음과 같은 특징을 가지고 있습니다:

연결 지향성: TCP는 데이터 전송을 시작하기 전에 먼저 목적지와의 연결을 확립합니다. 이 과정에서 3-way handshake라는 과정을 거칩니다.

신뢰성: TCP는 패킷의 재전송 기능을 제공하므로, 패킷이 손실되거나 에러가 발생한 경우에도 신뢰성 있는 데이터 전송을 보장합니다.

흐름 제어 (Flow Control): TCP는 송신측과 수신측의 데이터 처리 속도 차를 관리합니다. 이를 통해 네트워크의 효율성을 높이며, 데이터의 손실을 방지합니다.

혼잡 제어 (Congestion Control): 네트워크 내의 패킷 트래픽이 과도하게 증가하는 것을 방지합니다.

순서 보장: TCP는 패킷의 순서를 보장합니다. 각 TCP 패킷은 순서 정보를 가지고 있어서, 이를 통해 데이터를 올바른 순서로 재조립할 수 있습니다.

이러한 특성 덕분에, TCP는 웹 브라우징, 이메일, 파일 전송 등과 같은 신뢰성이 중요한 네트워크 애플리케이션에서 주로 사용됩니다.

3-way-handshake에 대해


3-way-handshake는 TCP (Transmission Control Protocol)에서 사용되는 방법으로, 클라이언트와 서버 간의 세션을 시작하기 위해 사용됩니다. 이 방법을 사용하면 양방향 통신이 정확하게 초기화되어 데이터 전송이 안정적으로 이루어집니다.


3-way-handshake는 다음과 같은 과정을 거칩니다:

클라이언트가 서버에 SYN 패킷을 보내 연결을 요청합니다. 이 패킷에는 클라이언트가 생성한 초기 시퀀스 번호가 포함됩니다.

서버는 SYN 패킷을 받고, 자신의 초기 시퀀스 번호와 함께 SYN/ACK 패킷을 클라이언트에게 보냅니다. 이 패킷은 서버가 연결 요청을 수락하고 클라이언트에게 다시 연결을 확인하라는 메시지입니다.

클라이언트는 SYN/ACK 패킷을 받고, 이를 확인한 후 ACK 패킷을 서버에게 보냅니다. 이 패킷은 클라이언트가 서버의 연결 수락을 인지하였음을 나타냅니다.

이렇게 3-way-handshake를 거쳐 세션을 성공적으로 시작하면, 클라이언트와 서버는 양방향으로 데이터를 안전하게 전송할 수 있습니다. 이 과정은 TCP/IP 프로토콜에서 연결 지향적인 통신을 제공하는 중요한 방법입니다.

4-way-handshake에 대해


4-way-handshake는 TCP (Transmission Control Protocol)에서 사용되는 프로세스로, 클라이언트와 서버 간의 연결을 안전하게 종료하기 위해 사용됩니다.


4-way-handshake는 다음과 같은 과정을 거칩니다:

클라이언트가 FIN 패킷을 보내어 연결을 종료하길 원함을 알립니다.

이 FIN 패킷을 받은 서버는 ACK 패킷을 되돌려 보내어 FIN 패킷을 받았음을 확인합니다. 이 시점에서, 클라이언트 측에서 서버 측으로의 연결은 종료되었지만, 서버 측에서 클라이언트 측으로의 연결은 아직 유지되어 있습니다.

서버는 모든 데이터를 전송하고 난 후에 자신의 FIN 패킷을 클라이언트에게 보냅니다.

클라이언트는 마지막으로 ACK 패킷을 서버에게 보내어 FIN 패킷을 받았음을 확인합니다. 이로써 모든 연결이 종료되었습니다.

이러한 4-way-handshake 과정을 거쳐 TCP 연결은 양측이 서로 동의하에 정상적으로 종료됩니다. 이렇게 양방향성을 보장하는 이 과정을 통해 데이터 전송이 완전히 완료된 후에 연결이 안전하게 종료되는 것을 보장합니다.

UDP 프로토콜에 대해


UDP (User Datagram Protocol)는 연결을 설정하지 않고, 데이터를 전송하는 데에 초점을 맞춘 통신 프로토콜입니다.


UDP는 TCP와는 다르게 비연결성 프로토콜입니다. 즉, 데이터를 전송하기 전에 특정 대상과의 연결을 먼저 확립하지 않습니다. UDP의 주요 특징은 다음과 같습니다:

비연결성: UDP는 데이터 전송을 시작하기 전에 목적지와의 연결을 확립하지 않습니다. 이는 UDP가 데이터를 빠르게 전송할 수 있게 해주지만, 동시에 신뢰성이나 데이터의 순서를 보장하지 않습니다.

신뢰성 없음: UDP는 TCP와는 달리 전송된 패킷이 손실되거나 에러가 발생해도 재전송하지 않습니다. 따라서 손실되거나 에러가 발생한 패킷에 대한 복구가 불가능합니다.

순서 없음: TCP와는 달리 UDP는 패킷의 순서를 보장하지 않습니다. 수신된 데이터의 순서가 전송된 순서와 다를 수 있습니다.

체크섬 오류검출: UDP 헤더에 있는 체크섬 필드를 통해 최소한의 오류 검출은 가능하지만, 이것이 UDP의 신뢰성을 크게 높이는 것은 아닙니다.

UDP는 이런 특성으로 인해 실시간 서비스(예: VoIP, 비디오 스트리밍, 온라인 게임)에서 주로 사용됩니다. 이런 애플리케이션들은 데이터의 신속한 전송이 중요하며, 일부 데이터 패킷의 손실은 사용자 경험에 큰 영향을 미치지 않기 때문입니다.

포워드 프록시와 리버스 프록시에 대해


프록시는 네트워크 상에서 중개자 역할을 하는 서버로, 포워드 프록시와 리버스 프록시는 그 역할과 동작 방식에 차이가 있습니다.

포워드 프록시: 클라이언트와 인터넷 사이에 위치하여 클라이언트의 요청을 대리로 처리하는 프록시입니다.
리버스 프록시: 서버와 인터넷 사이에 위치하여 서버의 응답을 대리로 처리하는 프록시입니다.


포워드 프록시는 주로 클라이언트 측에서 사용되며 다음과 같은 기능을 수행합니다:

콘텐츠 필터링: 특정 웹사이트의 접근을 제한합니다. 성능 향상: 캐싱을 통해 자주 요청되는 리소스의 로딩 시간을 줄입니다. 보안: 클라이언트의 IP 주소를 숨기는 등의 보안 기능을 제공합니다. 데이터 사용량 제어: 트래픽 관리와 데이터 사용량을 제어합니다.

반면, 리버스 프록시는 서버 측에서 주로 사용되며 이러한 역할을 합니다:

로드 밸런싱: 여러 서버에 분산하여 요청을 처리하므로 시스템 부하를 줄이고 효율을 높입니다. 캐싱: 자주 요청되는 콘텐츠를 캐시하여 서버의 부하를 줄이고 응답 시간을 향상시킵니다. 보안: 서버의 실제 IP를 숨기고, 공격으로부터 서버를 보호합니다. SSL/TLS 종단점 처리: 암호화와 복호화 처리를 담당하여 서버의 부하를 줄입니다. 요약하면, 포워드 프록시는 클라이언트 중심의 기능을 제공하며, 사용자의 요청을 관리하고 제어하는 반면, 리버스 프록시는 서버 중심의 기능을 제공하여 서버의 성능 향상, 보안, 관리를 도와줍니다.

프로세스와 스레드에 대해


프로세스는 운영 체제에서 실행 중인 프로그램을 나타냅니다. 이는 자체적인 메모리 공간을 갖고 있으며, 시스템 리소스를 활용할 수 있는 독립적인 엔티티입니다.
스레드는 프로세스 내에서 실행되는 여러 흐름의 단위입니다. 스레드는 프로세스의 자원을 공유하면서 병렬 처리를 가능하게 합니다.


프로세스는 각각 독립된 메모리 영역(Code, Data, Stack)과 시스템 자원을 할당받아 사용합니다. 프로세스는 다른 프로세스와 정보를 공유하지 않으며, 프로세스간의 통신(IPC, Inter-Process Communication)을 통해 데이터를 주고 받을 수 있습니다. 운영체제는 프로세스에게 CPU 사용 시간을 할당하고 이를 관리하며, 각 프로세스는 이런 CPU 스케줄링에 따라 동작합니다.

스레드는 프로세스 내에서 독립적으로 동작하는 여러 실행 흐름이며, 프로세스의 자원과 메모리를 공유합니다. 따라서 스레드간의 통신이 프로세스 간 통신보다 빠르며, 메모리 사용량도 적습니다. 각 스레드는 고유의 Register와 Stack을 갖고 있지만, Heap 메모리는 다른 스레드와 공유합니다. 이를 통해 프로세스 내에서 병렬 처리를 가능하게 하며, 효율적인 프로그램을 작성할 수 있습니다.

세마포어에 대해


세마포어는 동시에 자원에 접근할 수 있는 프로세스나 스레드의 수를 제한하는 동기화 기법입니다.


세마포어는 공유 자원에 대한 동시 접근을 제어하는 방법으로, 운영 체제의 커널 영역에서 관리되는 정수값을 이용하여 동작합니다. 이 정수값은 동시에 리소스에 접근할 수 있는 최대 허용 개수를 의미하며, 프로세스 또는 스레드가 자원에 접근하려 할 때 이 값을 감소시키고, 자원 사용이 끝나면 다시 증가시킵니다.

세마포어의 값이 0이면, 자원에 접근하려는 프로세스나 스레드는 대기 상태로 전환되고, 세마포어의 값이 다시 양수가 될 때까지 대기합니다. 이렇게 함으로써, 공유 자원에 대한 동시 접근을 제어하고 경쟁 상태(race condition)를 방지할 수 있습니다.

세마포어는 두 가지 기본 연산인 P (proberen, 시도) 연산과 V (verhogen, 증가) 연산으로 이루어져 있습니다. P 연산은 세마포어 값을 감소시키고, V 연산은 값을 증가시키는 작업을 합니다. 이 연산들은 원자적으로 수행되어야 합니다, 즉 이 연산들이 수행되는 동안에는 다른 프로세스나 스레드가 세마포어를 변경하지 못하도록 해야 합니다. 이를 통해 공유 자원에 대한 동기화를 유지하고 데이터의 일관성을 보장합니다.

뮤텍스에 대해


뮤텍스(Mutex, Mutual Exclusion)는 동시에 하나의 스레드 또는 프로세스만이 공유 리소스에 접근하도록 제한하는 동기화 기법입니다.


뮤텍스는 상호 배제(Mutual Exclusion)의 약어로, 여러 스레드 또는 프로세스가 동시에 공유 리소스에 접근하는 것을 방지하고, 한 번에 하나의 스레드 또는 프로세스만이 해당 자원을 사용하도록 제한합니다. 이렇게 함으로써, 뮤텍스는 동시성 제어와 데드락 방지를 위한 중요한 도구로 작용합니다.

뮤텍스는 일반적으로 lock과 unlock 연산으로 구성됩니다. lock 연산은 스레드가 공유 자원을 사용하려고 할 때 호출되며, 해당 자원에 대한 뮤텍스가 이미 잠겨있는 경우, 호출한 스레드는 뮤텍스가 해제될 때까지 대기 상태가 됩니다. 반대로 unlock 연산은 스레드가 공유 자원 사용을 완료하면 호출되며, 이 연산은 뮤텍스를 해제하고 다른 스레드가 공유 자원을 사용할 수 있도록 합니다.

다만, 뮤텍스를 사용할 때는 잠금-해제 순서를 잘 관리해야 하며, 그렇지 않으면 데드락(두 개 이상의 프로세스나 스레드가 서로 상대방의 작업이 끝나기를 영원히 기다리는 상태)가 발생할 수 있습니다. 이러한 문제를 방지하기 위해서는 구조적으로 잠금-해제 순서를 잘 디자인하고, 필요한 경우에는 다른 동기화 메커니즘(예: 세마포어나 컨디션 변수 등)과 함께 사용하는 것이 좋습니다.

CI CD에 대해


CI/CD는 Continuous Integration(지속적 통합)와 Continuous Delivery 또는 Continuous Deployment(지속적 배포)의 약자로, 소프트웨어 개발 프로세스를 자동화하고, 개발 팀이 더 빠르고 신뢰성 있게 애플리케이션을 빌드, 테스트, 배포하도록 돕는 방법론입니다.


Continuous Integration(CI): CI는 개발자가 자신의 코드 변경 사항을 공유 레포지토리에 빈번하게(일반적으로 하루에 여러 번) 통합하는 방법론입니다. 각 통합은 자동화된 빌드 및 테스트 단계를 트리거하여 가능한 한 빨리 버그를 발견하고 해결할 수 있게 합니다. 이렇게 하면 소프트웨어 품질이 향상되며, 통합 문제를 신속하게 찾고 해결할 수 있습니다.

Continuous Delivery: Continuous Delivery는 CI의 논리를 한 단계 더 나아가, 빌드 및 테스트 단계를 통과한 모든 코드 변경 사항이 실제 프로덕션 환경에 배포될 수 있도록 만드는 접근 방식입니다. 이 방법론은 프로덕션에 대한 변경 사항을 안전하게, 신속하게, 그리고 지속적으로 제공할 수 있게 해줍니다. 그러나 실제로 코드가 프로덕션 환경에 자동으로 배포되는 것은 아닙니다. 이 단계에서는 수동 트리거가 필요합니다.

Continuous Deployment: Continuous Deployment는 CI와 Continuous Delivery를 확장하여 코드 변경 사항이 자동으로 프로덕션 환경에 배포되도록 합니다. 이 방법론을 채택하면, 개발 단계에서 프로덕션 단계까지의 코드 변경 사항의 전체 라이프사이클이 자동화되어, 코드 변경 사항의 배포가 지속적으로 이루어집니다.

결과적으로, 이 세 가지 접근 방식의 주요 차이점은 “자동화 수준”에 있습니다. CI는 빌드 및 테스트를 자동화하며, Continuous Delivery는 배포 프로세스까지 자동화하지만 프로덕션 배포는 수동으로 유지합니다. 반면에, Continuous Deployment는 프로덕션 배포까지 완전히 자동화합니다.