Nền tảng Mạng máy tính
2/17
Bài 2 / 17~13 phútCó videoTừ URL đến ResponseMiễn phí… lượt xem

Điều gì xảy ra khi bạn gõ google.com và nhấn Enter?

Trace một HTTP request qua 5 chặng DNS, TCP, TLS, HTTP, render: mỗi chặng tốn mấy RTT, vì sao lần đầu chậm lần sau nhanh, sự cố nhìn vào chặng nào.

TL;DR: Giữa lúc nhấn Enter và lúc trang hiện ra, request đi qua 5 chặng nối tiếp: DNS biến tên miền thành IP, TCP bắt tay mở kết nối, TLS dựng kênh mã hoá, HTTP gửi yêu cầu nhận nội dung, rồi trình duyệt render. Bốn chặng đầu là bốn lượt khứ hồi mạng (RTT) xếp hàng dọc, lỗi ở chặng trước chặn mọi chặng sau. Lần load đầu chậm vì phải đi đủ bốn lượt; lần sau nhanh vì gần như chặng nào cũng có cache. Debug mạng là hỏi đúng một câu: request đang kẹt ở chặng nào?

Bạn gõ google.com, nhấn Enter. Khoảng 200 ms sau, trang hiện ra. Nhanh tới mức tưởng trình duyệt "biết" Google ở đâu và gọi thẳng tới.

Thực tế trong 200 ms đó có năm việc khác nhau chạy trên nhiều máy, mỗi việc trả lời một câu hỏi riêng: máy đó ở địa chỉ nào? mở kênh tới nó thế nào? làm sao kênh an toàn? gửi yêu cầu gì? nhận về rồi vẽ ra sao? Bạn không cần thuộc 7 tầng OSI, nhưng khi production ném ECONNRESET, khi trang chậm 3 giây không rõ lý do, khi cert hết hạn, bạn cần biết request đang kẹt ở chặng nào. Bài này đi một vòng qua cả năm chặng để dựng bản đồ đó; mỗi chặng về sau có một module riêng phóng to.

1. Analogy — gọi điện tới một tổng đài công ty

Hình dung bạn muốn gọi cho một tập đoàn lớn mà chỉ biết tên, không biết số:

  1. Bạn tra danh bạ để tìm số điện thoại từ tên công ty.
  2. Bạn quay số, chờ tổng đài nhấc máy, hai bên "alo, nghe rõ không?" để chắc đường dây thông.
  3. Vì nội dung nhạy cảm, hai bên chuyển sang đường dây mã hoá và thống nhất một bộ mật mã.
  4. Bạn nói yêu cầu ("cho tôi gặp phòng kinh doanh"), nhận lại câu trả lời.
  5. Bạn ghi lại và xử lý thông tin nhận được.

Một HTTP request đi đúng năm bước đó:

Gọi điệnNetworkingChặng
Tra danh bạ tìm sốDNS phân giải tên miền ra IP1
Quay số, xác nhận đường dâyTCP 3-way handshake2
Chuyển sang đường mã hoáTLS handshake (HTTPS)3
Nói yêu cầu, nghe trả lờiHTTP request / response4
Ghi lại, xử lýBrowser parse và render5
💡 Cách nhớ

Thứ tự luôn là địa chỉ → kết nối → bảo mật → nội dung → hiển thị. Tra danh bạ sai số thì mọi bước sau vô nghĩa; mạng cũng vậy, lỗi DNS chặn tất cả.

2. Toàn cảnh: năm chặng trên một dòng thời gian

Cả câu chuyện chỉ có ba nhân vật: trình duyệt của bạn, hệ thống DNS, và server đích.

Browser
Browser
→
DNS
DNS
→
Server
Server

Dưới đây là một lần load https://google.com từ con số 0, chưa cache gì. Hãy đếm số mũi tên trước khi byte HTML đầu tiên về tới:

Sơ đồ tuần tự ba cột DNS resolver, trình duyệt và server google.com: chặng 1 trình duyệt hỏi DNS và nhận 142.250.x.x; chặng 2 SYN, SYN-ACK, ACK tốn 1 RTT; chặng 3 ClientHello, ServerHello kèm cert, Finished tốn 1 RTT; chặng 4 GET rồi 200 OK kèm HTML tốn 1 RTT; chặng 5 trình duyệt render — tổng bốn lượt khứ hồi trước byte HTML đầu tiên

Mỗi cặp mũi tên đi-về là một RTT (Round-Trip Time), thời gian gói tin tới server rồi quay lại. Trong nước RTT cỡ 10–30 ms, đi quốc tế 150–300 ms. Bốn chặng đầu xếp hàng dọc, chặng sau phải đợi chặng trước xong, nên bốn RTT đó cộng dồn chứ không chạy song song. Hãy nhớ con số bốn này; cuối bài nó giải thích vì sao lần load thứ hai nhanh hơn hẳn lần đầu.

Giờ đi từng chặng, bắt đầu từ câu hỏi đầu tiên: google.com ở địa chỉ nào?

3. Chặng 1 — DNS: tên miền thành địa chỉ IP

Máy tính không định tuyến theo tên google.com; chúng định tuyến theo địa chỉ IP (ví dụ 142.250.190.78). DNS (Domain Name System) là hệ thống tra cứu biến tên thành IP. Bạn tự chạy thử bằng dig:

Bash
dig google.com +short
# 142.250.190.78

Trình duyệt không hỏi thẳng "tổng đài gốc" mỗi lần. Nó tra qua một chuỗi cache, hỏi tới đâu thấy kết quả còn hạn thì dừng:

Chuỗi cache DNS hỏi lần lượt: cache trình duyệt, cache hệ điều hành, router, recursive resolver của ISP, rồi mới tới root, TLD và authoritative — tầng nào còn bản ghi trong hạn TTL thì dừng ở đó, lần đầu vào domain lạ mất trên 100 ms vì phải đi hết chuỗi

Lần đầu vào một domain lạ có thể mất hơn 100 ms vì phải đi tới cuối chuỗi; lần sau gần như 0 ms vì đã cache. Chính vì "gần như 0" đó mà DNS hay bị bỏ qua khi debug, trong khi một resolver chậm đủ làm trang "đơ" vài giây.

📌 TTL — vì sao đổi DNS phải chờ

Mỗi bản ghi DNS có TTL (Time To Live), số giây được phép cache. Đặt TTL 3600 nghĩa là sau khi đổi IP, vẫn có client dùng IP cũ tới một giờ vì họ còn bản cache. Trước khi chuyển server, người ta thường hạ TTL xuống trước vài ngày.

Có IP rồi. Nhưng biết số điện thoại chưa phải là đang nói chuyện; còn phải quay số.

4. Chặng 2 — TCP handshake: bắt tay 3 bước

Hai đầu, client và server, phải bắt tay mở kết nối trước khi gửi bất kỳ byte dữ liệu nào.

Client
Client
⇄
Server
Server

TCP mở kết nối bằng đúng ba gói tin, gọi là 3-way handshake:

Bắt tay ba bước giữa client và server: client gửi SYN với seq bằng x, server trả SYN-ACK với seq bằng y và ack bằng x cộng 1, client gửi ACK với ack bằng y cộng 1, kết nối mở — tốn đúng 1 RTT trước byte dữ liệu đầu tiên

Ba bước này để cả hai phía đồng ý mở kết nối và đồng bộ số thứ tự gói (sequence number), thứ TCP dùng sau này để đảm bảo dữ liệu tới đủ và đúng thứ tự. Tốn đúng 1 RTT trước byte dữ liệu đầu tiên.

Backend dev phải quan tâm vì mỗi handshake tốn tài nguyên ở server, và khi đóng kết nối lại sinh ra trạng thái TIME_WAIT, nguồn cơn của lỗi "hết port" trên server tải cao (module TCP có hẳn một bài về nó). Xem trạng thái các kết nối bằng:

Bash
ss -tan | head
# State    Recv-Q  Send-Q   Local Address:Port   Peer Address:Port
# ESTAB    0       0        10.0.0.5:443         203.0.113.7:51324
# TIME-WAIT 0      0        10.0.0.5:443         203.0.113.7:51210

Thử ngẫmserver đang tải cao và ss -tan liệt kê hàng nghìn dòng TIME-WAIT. Trạng thái đó sinh ra từ chặng mở kết nối bạn vừa đọc, hay từ lúc đóng kết nối, và vì sao nó dẫn tới lỗi "hết port"?

Kết nối đã thông. Nhưng URL bắt đầu bằng https, nghĩa là chưa được nói gì trên đường dây trần này.

5. Chặng 3 — TLS: thiết lập kênh mã hoá

Firewall
Bảo vệ
Kênh mã hoá
Kênh mã hoá

Sau khi TCP mở kết nối, hai bên chạy thêm TLS handshake để làm hai việc: xác thực server đúng là google.com qua certificate, và thống nhất một khoá mã hoá chung cho phiên này. Với TLS 1.3, handshake tốn thêm 1 RTT; TLS 1.2 tốn 2 RTT, nên nâng cấp TLS là một cách làm web nhanh hơn mà không đụng tới code.

Bạn quan sát cả ba chặng vừa đi qua, cộng chặng tiếp theo, chỉ bằng một lệnh curl:

Bash
curl -v https://google.com -o /dev/null
# * Connected to google.com (142.250.190.78) port 443    <- DNS + TCP xong
# * TLS handshake, Done                                  <- TLS xong
# > GET / HTTP/2                                          <- chang 4 bat dau
# < HTTP/2 200

Cờ -v (verbose) in từng chặng theo thứ tự. Khi cert hết hạn hay trình duyệt báo "Not Secure", output dừng ngay ở dòng TLS, và bạn biết chính xác nó hỏng ở đâu mà chưa cần đọc log server.

⚠️ HTTPS không chỉ là 'mã hoá'

TLS giải quyết ba việc cùng lúc: mã hoá (người khác không đọc được), toàn vẹn (không bị sửa giữa đường), và xác thực (đúng server bạn nghĩ, không phải kẻ giả mạo). Thiếu xác thực thì mã hoá vô nghĩa: bạn có thể đang trao đổi mật mã rất an toàn với chính kẻ tấn công.

Ba RTT đã trôi qua, và vẫn chưa có byte nội dung nào được gửi.

6. Chặng 4 — HTTP: request và response

Kênh đã mở và an toàn. Trình duyệt gửi HTTP request thật sự để xin nội dung. Một request tối giản:

Plain Text
GET / HTTP/2
Host: google.com
User-Agent: Mozilla/5.0 ...
Accept: text/html

Server trả về response:

Plain Text
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: private, max-age=0

<!DOCTYPE html>...

Dòng đầu response mang status code: 200 là OK, 404 không tìm thấy, 500 server lỗi, 301 chuyển hướng. Phần lớn việc đọc lỗi production của backend dev là đọc đúng status code và header. Bạn "sống cùng" tầng này mỗi ngày, nên cả một module sau dành riêng cho nó.

7. Chặng 5 — Browser render (tóm tắt)

Nhận được HTML, trình duyệt parse ra cây DOM, phát hiện cần thêm CSS, JS, ảnh, và lặp lại chặng 1–4 cho từng tài nguyên đó. Một trang thường kéo hàng chục request con, nên HTTP/2 (multiplexing nhiều request trên một kết nối) tạo khác biệt lớn về tốc độ so với HTTP/1.1.

Render thuộc về frontend, khoá này chỉ điểm qua. Bốn RTT đếm được ở đầu bài đi đâu ở lần load thứ hai, mục sau ghép lại.

8. Vì sao lần đầu chậm, lần sau nhanh?

Ghép lại, ngân sách độ trễ một lần load "nguội" (chưa cache) so với lần "ấm" trông như sau:

ChặngLần đầu (nguội)Lần sau (ấm)
DNS20–120 ms~0 (đã cache)
TCP handshake1 RTT0 (tái dùng kết nối keep-alive)
TLS handshake1 RTT0 (session resumption)
HTTPthời gian server xử lýthường ~0 nếu cache HTTP
DNS cache
DNS cache
Cache
HTTP cache
CDN
CDN

Gần như mọi chặng đều có cache riêng, và cột bên phải gần như toàn số 0. Từ đó rút ra nguyên tắc tối ưu hiệu năng mạng: phần lớn không phải tăng băng thông, mà là bớt số RTT bằng cách tránh làm lại chặng đã làm: cache DNS, tái dùng kết nối TCP, resume phiên TLS, cache HTTP. Băng thông gấp đôi không rút ngắn được một RTT cố định; mỗi cache bạn bỏ lỡ là một RTT cộng thẳng vào độ trễ người dùng cảm nhận.

Thử ngẫmmột API bạn gọi luôn chậm thêm đúng ~200 ms mỗi lần, dù DNS đã cache lâu và HTTP cache lẫn keep-alive đều đã bật. Theo bảng trên, chặng nào còn chưa được "làm ấm"?

9. Pitfall — hiểu nhầm thường gặp

❌ Nhầm 1: "Trang chậm chắc do server yếu, cần thêm CPU." ✅ Server có thể trả byte đầu tiên trong 5 ms, nhưng nếu DNS resolver chậm 2 giây hoặc TLS handshake đi vòng quốc tế, người dùng vẫn chờ 2 giây. Luôn xác định chặng nào chậm trước khi tối ưu; curl -w in được thời gian từng chặng.

❌ Nhầm 2: "HTTPS chỉ làm chậm vì phải mã hoá." ✅ Chi phí mã hoá dữ liệu không đáng kể trên CPU hiện đại. Chi phí thật của HTTPS là handshake (thêm RTT), và nó được loại bỏ gần hết nhờ keep-alive và session resumption. Đổi lại, HTTP/2 (chỉ chạy trên HTTPS) thường làm trang nhanh hơn HTTP thuần.

❌ Nhầm 3: "ping được thì mạng ổn, lỗi phải do code." ✅ ping chỉ kiểm tra chặng định tuyến IP (ICMP), không đụng tới TCP, TLS hay HTTP. Ping thông mà app vẫn timeout là chuyện thường, vì lỗi nằm ở port bị firewall chặn, TLS sai cert, hay server không listen. Mỗi chặng phải debug bằng công cụ của chặng đó.

10. 📚 Deep Dive — tài liệu gốc

📚 RFC & spec chính thức

Đọc khi muốn đi tới tận gốc từng chặng:

Không cần đọc hết RFC để làm việc; chúng là nơi tra khi có tranh cãi "spec nói gì".

11. Tóm tắt

Checklist khi một request "có gì đó sai":

  • Hỏi đúng một câu trước: nó kẹt ở DNS, TCP, TLS hay HTTP? Chưa trả lời được thì chưa tối ưu gì cả.
  • dig soi chặng 1, ss soi chặng 2, curl -v soi được cả chặng 3 lẫn 4 trong một lệnh; curl -w in thời gian từng chặng.
  • Lần ấm gần như miễn phí bốn RTT đầu. Vẫn chậm ở lần ấm thì nghi server xử lý (HTTP) hoặc render, không phải DNS/TCP/TLS.
  • ping thông chỉ chứng minh tầng IP; nó không nói gì về cổng, cert hay app.

12. Tự kiểm tra

Tự kiểm tra
0/5 câu đã trả lời
  1. Q1
    Vì sao lần đầu vào một website thường chậm hơn rõ rệt so với những lần sau, dù server không đổi gì?
  2. Q2
    Một backend dev nói: 'tôi ping server thấy thông, nên lỗi timeout của app chắc chắn do code'. Lập luận này sai ở đâu?
  3. Q3
    Vì sao người ta thường nói tối ưu tốc độ mạng là 'giảm số RTT' chứ không phải 'tăng băng thông'?
  4. Q4
    TLS giải quyết ba vấn đề, không chỉ một. Đó là ba vấn đề gì, và vì sao thiếu phần xác thực thì mã hoá trở nên vô nghĩa?
  5. Q5
    Bạn đổi server sang IP mới, sửa bản ghi DNS xong nhưng nhiều người dùng vẫn vào IP cũ suốt nhiều giờ. Cơ chế nào gây ra, và cách phòng trước là gì?

Bài tiếp theo: Mô hình TCP/IP 4 tầng — đủ dùng thay cho OSI 7

Bài này có giúp bạn hiểu bản chất không?

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Thảo luận & góp ý

Hỏi đáp về bài này

Bài tiếp theo

Mô hình TCP/IP 4 tầng — đủ dùng thay cho OSI 7