Đ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ố:
- Bạn tra danh bạ để tìm số điện thoại từ tên công ty.
- 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.
- 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ã.
- 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.
- 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ện | Networking | Chặng |
|---|---|---|
| Tra danh bạ tìm số | DNS phân giải tên miền ra IP | 1 |
| Quay số, xác nhận đường dây | TCP 3-way handshake | 2 |
| Chuyển sang đường mã hoá | TLS handshake (HTTPS) | 3 |
| Nói yêu cầu, nghe trả lời | HTTP request / response | 4 |
| Ghi lại, xử lý | Browser parse và render | 5 |
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.
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:

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:
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:

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.
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.
TCP mở kết nối bằng đúng ba gói tin, gọi là 3-way handshake:

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:
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á
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:
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.
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:
GET / HTTP/2
Host: google.com
User-Agent: Mozilla/5.0 ...
Accept: text/html
Server trả về response:
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ặng | Lần đầu (nguội) | Lần sau (ấm) |
|---|---|---|
| DNS | 20–120 ms | ~0 (đã cache) |
| TCP handshake | 1 RTT | 0 (tái dùng kết nối keep-alive) |
| TLS handshake | 1 RTT | 0 (session resumption) |
| HTTP | thời gian server xử lý | thường ~0 nếu cache HTTP |
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
Đọc khi muốn đi tới tận gốc từng chặng:
- RFC 1034 / 1035 — DNS: hệ thống tên miền và cơ chế phân giải.
- RFC 9293 — TCP: bản hợp nhất của TCP, gồm 3-way handshake.
- RFC 8446 — TLS 1.3: handshake 1-RTT.
- RFC 9110 — HTTP Semantics: method, status code, header.
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ả.
digsoi chặng 1,sssoi chặng 2,curl -vsoi được cả chặng 3 lẫn 4 trong một lệnh;curl -win 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.
pingthô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
- Q1Vì 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ì?
- Q2Mộ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?
- Q3Vì 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'?
- Q4TLS 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?
- Q5Bạ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.
Module 1 — Từ URL đến Response: tổng quan
Bài tiếpMô hình TCP/IP 4 tầng — đủ dùng thay cho OSI 7
Thảo luận & góp ý
Hỏi đáp về bài này