컴퓨터 네트워크 5편

HTTP의 진화, 전자우편, DNS — 조건부 GET부터 이름 풀이까지

suhyun·2026년 10월 15일·읽는 데 약 22분
한 줄로: DNS는 어느 서버도 전부를 알지 못하는 분산·계층 데이터베이스이고, 로컬 DNS 서버가 루트, TLD, 책임 서버를 차례로 물어 이름을 IP 주소로 바꿉니다.

1. 조건부 GET — 캐시의 사본이 아직 맞는가

앞 글에서 웹 캐시가 응답 시간과 접속 회선 트래픽을 얼마나 줄이는지 계산했습니다. 캐시가 들고 있는 사본은 원 서버에서 객체가 바뀌면 낡은 사본이 됩니다. 캐시가 그 사본을 계속 내주면 사용자는 옛 내용을 보게 됩니다. 이것이 캐시와 원 서버 사이의 일관성 문제(consistency problem)입니다.

해결 방법이 조건부 GET(conditional GET)입니다. 캐시는 평소의 GET 요청에 헤더 줄 하나를 더해 원 서버에 보냅니다.

If-Modified-Since: Fri, 02 Oct 2026 09:30:00 GMT

날짜 자리에는 캐시가 가진 사본의 최종 수정 시각을 적습니다. 원 서버는 그 시각 이후 객체가 바뀌었는지 보고 답합니다.

원 서버의 객체응답객체 전송
그 시각 이후 바뀌지 않음304 Not Modified없음. 짧은 응답 메시지만 간다
그 시각 이후 바뀜200 OK + 새 객체새 객체를 보내고 캐시가 사본을 바꾼다

객체가 그대로라면 수백 바이트짜리 응답만 오갑니다. 2 MB 이미지라면 16,000,000비트를 싣는 전송 시간과 그만큼의 대역폭을 아낍니다. 요청마다 원 서버에 묻는 것도 낭비이므로, 원 서버는 처음 객체를 줄 때 얼마 동안 신선하다고 봐도 되는지를 함께 알려 줍니다. 캐시는 그 기간이 지난 객체에 대해서만 조건부 GET을 보냅니다.

2. HTTP/2와 HTTP/3

HTTP/1.1은 TCP 연결 하나로 요청 여러 개를 파이프라이닝할 수 있게 했습니다. 하지만 서버는 요청이 온 순서대로 응답합니다. 이런 선착순 스케줄링을 FCFS(first-come-first-served)라고 합니다. 그러면 작은 객체가 앞의 큰 객체 뒤에서 하염없이 기다리게 됩니다. 줄 맨 앞의 큰 객체가 뒤를 모두 막는 이 현상을 HOL 블로킹(head-of-line blocking)이라고 합니다.

HTTP/2는 메서드, 상태 코드, 헤더 필드 대부분을 HTTP/1.1과 같이 두고, 서버가 객체를 보내는 방식을 바꿨습니다.

  • 프레임으로 나눠 섞어 보내기 — 객체를 작은 프레임(frame)으로 나누고, 여러 객체의 프레임을 번갈아 보냅니다. 큰 객체가 작은 객체를 오래 막지 못합니다.
  • 우선순위 — 보내는 순서를 FCFS로 고정하지 않고 클라이언트가 정한 객체 우선순위에 따라 정할 수 있습니다.
  • 서버 푸시(server push) — 클라이언트가 아직 요청하지 않은 객체도 보낼 수 있습니다. HTML에 이미지가 링크되어 있으면, 브라우저가 HTML을 읽고 이미지를 요청하기 전에 서버가 먼저 보냅니다.

문제 1

클라이언트가 큰 객체 O1과 작은 객체 O2, O3, O4를 이 순서로 요청합니다. 프레임으로 나누면 O1은 6개, O2는 1개, O3는 2개, O4는 1개이고, 프레임 하나를 보내는 데 1단위 시간이 듭니다. (가) FCFS로 보낼 때 (나) 아직 끝나지 않은 객체들의 프레임을 O1, O2, O3, O4 순서로 하나씩 돌아가며 보낼 때, 각 객체가 다 도착하는 시각과 평균을 구하십시오.

(가) O1이 6에 끝나고, O2는 7, O3는 9, O4는 10에 끝납니다. 평균은 (6 + 7 + 9 + 10) / 4 = 8입니다. (나) 1에 O1, 2에 O2를 보내 O2가 끝나고, 3에 O3, 4에 O4를 보내 O4가 끝납니다. 다음 바퀴에서 5에 O1, 6에 O3를 보내 O3가 끝나고, 남은 O1 프레임 4개가 7부터 10까지 나갑니다. 끝나는 시각은 O1 10, O2 2, O3 6, O4 4이고 평균은 (10 + 2 + 6 + 4) / 4 = 5.5입니다. 큰 객체는 4단위 늦어지지만 작은 객체 셋이 훨씬 빨리 도착해 평균이 줄어듭니다.

HTTP/3

HTTP/2도 모든 객체를 TCP 연결 하나로 보냅니다. TCP는 데이터를 순서대로 전달하므로, 패킷 하나를 잃으면 그것을 다시 받을 때까지 뒤의 데이터를 응용에 넘기지 않습니다. 잃은 패킷과 상관없는 객체까지 멈춥니다. 응용 계층의 HOL 블로킹은 줄였지만 전송 계층의 HOL 블로킹이 남은 것입니다. 또 순수한 TCP 연결에는 보안이 없습니다.

HTTP/3는 TCP를 쓰지 않습니다. UDP 위에서 동작하는 QUIC 프로토콜을 쓰고, 그 위에 보안과 객체별 오류 제어, 혼잡 제어를 더합니다. 한 객체의 패킷을 잃어도 다른 객체는 계속 전달됩니다. QUIC의 동작은 전송 계층에서 다룹니다.

3. 전자우편의 세 구성 요소

전자우편은 오래된 응용이지만 지금도 널리 씁니다. 구성 요소는 셋입니다.

구성 요소하는 일
사용자 에이전트 (user agent)메일을 쓰고, 고치고, 읽는 프로그램. 휴대폰 메일 앱이나 PC 메일 프로그램이 해당한다. 메일을 저장하지 않고, 받는 사람의 에이전트로 직접 보내지도 않는다
메일 서버 (mail server)사용자마다 들어온 메일을 담는 메일함(mailbox)과, 아직 보내지 못한 메일이 기다리는 메시지 큐(message queue)를 둔다
SMTP (Simple Mail Transfer Protocol)메일 서버 사이에서 메일을 옮기는 프로토콜

메일 서버를 두는 이유는 사용자가 늘 온라인이 아니기 때문입니다. 사용자 에이전트끼리 직접 보내려면 양쪽이 동시에 켜져 있어야 하는데, 보내는 쪽은 받는 사람의 휴대폰이 켜져 있는지 알 수 없습니다. 늘 켜져 있는 메일 서버가 대신 받아 두면 받는 사람은 아무 때나 가져가면 됩니다.

SMTP에도 클라이언트와 서버가 있습니다. 메일을 보내는 메일 서버가 클라이언트, 받는 메일 서버가 서버입니다. 같은 기계가 보낼 때는 클라이언트, 받을 때는 서버가 됩니다.

민지가 준호에게 메일을 보내기까지

  1. 민지가 사용자 에이전트로 junho@example.net 앞으로 메일을 씁니다.
  2. 민지의 에이전트가 메일을 민지의 메일 서버로 보냅니다. 메일은 메시지 큐에 들어갑니다.
  3. 민지의 메일 서버가 SMTP 클라이언트로서 준호의 메일 서버와 TCP 연결을 엽니다.
  4. 그 연결로 메일을 보냅니다.
  5. 준호의 메일 서버가 메일을 준호의 메일함에 넣습니다.
  6. 준호가 나중에 에이전트를 열어 메일을 읽습니다. 그동안 준호가 오프라인이어도 메일은 메일함에서 기다립니다.

SMTP는 중간 메일 서버를 거치지 않고 보내는 서버에서 받는 서버로 곧바로 보냅니다(direct transfer). 받는 서버가 꺼져 있으면 메일은 보내는 서버의 큐에 남아 있다가 나중에 다시 시도됩니다.

4. SMTP의 대화와 메일 메시지 형식

SMTP는 메일이 빠지거나 깨지면 안 되므로 TCP를 쓰고, 서버는 25번 포트를 씁니다. 전송은 인사(handshaking), 메시지 전송, 종료(closure) 세 단계로 이루어집니다. HTTP처럼 명령과 응답을 주고받는 방식이고, 명령은 ASCII 텍스트, 응답은 상태 코드와 문구입니다. 아래는 TCP 연결이 맺어진 뒤 오가는 대화의 예입니다. S는 받는 메일 서버, C는 보내는 메일 서버입니다.

S: 220 mail.example.net
C: HELO example.org
S: 250 Hello example.org
C: MAIL FROM: <minji@example.org>
S: 250 OK
C: RCPT TO: <junho@example.net>
S: 250 OK
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: The meeting moved to 3 pm.
C: Please bring the report.
C: .
S: 250 OK: queued
C: QUIT
S: 221 Bye
  • 받는 서버가 먼저 220으로 인사하며 대화를 시작합니다.
  • MAIL FROM과 RCPT TO로 보내는 사람과 받는 사람을 알립니다.
  • DATA는 이제 본문을 보내겠다는 명령입니다. 서버가 354로 답하면 클라이언트가 본문을 한 줄씩 보냅니다.
  • 마침표 하나만 있는 줄이 본문의 끝입니다. 줄바꿈 문자까지 쓰면 CRLF.CRLF입니다.
  • 메일이 여러 통이면 같은 연결로 이어서 보냅니다. SMTP는 지속 연결을 씁니다. 다 보내면 QUIT으로 연결을 닫습니다.

SMTP와 HTTP

HTTPSMTP
방향pull. 클라이언트가 서버에서 객체를 끌어온다push. 보내는 서버가 받는 서버로 밀어 넣는다
객체 담기응답 메시지 하나에 객체 하나여러 객체를 multipart 메시지 하나에 담는다
공통점ASCII 명령과 응답, 상태 코드ASCII 명령과 응답, 상태 코드

메일 메시지 형식

SMTP(RFC 5321)가 메일을 주고받는 절차라면, RFC 5322는 메일 메시지 자체의 문법을 정합니다. 메시지는 헤더와 본문으로 나뉘고, 빈 줄 하나가 둘을 가릅니다. 헤더에는 From:, To:, Subject: 같은 줄이 들어갑니다. 이 줄들은 메시지 안의 내용이고, SMTP 명령 MAIL FROM, RCPT TO와는 별개입니다. 편지 봉투에 쓰는 주소와 편지지 첫머리에 쓰는 받는 이가 따로 있는 것과 같습니다.

SMTP는 헤더와 본문이 모두 7비트 ASCII여야 합니다. 한글이나 사진 첨부 파일은 그대로 보낼 수 없습니다. 그래서 ASCII가 아닌 데이터를 ASCII 문자로 바꿔 싣고, 어떤 방식으로 바꿨는지 알리는 헤더 줄을 더합니다. 받는 쪽은 그 헤더를 보고 원래 내용으로 되돌립니다. 이 확장을 MIME(Multipurpose Internet Mail Extensions)이라고 합니다.

5. 메일을 가져오는 프로토콜

메일이 지나는 구간은 셋이고, SMTP는 앞의 두 구간에만 씁니다.

구간프로토콜
보내는 사람의 에이전트 → 보내는 사람의 메일 서버SMTP
보내는 사람의 메일 서버 → 받는 사람의 메일 서버SMTP
받는 사람의 메일 서버 → 받는 사람의 에이전트메일 접근 프로토콜 (POP3, IMAP, HTTP)

마지막 구간에 SMTP를 쓸 수 없는 이유는 방향 때문입니다. SMTP는 밀어 넣는 프로토콜인데, 받는 사람이 언제 온라인인지 서버는 알 수 없습니다. 받는 사람이 원할 때 서버에서 끌어와야 하므로 동작 순서가 다른 프로토콜이 필요합니다.

  • POP3(Post Office Protocol version 3) — 단순하고 기능이 적습니다. 메일을 내려받는 데 집중합니다.
  • IMAP(Internet Mail Access Protocol) — 메일을 서버에 둔 채로 가져오고, 지우고, 폴더로 정리합니다. 여러 기기에서 같은 메일함을 볼 수 있습니다.
  • HTTP — 웹 브라우저로 메일을 보는 웹 메일입니다. 브라우저와 웹 서버 사이는 HTTP이고, 그 뒤에서 메일 서버끼리는 여전히 SMTP로 메일을 보냅니다.

메일 프로그램에 계정을 설정할 때 받는 서버와 보내는 서버를 따로 적는 이유도 이것입니다. 받는 서버 주소는 IMAP이나 POP3 서버를, 보내는 서버 주소는 SMTP 서버를 가리킵니다.

6. DNS — 이름을 주소로 바꾸는 시스템

웹 서버에 접속하려면 서버의 IP 주소가 필요합니다. 하지만 사람은 숫자 주소를 외우지 못합니다. 전화를 걸 때 번호를 외우지 않고 연락처에서 이름을 찾는 것처럼, 인터넷에서도 이름으로 찾습니다. 인터넷의 호스트에는 식별자가 둘 있습니다.

식별자예누가 쓰나
IP 주소 (32비트)203.0.113.25네트워크 계층이 데이터그램의 주소로 쓴다
호스트 이름 (hostname)www.example.com사람이 쓴다

DNS(Domain Name System)는 둘을 잇습니다. DNS는 여러 이름 서버(name server)를 계층으로 엮은 분산 데이터베이스이고, 동시에 호스트와 이름 서버가 대화해 이름을 주소로 바꾸는(resolve) 응용 계층 프로토콜입니다. IP 주소는 네트워크 계층의 것이지만, 그 주소를 찾아 주는 DNS는 엣지의 호스트와 서버에서 도는 응용입니다. 인터넷의 중요한 기능 하나가 코어의 라우터 대신 엣지의 응용으로 구현되어 있습니다.

브라우저에 www.example.com을 치면 이런 순서로 진행됩니다. 브라우저가 URL에서 호스트 이름을 뽑아 같은 컴퓨터의 DNS 클라이언트에 넘깁니다. DNS 클라이언트가 DNS 서버에 그 이름의 주소를 묻는 질의(query)를 보내고 응답(reply)을 받습니다. 주소를 얻은 뒤에야 브라우저가 그 주소의 80번 포트로 TCP 연결을 열고 HTTP 요청을 보냅니다.

DNS가 주는 서비스

  • 호스트 이름을 IP 주소로 변환 — 가장 기본이 되는 서비스입니다.
  • 호스트 별칭(host aliasing) — 길고 복잡한 실제 이름인 정식 이름(canonical name) 대신 짧은 별칭(alias)을 쓰게 하고, 별칭에 대응하는 정식 이름을 알려 줍니다.
  • 메일 서버 별칭(mail server aliasing) — 메일 주소에는 example.com처럼 단순한 도메인을 쓰고, 실제 메일 서버의 복잡한 이름은 DNS가 찾아 줍니다.
  • 부하 분산(load distribution) — 큰 사이트는 같은 웹 서버를 여러 대 복제해 둡니다. 이름 하나에 IP 주소 여러 개가 대응하고, DNS는 주소 목록 전체를 돌려주되 응답마다 순서를 돌립니다. 클라이언트는 보통 맨 앞 주소로 접속하므로 요청이 여러 서버로 나뉩니다.

한 곳에 모으지 않는 이유

DNS 서버를 하나만 두고 모두 거기에 묻는 중앙집중식 설계는 단순하지만 버티지 못합니다. 그 서버가 죽으면 전 세계의 이름 풀이가 멈추는 단일 장애 지점(single point of failure)이 됩니다. 모든 질의가 한 서버로 몰립니다. 서버에서 먼 곳의 사용자는 질의마다 긴 전파 지연을 겪습니다. 새 호스트와 주소 변경을 거대한 데이터베이스 하나에서 모두 관리해야 합니다. 사용자가 늘수록 이 문제가 모두 커지므로 이 설계는 확장되지 않습니다(doesn't scale).

7. 루트, TLD, 책임 서버, 그리고 로컬 DNS

실제 DNS는 세 단계 계층으로 나뉘어 전 세계에 흩어져 있습니다.

단계아는 것운영
루트 이름 서버 (root)각 최상위 도메인을 맡은 TLD 서버가 어디 있는지 안다논리적 주소는 13개이고, 각각이 전 세계에 여러 대 복제되어 있다. ICANN이 루트 도메인을 관리한다
TLD 서버 (top-level domain).com, .org, .edu 같은 일반 도메인이나 .kr, .jp 같은 국가 도메인 하나를 맡아, 그 아래 각 조직의 책임 서버가 어디 있는지 안다도메인마다 다른 기관이 맡는다
책임 DNS 서버 (authoritative)그 조직 호스트들의 이름과 IP 주소의 공식 대응을 안다조직이 직접 운영하거나 서비스 업체에 맡긴다

이름은 오른쪽에서 왼쪽으로 읽습니다. www.example.com이라면 루트가 .com을 보고 .com TLD 서버를 가리키고, .com 서버가 example.com을 보고 example.com의 책임 서버를 가리키고, 책임 서버가 www.example.com의 IP 주소를 줍니다. 루트와 TLD 서버는 최종 주소를 모르고 다음에 물을 곳만 압니다. 어느 서버도 전부를 알지 못하고 단계마다 일부만 압니다. 루트 서버는 이름을 풀지 못한 이름 서버가 마지막에 찾는 곳이라 인터넷이 동작하는 데 꼭 필요하고, DNSSEC으로 응답의 출처와 무결성을 확인할 수 있게 합니다.

로컬 DNS 서버

세 단계 어디에도 속하지 않지만 실제로 가장 먼저 만나는 서버가 로컬 DNS 서버(local DNS name server)입니다. 가정용 ISP, 회사, 대학마다 하나씩 있고 기본 이름 서버(default name server)라고도 부릅니다. 호스트의 DNS 질의는 루트로 가지 않고 로컬 DNS 서버로 갑니다. 로컬 서버는 최근에 찾은 이름과 주소를 캐시에 두었다가 바로 답하고, 모르면 호스트를 대신해 계층 안으로 질의를 보냅니다. 웹 캐시의 프록시 서버와 같은 자리입니다.

8. 반복 질의와 재귀 질의, 그리고 DNS 캐싱

대학 기숙사의 노트북이 cs.example.edu의 주소를 찾는다고 합시다. 로컬 DNS 서버가 질의를 처리하는 방식은 두 가지입니다.

반복 질의(iterated query)에서는 질의를 받은 서버가 답을 찾아 주지 않고 "나는 모르니 이 서버에 물어보라"며 다음 서버의 이름을 돌려줍니다.

  1. 노트북이 로컬 DNS 서버에 묻습니다.
  2. 로컬 DNS가 루트에 묻고, 루트는 .edu TLD 서버를 알려 줍니다.
  3. 로컬 DNS가 .edu TLD 서버에 묻고, TLD는 example.edu의 책임 서버를 알려 줍니다.
  4. 로컬 DNS가 책임 서버에 묻고 IP 주소를 받습니다.
  5. 로컬 DNS가 노트북에 주소를 전합니다.

여기서 로컬 DNS와 루트, TLD, 책임 서버 사이는 반복 질의입니다. 노트북과 로컬 DNS 사이는 재귀 질의입니다. 노트북은 답을 통째로 로컬 DNS에 맡기기 때문입니다.

재귀 질의(recursive query)에서는 질의를 받은 서버가 직접 다음 서버에 묻고 답을 받아 돌려줍니다. 루트가 TLD에 묻고, TLD가 책임 서버에 묻고, 답이 거꾸로 내려옵니다. 이름 풀이의 부담을 질의받은 서버가 집니다. 모든 질의가 상위 계층을 거치는데 루트와 TLD가 매번 아래에 묻고 기다려야 하니 상위 서버에 부하가 몰립니다. 그래서 대부분 반복 방식을 씁니다.

DNS 캐싱

이름 서버는 한 번 알아낸 대응을 캐시해 두고, 같은 이름의 질의가 다시 오면 상위 서버에 묻지 않고 바로 답합니다. 캐시 항목은 TTL(time to live)만큼 시간이 지나면 지워집니다. TLD 서버들의 주소는 대개 로컬 DNS에 캐시되어 있어서 루트 서버는 생각만큼 자주 불리지 않습니다.

캐시 항목은 낡았을 수 있습니다. 어떤 호스트가 IP 주소를 바꿔도, 그 이름을 캐시한 서버들의 TTL이 모두 끝날 때까지 인터넷 전체가 바뀐 주소를 알지 못할 수 있습니다. DNS의 이름 풀이는 최선 노력(best-effort)입니다.

문제 2

노트북과 로컬 DNS 사이의 RTT는 4 ms이고, 로컬 DNS와 다른 모든 DNS 서버 사이, 그리고 DNS 서버끼리의 RTT는 30 ms입니다. 반복 질의를 쓰고 전송 시간은 무시합니다. (가) 어느 서버에도 캐시가 없을 때 (나) 로컬 DNS가 .edu TLD 서버의 주소를 캐시하고 있을 때 (다) 로컬 DNS가 찾는 이름의 주소 자체를 캐시하고 있을 때, 노트북이 주소를 받기까지 걸리는 시간은 각각 얼마입니까.

(가) 노트북과 로컬 DNS 왕복 4 ms에, 로컬 DNS가 루트, TLD, 책임 서버와 한 번씩 왕복하는 3 × 30 ms를 더해 94 ms입니다. 재귀 질의로 바꿔도 왕복 수가 같으므로 같은 조건에서는 94 ms입니다. (나) 루트에 묻는 왕복을 건너뛰어 4 + 2 × 30 = 64 ms입니다. (다) 로컬 DNS가 바로 답하므로 4 ms입니다. 캐시가 계층의 위쪽 단계를 하나씩 건너뛰게 해 줍니다.

9. DNS 레코드와 도메인 등록

DNS 데이터베이스에 담기는 단위는 자원 레코드(RR, resource record)입니다. 레코드 하나는 네 필드로 이루어집니다.

(name, value, type, ttl)

ttl은 앞에서 본 캐시 수명이고, name과 value의 뜻은 type에 따라 달라집니다.

typenamevalue쓰임
A호스트 이름IP 주소이름을 주소로 바꾸는 기본 레코드
NS도메인 (예: example.com)그 도메인의 책임 이름 서버의 호스트 이름질의를 책임 서버로 넘길 때 쓴다
CNAME별칭정식 이름호스트 별칭
MX메일 도메인그 도메인의 메일 서버 이름메일 서버 별칭

예를 들어 www.example.com이 실제로는 web-03.seoul.example.com이라는 서버라면 (www.example.com, web-03.seoul.example.com, CNAME) 레코드를 둡니다.

새 도메인을 DNS에 올리기

새로 생긴 회사가 example.com이라는 이름을 쓰려 한다고 합시다.

  1. DNS 등록 기관(DNS registrar)에 example.com을 등록하면서 자기 책임 이름 서버의 이름과 IP 주소를 알립니다. 서버는 보통 주 서버와 보조 서버(primary, secondary) 둘을 둡니다.
  2. 등록 기관이 .com TLD 서버에 레코드 두 개를 넣습니다. (example.com, ns1.example.com, NS)는 이 도메인의 책임 서버 이름을, (ns1.example.com, 203.0.113.10, A)는 그 서버의 주소를 알려 줍니다.
  3. 회사는 203.0.113.10에 책임 이름 서버를 직접 세우고, 그 안에 웹 서버를 가리키는 www.example.com의 A 레코드와 메일 서버를 가리키는 example.com의 MX 레코드를 넣습니다.

이제 누군가 www.example.com을 찾으면 루트가 .com TLD 서버를 가리키고, .com 서버가 NS와 A 레코드로 책임 서버를 가리키고, 책임 서버가 A 레코드로 웹 서버의 주소를 줍니다.

정리

캐시는 If-Modified-Since 헤더를 붙인 조건부 GET으로 사본이 최신인지 확인하고, 바뀌지 않았으면 304 응답만 받습니다. HTTP/2는 객체를 프레임으로 나눠 섞어 보내 응용 계층의 HOL 블로킹을 줄였고, HTTP/3는 UDP 위의 QUIC으로 옮겨 전송 계층의 HOL 블로킹까지 피합니다. 전자우편은 사용자 에이전트, 메일 서버, SMTP로 이루어지고, SMTP는 메일 서버까지 메일을 밀어 넣으며, 받는 사람은 POP3, IMAP, HTTP로 메일을 끌어옵니다. DNS는 루트, TLD, 책임 서버가 계층을 이룬 분산 데이터베이스이고, 로컬 DNS 서버가 대개 반복 질의로 이름을 풀며 TTL 동안 결과를 캐시합니다. 데이터베이스에는 A, NS, CNAME, MX 같은 자원 레코드가 들어 있습니다.

dev-news학습 노트소개개인정보 처리