Skip to main content

2.2 — Concept learning path

Summary

Module này có nhiều thuật ngữ rời rạc — DNS, TCP, TLS, HTTP, JSON, JWT, database, hosting — và học từng cái riêng lẻ rất dễ quên. Bài này là bản đồ nối tất cả lại bằng một ví dụ duy nhất chạy xuyên suốt: chuyện gì xảy ra khi bạn gõ crm.company.com và bấm Đăng nhập. Tám chặng, mỗi chặng ứng với một bài trong module. Cách học được khuyến nghị: đọc bài này trước, học từng bài, rồi quay lại đọc bài này lần nữa — lần hai bạn sẽ thấy các mảnh ghép vào đúng chỗ. Và thứ tự quan trọng: học từ trải nghiệm hằng ngày tới thuật ngữ kỹ thuật, không phải ngược lại.

Mục tiêu bài học​

Sau bài này bạn có thể:

  • Mô tả tám chặng của một request web.
  • Biết mỗi bài trong module ứng với chặng nào.
  • Chọn thứ tự học phù hợp với nền tảng của mình.
  • Nhận ra chặng nào gây lỗi khi có sự cố.

Nội dung bài học​

2.2.1 — Ví dụ xuyên suốt​

Tám chặng này xảy ra trong khoảng 200 mili giây, và mỗi chặng là một bài trong module.

2.2.2 — Từng chặng, học ở bài nào​

Chặng 1–2: gõ URL và phân giải DNS → bài 2.3

crm.company.com  ->  DNS resolver  ->  203.0.113.45

Trình duyệt không biết crm.company.com nằm ở đâu. Nó hỏi DNS — giống tra danh bạ điện thoại — để lấy địa chỉ IP.

Chặng 3: kết nối TCP → bài 2.3

Trình duyệt và server bắt tay ba bước để mở một kênh tin cậy. TCP đảm bảo dữ liệu tới đủ và đúng thứ tự.

Chặng 4: bắt tay TLS → bài 2.5

Hai bên trao đổi khoá để mã hoá. Đây là chữ S trong HTTPS. Không có nó, mật khẩu bạn gửi đi ai cũng đọc được trên đường truyền.

Chặng 5: request HTTP → bài 2.5 và bài 2.6

POST /api/auth/login HTTP/1.1
Host: crm.company.com
Content-Type: application/json

{ "email": "an@company.com", "password": "..." }

Đây là chỗ bạn sẽ làm việc nhiều nhất với tư cách backend engineer: method, đường dẫn, header, body, và mã trạng thái trả về.

Chặng 6: backend xử lý → bài 2.4

Server nhận request, phân tích, và quyết định làm gì. Đây là mô hình client–server: một bên hỏi, một bên trả lời.

Chặng 7: truy vấn database → bài 2.7

SELECT Id, PasswordHash FROM Users WHERE Email = @email;

Backend hỏi database xem tài khoản có tồn tại không và mật khẩu có khớp không.

Chặng 8: trả JWT → bài 2.8

{ "token": "eyJhbGciOiJIUzI1NiIs..." }

Từ các request sau, trình duyệt đính token này vào header Authorization để server biết bạn là ai mà không phải đăng nhập lại.

Và tất cả chạy ở đâu? → bài 2.9 và bài 2.10

2.2.3 — Chặng nào gây lỗi gì​

Bảng này hữu ích ngay cả khi bạn chưa học hết module — nó giúp khoanh vùng khi có sự cố:

Triệu chứngChặng có vấn đề
ERR_NAME_NOT_RESOLVEDDNS (chặng 2)
ERR_CONNECTION_REFUSEDTCP — server không chạy hoặc sai cổng (chặng 3)
ERR_CERT_AUTHORITY_INVALIDTLS — chứng chỉ sai hoặc hết hạn (chặng 4)
404 Not FoundHTTP — sai đường dẫn (chặng 5)
500 Internal Server ErrorBackend — lỗi trong code (chặng 6)
Timeout khi gọi APIDatabase chậm hoặc mất kết nối (chặng 7)
401 UnauthorizedToken thiếu, sai hoặc hết hạn (chặng 8)

Nguyên tắc chẩn đoán: mã lỗi cho biết chặng nào, và biết chặng nào tiết kiệm rất nhiều thời gian tìm kiếm (bài 2.12).

2.2.4 — Thứ tự học theo nền tảng​

Nếu bạn hoàn toàn mới với web: đọc theo đúng thứ tự 2.3 → 2.10. Mỗi bài dựa trên bài trước.

Nếu đã biết HTML/CSS/JavaScript: bắt đầu từ 2.5 (HTTP) và 2.6 (API và JSON) — hai bài gần với công việc backend nhất. Quay lại 2.3 và 2.4 khi cần.

Nếu đã làm frontend: 2.7 (database) và 2.8 (xác thực) là hai mảng bạn ít tiếp xúc nhất. Ưu tiên chúng.

Nếu chỉ có 2 giờ: 2.5 và 2.8. Hai bài này chiếm phần lớn công việc hàng ngày của một backend engineer.

2.2.5 — Học từ trải nghiệm tới thuật ngữ​

Cách học không hiệu quả:

Học thuộc: "DNS là hệ thống phân giải tên miền thành địa chỉ IP"
-> Nhớ được vài ngày, rồi quên

Cách học hiệu quả:

1. Mở terminal, gõ:  nslookup google.com
2. Thấy kết quả trả về một địa chỉ IP
3. Gõ địa chỉ IP đó vào trình duyệt — vẫn ra Google
4. "À, DNS là để khỏi phải nhớ dãy số này"
-> Hiểu, và không quên

Với mỗi khái niệm trong module, tìm một cách tự tay thử nó. Vài lệnh đáng biết ngay:

nslookup crm.company.com          # DNS trả về IP nào
curl -i https://example.com # Xem đầy đủ header phản hồi
ping google.com # Đo độ trễ mạng

Và công cụ quan trọng nhất: DevTools của trình duyệt, tab Network. Mọi thứ trong module này đều quan sát được ở đó — request, header, mã trạng thái, thời gian từng chặng.

2.2.6 — Rà lại code của bạn​

Danh sách rà soát trước khi sang Module 3

  • •Mô tả được tám chặng của một request web.
  • •Biết mã lỗi nào ứng với chặng nào.
  • •Đã tự chạy nslookup và curl ít nhất một lần.
  • •Mở được DevTools tab Network và đọc được một request.
  • •Phân biệt được HTTP và HTTPS khác nhau ở đâu.
  • •Giải thích được JWT dùng để làm gì.
  • •Biết database nằm ở chặng nào trong luồng.

Bài tập áp dụng​

Bài 1 — Lần theo luồng thật​

Mở DevTools trên một trang có đăng nhập, thực hiện đăng nhập, và xác định từng chặng trong tab Network.

Tiêu chí hoàn thành: bạn ánh xạ được tám chặng vào những gì DevTools hiện ra, và nhận ra có chặng không hiện ra ở đó.

Gợi ý và lời giải — Bài 1

Gợi ý. Bấm vào một request rồi mở tab Timing. Nó chia sẵn thời gian theo từng giai đoạn.

Lời giải — đọc bảng Timing của request đăng nhập:

POST https://crm.company.com/api/auth/login

Queueing 0,42 ms
Stalled 1,18 ms
DNS Lookup 24,00 ms <- chặng 2
Initial connection 48,00 ms <- chặng 3 (TCP)
SSL 31,00 ms <- chặng 4 (TLS, nằm trong Initial connection)
Request sent 0,21 ms <- chặng 5
Waiting (TTFB) 186,00 ms <- chặng 6 và 7
Content Download 12,00 ms <- chặng 8
---------
Total 271,81 ms

Ánh xạ tám chặng:

ChặngTrong DevToolsĐo được
1. Gõ URLQueueing, Stalled1,6 ms
2. DNSDNS Lookup24 ms
3. TCPInitial connection trừ SSL17 ms
4. TLSSSL31 ms
5. HTTP requestRequest sent0,2 ms
6. Backend xử lýWaiting (TTFB)186 ms
7. Databasecũng nằm trong Waitingkhông tách được
8. Trả JWTContent Download12 ms

Và đây là điều bài tập muốn bạn thấy: chặng 7 KHÔNG hiện ra riêng.

DevTools chỉ thấy tới biên của máy chủ.
Nó biết "máy chủ mất 186 ms", nhưng không biết trong 186 ms đó:
- bao nhiêu cho middleware xác thực
- bao nhiêu cho truy vấn database
- bao nhiêu cho việc băm mật khẩu
Băm mật khẩu đáng chú ý: BCrypt hoặc Argon2 CỐ TÌNH chậm,
thường 50–200 ms, để chống dò mật khẩu bằng vét cạn.
-> với endpoint đăng nhập, phần lớn TTFB có thể là băm mật khẩu,
không phải database.

Muốn tách chặng 6 và 7, phải đo từ phía máy chủ:

app.Use(async (ctx, next) =>
{
var sw = Stopwatch.StartNew();
await next();
ctx.Response.Headers["Server-Timing"] = $"app;dur={sw.Elapsed.TotalMilliseconds:F1}";
});
Header Server-Timing hiện THẲNG trong tab Timing của DevTools
-> nối được số liệu máy chủ với số liệu trình duyệt

Hai điều nữa quan sát được trong cùng tab Network:

1. Request thứ hai nhanh hơn hẳn.

Request 1: DNS 24 ms + connection 48 ms = 72 ms chi phí thiết lập
Request 2: DNS 0 ms + connection 0 ms = 0 ms

-> DNS đã nằm trong bộ nhớ đệm, kết nối được dùng lại (keep-alive)

2. Token đi đâu sau khi nhận được.

Xem request TIẾP THEO sau khi đăng nhập:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Hoặc, nếu dùng cookie:
Set-Cookie: .AspNetCore.Identity.Application=...; HttpOnly; Secure; SameSite=Lax
HttpOnly là khác biệt quan trọng: JavaScript KHÔNG đọc được cookie đó
-> một lỗ hổng XSS không lấy được phiên đăng nhập
-> token lưu trong localStorage thì ngược lại

Bài 2 — Thử DNS bằng tay​

Chạy nslookup cho ba tên miền bất kỳ, rồi thử truy cập bằng IP thay vì tên miền.

Tiêu chí hoàn thành: bạn thấy truy cập bằng IP trần không ra đúng trang, và giải thích được thứ gì mới thật sự chọn ra trang web.

Gợi ý và lời giải — Bài 2

Gợi ý. Một địa chỉ IP thường phục vụ hàng nghìn tên miền. Máy chủ dựa vào đâu để biết bạn muốn trang nào?

Lời giải — tra DNS:

for d in example.com github.com microsoft.com; do
echo "--- $d"; nslookup $d | grep -A3 "Non-authoritative"
done

Kết quả chạy thật:

--- example.com
Non-authoritative answer:
Name: example.com
Address: 172.66.147.243
Name: example.com
Address: 104.20.23.154

--- github.com
Non-authoritative answer:
Name: github.com
Address: 20.205.243.166

--- microsoft.com
Non-authoritative answer:
Name: microsoft.com
Address: 150.171.110.68
Name: microsoft.com
Address: 2603:1061:14:16b::1

Ba quan sát ngay từ đây:

1. example.com có HAI địa chỉ IPv4 -> cân bằng tải ở tầng DNS
2. microsoft.com có cả IPv4 lẫn IPv6 (bản ghi A và AAAA)
3. "Non-authoritative answer" nghĩa là câu trả lời lấy từ bộ nhớ đệm
của resolver, không phải hỏi thẳng máy chủ tên miền gốc

Giờ thử truy cập bằng IP:

curl -s -o /dev/null -w "IP trần: %{http_code}\n" http://172.66.147.243/
curl -s -o /dev/null -w "IP + Host header: %{http_code}\n" -H "Host: example.com" http://172.66.147.243/
curl -sk -o /dev/null -w "HTTPS bằng IP (bỏ qua chứng chỉ): %{http_code}\n" \
--resolve example.com:443:172.66.147.243 https://example.com/
curl -s -o /dev/null -w "HTTPS bằng IP trực tiếp: %{http_code} ssl=%{ssl_verify_result}\n" \
https://172.66.147.243/

Kết quả chạy thật:

IP trần:                          403
IP + Host header: 200
HTTPS bằng IP (bỏ qua chứng chỉ): 200
HTTPS bằng IP trực tiếp: 000 ssl=1

Bốn dòng này trả lời câu hỏi chính:

IP trần -> 403
Máy chủ nhận được request nhưng KHÔNG BIẾT bạn muốn trang nào
-> nó từ chối

IP + Host: example.com -> 200
Header Host là thứ CHỌN RA trang web
Nói cách khác: DNS chỉ đưa bạn TỚI ĐÚNG MÁY.
Header Host mới nói bạn muốn TRANG NÀO trên máy đó.
GET / HTTP/1.1
Host: example.com <- dòng này chọn trang web
Một máy chủ có thể phục vụ hàng nghìn tên miền trên cùng một IP.
Đây gọi là virtual hosting, và header Host là cơ chế duy nhất phân biệt chúng.

Và dòng thứ tư nói về HTTPS — nó còn chặt hơn:

https://172.66.147.243/ -> ssl_verify_result=1, kết nối THẤT BẠI

Chứng chỉ được cấp cho TÊN MIỀN example.com, không phải cho một địa chỉ IP.
-> trình duyệt so tên trong chứng chỉ với tên bạn gõ -> không khớp -> từ chối
Còn --resolve example.com:443:172.66.147.243 thì thành công, vì:
- curl vẫn gửi tên example.com trong SNI và trong header Host
- nó chỉ bỏ qua bước hỏi DNS, dùng IP bạn chỉ định
-> chứng chỉ khớp -> 200

SNI — Server Name Indication — là phiên bản của header Host ở tầng TLS:

Vấn đề: bắt tay TLS xảy ra TRƯỚC khi gửi header HTTP
-> máy chủ phải chọn chứng chỉ nào mà chưa biết bạn muốn trang gì

SNI giải quyết: tên miền được gửi kèm ngay trong bước bắt tay TLS
-> máy chủ chọn đúng chứng chỉ

Và vì nó nằm ngoài phần mã hoá, SNI là thứ duy nhất trong một kết nối HTTPS
mà người quan sát trên đường truyền đọc được — họ biết bạn vào trang nào,
nhưng không biết bạn xem gì trên đó.

Ba lệnh nữa đáng biết khi gỡ lỗi DNS:

dig +short crm.company.com              # gọn hơn nslookup
dig crm.company.com +trace # xem toàn bộ chuỗi phân giải từ gốc
dig @8.8.8.8 crm.company.com # hỏi một resolver KHÁC
Lệnh thứ ba hữu ích nhất khi gặp "trang này chạy ở máy tôi mà không chạy ở máy anh":
hai máy dùng hai resolver khác nhau, và một cái còn giữ bản ghi CŨ trong đệm
-> so sánh kết quả từ hai resolver là cách nhanh nhất xác nhận giả thuyết đó

Bài 3 — Tự vẽ sơ đồ​

Không nhìn bài, vẽ lại tám chặng và ghi tên bài học tương ứng với mỗi chặng.

Tiêu chí hoàn thành: bạn vẽ được đủ tám chặng, và với mỗi chặng nêu được một lỗi cụ thể có thể xảy ra ở đó.

Gợi ý và lời giải — Bài 3

Gợi ý. Nhớ được tám chặng là một chuyện. Biết chặng nào gây lỗi gì mới là thứ dùng được khi có sự cố.

Lời giải — sơ đồ kèm lỗi đặc trưng của từng chặng:

1. Gõ URL
Lỗi: gõ sai, hoặc trình duyệt tự thêm https:// vào một địa chỉ chỉ có http

2. DNS: tên miền -> IP [bài 2.3]
Lỗi: ERR_NAME_NOT_RESOLVED
tên miền hết hạn, bản ghi sai, hoặc resolver còn giữ bản ghi cũ
Chẩn đoán: dig +short, dig @8.8.8.8

3. TCP: thiết lập kết nối [bài 2.3]
Lỗi: ERR_CONNECTION_REFUSED -> không có gì lắng nghe ở cổng đó
ERR_CONNECTION_TIMED_OUT -> tường lửa chặn, hoặc máy chủ không phản hồi
Chẩn đoán: telnet <host> 443, hoặc nc -zv <host> 443

4. TLS: mã hoá kênh truyền [bài 2.5]
Lỗi: ERR_CERT_DATE_INVALID -> chứng chỉ hết hạn
ERR_CERT_COMMON_NAME_INVALID -> chứng chỉ cấp cho tên khác
Chẩn đoán: openssl s_client -connect host:443 -servername host

5. HTTP: POST /api/auth/login [bài 2.5, 2.6]
Lỗi: 400 body sai định dạng
404 sai đường dẫn
405 sai method
415 thiếu Content-Type
Chẩn đoán: đọc thẳng tab Network, hoặc curl -v

6. Backend nhận và xử lý [bài 2.4]
Lỗi: 500 ngoại lệ chưa xử lý
502 gateway không gọi được ứng dụng
503 ứng dụng chưa sẵn sàng
Chẩn đoán: log của ứng dụng, và traceId trong phản hồi

7. Database: kiểm tra tài khoản [bài 2.7]
Lỗi: timeout, pool cạn, truy vấn chậm
-> thường biểu hiện ra ngoài thành 500 hoặc 504
Chẩn đoán: log truy vấn, thời gian chờ lấy kết nối

8. Trả JWT về trình duyệt [bài 2.8]
Lỗi: 401 ở các request SAU (token sai, hết hạn, lệch đồng hồ)
lỗi CORS nếu web và API khác origin
Chẩn đoán: giải mã token, so exp với giờ hiện tại

Và đây là cách dùng sơ đồ này khi có sự cố — chia đôi thay vì đi tuần tự:

Thay vì kiểm tra chặng 1, rồi 2, rồi 3...
hãy kiểm tra chặng 5 TRƯỚC:

curl -i https://crm.company.com/api/auth/login -d '...'

Có phản hồi HTTP -> chặng 1–5 đều tốt -> vấn đề ở 6, 7 hoặc 8
Không có -> vấn đề ở 1–4
Một lệnh loại bỏ được một nửa số khả năng.
Đây là cùng ý tưởng với git bisect ở bài 3.11.

Bảng ánh xạ nhanh từ triệu chứng sang chặng:

Triệu chứngChặngKiểm tra đầu tiên
Trang không mở được, không có gì trong Network2–3dig, nc -zv
Cảnh báo bảo mật của trình duyệt4openssl s_client
Có mã trạng thái 4xx5Đọc body phản hồi
Có mã trạng thái 5xx6–7Log máy chủ theo traceId
Đăng nhập được rồi lại bị đẩy ra8Giải mã token, xem exp
"Blocked by CORS policy"5Header phản hồi, và thứ tự middleware

Và một bài tập nhỏ để tự kiểm tra: giải thích cho người không làm kỹ thuật.

"Khi anh gõ địa chỉ và bấm Enter:
máy tính hỏi danh bạ xem trang đó nằm ở máy nào,
gọi điện tới máy đó và thống nhất một cách nói chuyện riêng để không ai nghe lén,
gửi câu hỏi kèm tên đăng nhập và mật khẩu,
máy bên kia tra sổ xem có đúng không,
rồi đưa lại một tấm vé để lần sau khỏi phải đăng nhập nữa."
Giải thích được bằng ngôn ngữ đó nghĩa là bạn đã hiểu, không phải đã thuộc.
Và đó cũng là kỹ năng cần khi phải nói chuyện với người dùng trong một sự cố.

Tự kiểm tra​

Frequently asked questions

Vì sao nên học từ trải nghiệm tới thuật ngữ?

Vì học thuộc định nghĩa thì quên sau vài ngày, còn tự tay chạy nslookup rồi gõ IP vào trình duyệt thì hiểu ngay DNS dùng để làm gì và không quên. Mỗi khái niệm nên có một cách tự thử.

Tám chặng của một request web là gì?

Gõ URL, phân giải DNS, thiết lập kết nối TCP, bắt tay TLS, gửi request HTTP, backend xử lý, truy vấn database, và trả kết quả kèm token về trình duyệt.

Mã lỗi ERR_CONNECTION_REFUSED cho biết vấn đề ở chặng nào?

Chặng TCP. Tên miền đã phân giải ra IP thành công nhưng không mở được kết nối, thường vì server không chạy hoặc sai cổng.

Lỗi 401 khác lỗi 404 ở chỗ nào về mặt chẩn đoán?

404 là sai đường dẫn ở chặng HTTP, tức route không tồn tại. 401 là vấn đề ở chặng xác thực, tức token thiếu, sai hoặc hết hạn, còn đường dẫn thì đúng.

Nếu chỉ có hai giờ thì nên học bài nào?

Bài về HTTP và bài về xác thực, vì hai mảng đó chiếm phần lớn công việc hàng ngày của một backend engineer.

Công cụ quan trọng nhất để quan sát mọi thứ trong module này là gì?

DevTools của trình duyệt, tab Network. Ở đó bạn thấy được request, header, mã trạng thái và thời gian của từng chặng.

Kết luận​

Ba điều đáng nhớ nhất:

  1. Một ví dụ xuyên suốt nối mọi khái niệm lại — dễ nhớ hơn học từng thuật ngữ rời.
  2. Mã lỗi cho biết chặng nào có vấn đề. Đây là kỹ năng chẩn đoán cơ bản nhất.
  3. Tự tay thử mỗi khái niệm. Một lệnh nslookup đáng giá hơn một đoạn định nghĩa.

Tham khảo​

Điều hướng​