"L7 로드밸런서", "L4 스위치" 같은 말의 근원. 네트워크는 역할별로 층(Layer)을 나눠 설계되어 있고, 각 장비·도구가 어느 층에서 일하는지 알면 대화가 통합니다.
L7
응용 계층 실무 최중요
사람이 쓰는 서비스 수준. URL, HTTP 메서드, 쿠키, 헤더를 "읽고 이해"할 수 있는 층.
HTTP, HTTPS, DNS, WebSocket ALB, nginx, WAF가 여기서 동작
L6
표현 계층
데이터의 형식 변환과 암호화. 실무에선 L7과 묶어서 이야기하는 경우가 많다.
TLS/SSL, 인코딩(UTF-8), 압축
L5
세션 계층
통신 세션(연결의 시작~끝)을 관리. 역시 실무에선 잘 따로 언급되지 않는다.
세션 수립/유지/종료
L4
전송 계층 실무 최중요
IP+포트로 "어느 프로그램에게" 전달할지 결정. 내용은 못 보고 주소만 본다.
TCP, UDP, 포트 번호 NLB, L4 스위치가 여기서 동작
L3
네트워크 계층
IP 주소로 "어느 컴퓨터까지" 갈지 길을 찾는 층. 라우터의 세계.
IP, 라우터, VPC 라우팅 테이블
L2
데이터링크 계층
같은 네트워크 안에서 장비끼리 직접 데이터를 주고받는 층.
MAC 주소, 스위치, 이더넷
L1
물리 계층
실제 전기 신호와 케이블. 랜선, 광케이블, 와이파이 전파.
케이블, 허브, 무선 전파
💡 L4 vs L7 — 실무에서 이게 왜 중요한가? L4 장비(NLB)는 "IP:포트"만 보고 빠르게 넘긴다 → 속도가 빠르지만 URL 기반 분기 불가. L7 장비(ALB, nginx)는 HTTP 내용을 읽는다 → /api/*는 A서버로, /admin/*은 B서버로 같은 똑똑한 라우팅 가능. 대신 약간 느림.
"ALB 쓸까 NLB 쓸까?"는 결국 "내용을 봐야 하나(L7), 빠르게만 넘기면 되나(L4)"의 질문이다.
OSI 7계층네트워크를 역할별로 7개 층으로 나눈 표준 모델. 위의 스택이 바로 그것.
TCP/IP 4계층OSI를 실용적으로 4층(응용/전송/인터넷/네트워크접근)으로 압축한 모델. 실제 인터넷은 이 모델로 동작.
TCP순서 보장·재전송으로 "확실하게" 전달하는 프로토콜. 웹, API 등 대부분이 사용.
UDP확인 절차 없이 "빠르게" 던지는 프로토콜. 영상 스트리밍, 게임, DNS 조회에 사용.
3-way HandshakeTCP 연결 수립 절차. SYN → SYN+ACK → ACK 세 번 주고받고 연결 성립.
MAC 주소네트워크 장비마다 새겨진 고유 하드웨어 주소 (L2). IP는 바뀌어도 MAC은 고정.
라우터 / 스위치라우터는 네트워크 간 길찾기(L3), 스위치는 같은 네트워크 안 전달(L2)을 담당하는 장비.
NAT Network Address Translation사설 IP를 공인 IP로 바꿔 인터넷에 나가게 해주는 변환기. 집 공유기도 NAT.더 알아보기
집 공유기 아래 기기 여러 대가 공인 IP 하나를 나눠 쓰는 것과 같은 원리다. VPC의 NAT Gateway도 프라이빗 서버들의 요청을 자기 공인 IP로 바꿔 내보낸다.
실무에서: 우리 서버가 외부 API를 호출할 때 상대에게 보이는 IP가 NAT의 IP다. 그래서 외부사 "IP 화이트리스트 등록"엔 NAT Gateway IP를 알려준다.
CIDR 사이더IP 주소 범위 표기법. 10.0.0.0/16 = 10.0.x.x 전체. VPC/서브넷 설계에서 필수.더 알아보기
/ 뒤 숫자 = 앞에서부터 고정되는 비트 수. /16은 앞 두 자리 고정(10.0.x.x, 65,536개), /24는 앞 세 자리 고정(10.0.1.x, 256개). 숫자가 클수록 범위가 좁다.
실무에서: Security Group 규칙("10.0.0.0/16에서 오는 3306 허용")과 VPC 설계에서 매일 만나는 표기다.
VPN공용 인터넷 위에 암호화된 전용 터널을 만드는 기술. 회사 내부망 접속에 사용.
공인 IP vs 사설 IP공인 = 인터넷 전체에서 유일한 주소, 사설 = 내부망 전용 주소(10.x.x.x, 192.168.x.x 등). 사설 IP는 인터넷에서 직접 못 쓰고 NAT를 거쳐야 나간다. VPC 안 서버들의 주소가 전부 사설 IP다.
L4 로드밸런서 (NLB)IP:포트만 보고 분배. 초고속·대용량 처리에 유리.
L7 로드밸런서 (ALB)HTTP 내용(URL, 헤더, 쿠키)을 보고 분배. 경로 기반 라우팅 등 똑똑한 기능 제공.
서버는 한 대가 아닙니다. 트래픽을 여러 서버에 나눠주고(로드밸런서), 요청을 대신 받아 넘겨주는(프록시) 교통정리 구간입니다.
← 옆으로 밀어서 보세요
로드밸런서 Load Balancer, LB트래픽을 여러 서버에 골고루 나눠주는 교통경찰. 서버 한 대가 죽어도 서비스가 유지되는 이유.
ALB Application LBAWS의 L7 로드밸런서. URL 경로·호스트·헤더를 보고 분배할 수 있다.
NLB Network LBAWS의 L4 로드밸런서. 내용은 안 보고 초고속으로 넘긴다. gRPC, TCP 서비스에 적합.
nginx 엔진엑스웹서버이자 리버스 프록시의 대표 소프트웨어. 정적 파일 서빙, 요청 중계, 로드밸런싱까지 다 한다.더 알아보기
하는 일: 정적 파일 서빙, WAS로 중계(proxy_pass), 로드밸런싱, TLS 종료, gzip 압축, 접근 로그 기록. 설정 파일(nginx.conf)의 location 블록으로 "이 경로는 이렇게"를 정의한다.
실무에서: "nginx 로그 봐봐"는 요청이 앱까지 도달했는지 확인하는 첫 단계. 앱 로그엔 없는데 nginx 로그엔 있다면 그 사이가 문제다.
리버스 프록시 Reverse Proxy서버 앞에 서서 요청을 대신 받아 뒤로 넘겨주는 중개인. 뒤에 서버가 몇 대인지 사용자는 모른다.
포워드 프록시 Forward Proxy반대로 클라이언트 쪽을 대신해주는 중개인. 회사 프록시, 우회 접속이 이쪽.
업스트림 Upstream프록시 뒤에 있는 실제 목적지 서버. nginx 설정 파일에서 upstream 블록으로 자주 만난다.
헬스체크 Health CheckLB가 "이 서버 살아있나?"를 주기적으로 확인하는 것. 실패한 서버로는 트래픽을 보내지 않는다.
라우팅 Routing요청을 조건(경로, 도메인, 헤더)에 따라 어느 서버로 보낼지 정하는 규칙.
스티키 세션 Sticky Session같은 사용자를 계속 같은 서버로 보내는 LB 설정. 서버가 세션을 메모리에 갖고 있을 때 필요.
타임아웃 Timeout응답을 기다려주는 최대 시간. 구간마다 각자의 타임아웃이 있어서, 어디 것이 먼저 터졌는지가 디버깅 포인트.더 알아보기
종류도 나뉜다 — 연결 타임아웃(연결 수립까지 기다리는 시간)과 리드 타임아웃(응답을 기다리는 시간). 그리고 CDN 30초, ALB 60초, nginx 60초, 앱 내부 10초… 구간마다 값이 제각각이다.
실무에서: 504가 나면 "어느 구간의 타임아웃이 먼저 터졌나"부터 찾는다. 앱의 타임아웃이 LB보다 길면, 앱이 끝나기 전에 LB가 먼저 연결을 끊어버린다.
X-Forwarded-For프록시를 거치면 서버는 프록시 IP만 보게 되는데, 진짜 사용자 IP를 전달해주는 헤더.
💡 502 vs 504 구분법 — 둘 다 프록시/LB가 내는 에러다. 502 Bad Gateway: 뒤 서버가 죽었거나 이상한 응답을 줬다 (연결 자체가 실패, 배포 중 자주 발생). 504 Gateway Timeout: 뒤 서버가 살아는 있는데 너무 느려서 시간 안에 응답을 못 줬다 (슬로우 쿼리, 과부하 의심).
쿠버네티스 Kubernetes, k8s수많은 컨테이너를 자동으로 배치·복구·확장하는 관리 시스템. k8s는 k와 s 사이 8글자를 줄인 표기.
EKSAWS가 관리해주는 쿠버네티스. 회사의 dev-common, prod-common 클러스터가 이것.
클러스터 Cluster쿠버네티스가 관리하는 서버 묶음 전체. 하나의 큰 논리적 컴퓨터처럼 동작한다.
노드 Node클러스터를 구성하는 서버 한 대. EKS에서 실체는 EC2 인스턴스다.
Pod쿠버네티스의 최소 실행 단위. 컨테이너 1개 이상을 담은 캡슐. "pod이 죽었다" = 앱 프로세스 하나가 내려갔다.더 알아보기
보통 Pod 하나에 앱 컨테이너 하나(+사이드카)이며, Pod 안 컨테이너들은 IP와 저장소를 공유한다. Pod은 언제든 죽고 다른 노드에서 다시 태어날 수 있는 "소모품"으로 설계됐다 — 그래서 앞에 고정 주소(Service)가 필요하다.
실무에서:kubectl logs로 보는 로그, kubectl top으로 보는 CPU/메모리가 전부 Pod 단위다.
Deployment"이 앱을 pod 3개로 유지해줘"라는 선언. pod이 죽으면 쿠버네티스가 알아서 다시 띄운다.
ReplicaSet / Replica유지할 pod 개수. replica=3이면 같은 앱이 3개 떠 있다. Deployment가 이를 관리.
Service수시로 죽고 살아나는 pod들 앞에 붙는 고정 주소 겸 내부 로드밸런서.
Ingress클러스터 외부의 트래픽을 내부 Service로 연결하는 입구 규칙. "이 도메인/경로는 이 서비스로".
Namespace클러스터 안을 나누는 논리적 폴더. 회사는 unionstay-api처럼 프로젝트-컴포넌트 형식.
ConfigMap / Secret설정값을 담는 저장소. Secret은 비밀번호·API 키 같은 민감정보 전용.
kubectl 큐브컨트롤쿠버네티스에 명령을 내리는 CLI 도구. kubectl get pods, kubectl logs 등.
Helm쿠버네티스 설정 뭉치(yaml 수십 개)를 하나의 패키지로 설치·관리하는 도구. "k8s의 앱스토어".
사이드카 Sidecar메인 컨테이너 옆에 붙어 보조 역할(로그 수집, 프록시)을 하는 컨테이너. 오토바이 사이드카에서 유래.
운영에서 만나는 상태·설정
HPA Horizontal Pod AutoscalerCPU 사용률 등에 따라 pod 개수를 자동 조절. 쿠버네티스판 오토스케일링.
리소스 request / limitpod에게 보장해줄 CPU·메모리(request)와 최대 허용치(limit). 이 설정이 성능·비용을 좌우한다.더 알아보기
request는 스케줄링 기준("이만큼 여유 있는 노드에 배치해줘"), limit은 초과 시 제재 기준이다. CPU는 limit을 넘으면 속도를 늦추고(스로틀링), 메모리는 넘는 순간 죽인다(OOMKilled).
실무에서: limit이 없으면 한 Pod이 노드 전체를 잡아먹을 수 있고, 너무 빡빡하면 OOMKilled가 반복된다. 성능 이슈 조사에서 가장 먼저 보는 설정 중 하나.
OOMKilled메모리 limit을 초과해 pod이 강제 종료된 것. Out Of Memory. 메모리 누수나 limit 부족 신호.
CrashLoopBackOffpod이 시작하자마자 죽고 재시작을 반복하는 상태. 앱 자체가 못 뜨고 있다는 뜻 (설정 오류, 의존 서비스 접속 실패 등).
Liveness / Readiness ProbeLiveness = 살았나? (실패 시 재시작) / Readiness = 트래픽 받을 준비 됐나? (실패 시 트래픽 차단).
롤링 업데이트 Rolling Updatepod을 하나씩 새 버전으로 교체하며 무중단으로 배포하는 기본 방식.
💬 이럴 때 듣는다
"pod이 자꾸 재시작돼요" → 두 갈래로 나눠 본다. OOMKilled면 메모리 limit 초과(앱은 정상, 메모리가 문제),
CrashLoopBackOff면 앱이 아예 못 뜨는 것(설정·의존 서비스부터 확인).
kubectl get pods의 RESTARTS와 STATUS가 첫 단서다.
✅ 한 줄 요약 — 요청은 Ingress → Service → Pod 순으로 들어오고, 쿠버네티스가 Pod의 개수와 생사를 자동으로 관리한다.
다음: 드디어 우리가 짠 코드 앞에 도착 →
구간 6
애플리케이션 내부: 요청이 코드를 만나다
드디어 요청이 우리가 짠 코드에 도착했습니다. 앱 안에서도 요청은 여러 단계를 거칩니다 — 받아서, 확인하고, 처리하고, 데이터를 가져오는.
← 옆으로 밀어서 보세요
요청 수신 — 웹서버, API의 세계
웹서버 vs WAS웹서버(nginx)는 정적 파일 서빙·중계, WAS(Tomcat, Netty)는 코드를 실행해 동적 응답을 만든다. 보통 nginx → WAS 순으로 배치.
API서버가 제공하는 기능 호출 창구. 프론트와 백엔드, 서비스와 서비스가 이걸로 대화한다.
REST APIURL(자원) + HTTP 메서드(GET/POST/PUT/DELETE)로 기능을 표현하는 API 스타일. 현재 가장 보편적.
엔드포인트 EndpointAPI의 개별 주소. 예: GET /api/v1/orders. 컨트롤러가 이 주소로 요청을 받는다.
미들웨어 Middleware요청이 비즈니스 로직에 닿기 전 거치는 공통 처리 계층. 인증 확인, 로깅, 에러 처리 등.
GraphQL클라이언트가 필요한 데이터 모양을 직접 지정하는 API 방식. REST의 과다/과소 조회 문제를 해결.
gRPC서버끼리의 고속 통신용 프로토콜. 바이너리로 압축해 REST보다 빠르다. MSA 내부 통신에 애용.
WebSocket연결을 계속 유지하며 실시간 양방향 통신하는 방식. 채팅, 실시간 알림에 사용.
웹훅 Webhook이벤트가 생기면 상대 서버로 "먼저 알려주는" 호출. 결제 완료 시 PG사가 우리 서버를 호출하는 식.
인증과 상태 — 너 누구야?
세션 Session로그인 상태를 서버가 기억하는 방식. 서버 메모리/Redis에 저장하고 사용자에겐 세션 ID만 준다.
쿠키 Cookie브라우저에 저장되는 작은 데이터. 세션 ID를 담아 매 요청마다 자동으로 서버에 보내진다.
토큰 / JWT로그인 증명서를 클라이언트가 직접 들고 다니는 방식. 서버가 기억할 필요가 없어 서버 확장에 유리.더 알아보기
JWT는 header.payload.signature 세 부분을 점(.)으로 이은 문자열. payload에 유저 ID·만료시각이 들어있고, 서명 덕에 위조하면 들통난다. 단 내용은 암호화가 아니라 인코딩이라 누구나 읽을 수 있다 — 비밀번호 같은 걸 넣으면 안 되는 이유.
실무에서: 만료가 짧은 액세스 토큰 + 만료가 긴 리프레시 토큰 조합이 표준 패턴. "토큰 만료로 401 떴어요"가 일상 대화.
세션 vs 토큰세션=서버가 기억(즉시 무효화 가능), 토큰=클라이언트가 소지(서버 부담 없음). 서버가 여러 대면 토큰이나 Redis 세션이 필요.
OAuth"카카오로 로그인" 같은 제3자 인증 위임 표준. 비밀번호를 넘기지 않고 권한만 위임받는다.
인증 vs 인가 Authentication / Authorization인증 = "너 누구야?" (로그인), 인가 = "너 이거 해도 돼?" (권한 확인). 401은 인증 실패, 403은 인가 실패.
CORS브라우저가 다른 도메인의 API 호출을 기본 차단하는 보안 정책. 프론트 개발 때 가장 자주 만나는 에러.더 알아보기
다른 출처(도메인·포트가 다르면)로 요청하기 전, 브라우저가 OPTIONS "예비 요청(preflight)"을 보내 서버가 Access-Control-Allow-Origin 헤더로 허락하는지 확인한다. 허락이 없으면 응답을 받아놓고도 JS에게 안 준다.
실무에서: 서버끼리의 호출엔 CORS가 없다 — 순수하게 브라우저만의 규칙이다. "포스트맨으론 되는데 브라우저에선 안 돼요"의 정체.
XSS / CSRF대표적인 웹 공격. XSS = 악성 스크립트 주입, CSRF = 사용자 몰래 요청 위조. WAF와 프레임워크가 방어.
Stateless / Stateful서버가 이전 요청을 기억 안 함 / 함. Stateless여야 아무 서버나 요청을 받아도 되므로 스케일 아웃이 쉽다.
처리 모델 — 서버는 어떻게 동시에 많은 요청을 받나
프로세스 / 스레드 Process / Thread프로그램 실행 단위. 프로세스(독립된 앱) 안에 스레드(일꾼) 여러 개가 있다.
스레드 풀 Thread Pool스레드를 미리 만들어두고 요청마다 빌려주는 방식. Tomcat 기본 200개. 다 차면 요청이 대기한다.
이벤트 루프 Event Loop적은 스레드가 여러 요청을 번갈아 처리하는 방식 (Node.js, WebFlux). 하나가 루프를 오래 점유하면 전체가 밀린다.더 알아보기
식당에 비유하면 웨이터(스레드) 한 명이 주문만 받고 요리는 주방(비동기 I/O)에 맡기는 방식. 웨이터가 한 테이블에 붙잡혀 있으면(블로킹 호출) 모든 테이블의 주문이 멈춘다.
실무에서: "블로킹 호출 하나가 서비스 전체를 느리게 만들었다"는 장애 패턴이 실제로 흔하다. 이벤트 루프 기반 서비스에선 동기 DB 호출·무거운 연산을 루프 밖으로 빼는 게 철칙.
블로킹 / 논블로킹블로킹 = 작업이 끝날 때까지 기다림, 논블로킹 = 안 기다리고 다른 일 함. 이벤트 루프에서 블로킹 호출은 금기.
동기 / 비동기 Sync / Async동기 = 순서대로 결과를 받고 진행, 비동기 = 일 시켜놓고 나중에 결과를 받음.
GC Garbage Collection안 쓰는 메모리를 자동 청소하는 기능. GC가 도는 동안 앱이 잠깐 멈출 수 있다 (GC pause).
커넥션 풀 Connection PoolDB 연결을 미리 만들어두고 재사용하는 저수지. 연결 생성은 비싸므로 필수. 풀이 고갈되면 요청이 줄줄이 대기.더 알아보기
Spring에선 HikariCP가 표준(기본 10개). "풀 크기 = 동시에 DB에 날릴 수 있는 쿼리 수"라서 너무 작으면 앱이 대기하고, 너무 크면 DB가 버거워한다.
실무에서: "connection timeout" 에러는 풀 고갈 신호다. 범인은 대부분 커넥션을 오래 붙잡는 느린 쿼리나 긴 트랜잭션 — 풀 크기를 늘리기 전에 그것부터 찾는다.
아키텍처와 환경
모놀리식 Monolithic모든 기능이 한 덩어리 앱에 들어있는 구조. 단순하지만 커지면 배포·확장이 무거워진다.
MSA Microservices기능별로 작은 서비스 여러 개로 쪼갠 구조. 독립 배포가 가능하지만 서비스 간 통신·운영 복잡도가 올라간다.
환경변수 Environment Variable코드 밖에서 주입하는 설정값 (DB 주소, API 키). 환경마다 다른 값을 쓰기 위한 표준 방법.
dev / staging / prod개발용 / 배포 전 최종 검증용 / 실서비스 환경. "스테이징에서 확인하고 프로드 배포하자"의 그것.
💬 이럴 때 듣는다
"특정 시간대만 API 전체가 느려져요" → 코드가 아니라 '풀 고갈'을 의심한다.
스레드 풀이 다 찼거나, DB 커넥션 풀이 말랐거나, 이벤트 루프를 누가 오래 잡고 있는 것.