從一個封包到一套可擴展架構:前端該懂的 15 個全端概念

文字解析 · 1 支影片 · 產生於 2026-10-01 00:54

🎧 語音解析📝 筆記✍️ 練習

🎧 語音解析 48m20s · TTS 講解與作者原聲交錯;點章節可跳。
邊聽邊看逐句講稿,點任一句從那裡開始
章節(16)

1. Outline

  1. 起點 · 15 Fullstack Concepts Every Frontend Should Know
    從瀏覽器按下 Enter 之後的第一個封包開始,一層層往上推到 API Gateway、BFF 與負載平衡,把「前端該懂的全端」串成一條完整路徑。

2. YouTuber 的思維推導

15 Fullstack Concepts Every Frontend Should Know

theSeniorDev · 41m57s · 字幕 en · vision=on (整支影片是簡報+手繪架構圖講解,transcript 中「in this picture you see」「if we look at the headers」「this is the diagram of the Amazon API gateway」「and this is how these certificates look like」等指示語遠超過 3 次,封包結構、TLS 交握、N+1、BFF 架構都要看圖才懂,因此逐張讀圖。) · YouTube

預估 vs 實際耗時
階段預估實際
fetch 6s 1s
segment 1m54s 5m00s
shot 1m24s 9s
analyze 17m30s 25m00s
render 5s –

作者的推導是一條「由下往上、每一層都由上一層的缺口逼出來」的直線。他先從最底層問「在網址列按 Enter 之後到底發生什麼」,得到 HTTP 一問一答的模型;為了送出請求需要 IP,於是有 DNS;為了理解 IP 為什麼稀缺又為什麼有物理極限,於是往下看封包與海底電纜。既然跨網路有成本,就用快取省掉那趟路;既然連線是明文,就用 TLS 把它包起來。

到這裡「安全地拿一份資源」完整了,但 HTTP 仍然只能由客戶端發問,於是他用 polling → WebSocket → SSE 三段給出即時通訊的梯度。接著他把焦點從「怎麼傳」換到「請求長什麼樣」:RPC 讓請求像呼叫函式但會把兩端綁死,REST 用資源與動詞換來可預測性,卻在同時服務桌面與手機時裂成 under-fetching 與 over-fetching,於是 GraphQL 把欄位的決定權交給前端,而這又帶出 N+1 與 DataLoader。最後兩層是架構與組織:API Gateway 把各微服務重複的邊緣功能抽出來做一次,BFF 讓前端團隊擁有自己的資料層以繞開跨團隊協調,而全部流量集中之後產生的單點故障,再由負載平衡收尾。

整支影片的落點不是十五個名詞,而是一句話:前端要往 senior 走,必須看得見自己那個 fetch 之後的整條路徑,並且知道每一層是被前一層的哪個缺口逼出來的。

推理鏈:每段留給下一段的線索

每一列是一段,箭頭後的字是這段留給下一段的線索。點段落標題跳到該段。

  1. HTTP:一封信的來回 → 整條路徑都建立在「請求要送到某個 IP」上,可是你在網址列打的是 theseniordev.com 而不是一串數字——那個 IP 是誰告訴瀏覽器的?
  2. DNS:先問到 IP 才能發請求 → DNS 換來的是一串 IP 加一個埠號,但 IP 本身到底是什麼、為什麼會有「不夠用」這種事?
  3. IP:機器之間如何找到彼此 → 既然跨網路取檔案受限於光速與實體線路,那有沒有辦法乾脆不要再跑那一趟?
  4. HTTP 快取與 E-Tag → 快取解決了速度,但從第一個封包到現在,整條連線都是明文的——坐在中間的人看得到你送了什麼。
  5. TLS:為什麼要換兩種加密 → 到這裡「安全地把一份資源拿回來」已經完整了,但 HTTP 從頭到尾都只能由客戶端發問——想要「狀態一變就知道」該怎麼辦?
  6. Polling:最土但最簡單的即時 → 輪詢的成本跟「問的頻率」成正比,一旦資料量變大或要做聊天這種雙向場景,它就撐不住了。
  7. WebSocket:改成打電話 → 但很多場景其實只需要伺服器單向一直送,為了這個開一條雙向通道並不划算。
  8. SSE:AI 應用的串流來源 → 前面談的都是「怎麼把資料搬過來」,還沒談「請求本身該長什麼樣」——如果請求可以直接是「執行對面的一個函式」呢?
  9. RPC / tRPC 與 MCP → 既然主流仍然是 REST,那 REST 到底規範了什麼,才讓它贏過 RPC?
  10. REST:把 HTTP 標準化 → 這套規則有個隱含假設:只有一種客戶端。一旦要同時服務桌面與手機,它就開始出現裂縫。
  11. Under-fetch 與 Over-fetch → 如果問題出在「欄位由後端決定」,那把決定權交給前端會發生什麼事?
  12. GraphQL:前端自己決定要什麼 → 把決定權交給前端之後,後端要怎麼把那一次查詢變成資料庫操作?這裡藏著一個會把資料庫打爆的陷阱。
  13. N+1 問題與 DataLoader → 資料層的問題解決了,但這些微服務各自都要處理認證、SSL、限流……前端每接一個新的資料來源就要重新面對一次。
  14. API Gateway:重複的事只做一次 → 技術上的重複被消掉了,但要出一個功能仍然要跟一堆團隊協調——瓶頸其實已經不在程式碼裡了。
  15. BFF:前端擁有自己的後端 → 但所有流量仍然全部穿過同一個 API Gateway——它現在同時是壓力來源,也是單點故障。
  16. 負載平衡:消除單點故障

3. 逐段說明

15 Fullstack Concepts Every Frontend Should Know

1. HTTP:一封信的來回 0:00–3:02

作者從最底層開始:瀏覽器對伺服器發出 GET 請求,伺服器把 index.html 拆成 TCP 封包送回,客戶端再組回一份 HTTP response。他拆開封包給你看:IP header 包住 TCP header 再包住 payload,TCP 多出來的那層換來「不掉包、會照順序到」的保證。最後他把 HTTP response 描述成一封信:第一行狀態碼、接著是 headers(資料的資料)、空行、然後才是內容。

IP header/TCP header/payload 的巢狀封包結構圖,是理解「為什麼 TCP 要多付出空間換保證」的關鍵畫面
1:40 · IP header/TCP header/payload 的巢狀封包結構圖,是理解「為什麼 TCP 要多付出空間換保證」的關鍵畫面
HTTP response 的文字結構(狀態行/headers/空行/body),對照他「像一封信」的比喻
2:35 · HTTP response 的文字結構(狀態行/headers/空行/body),對照他「像一封信」的比喻
承上 前情提要裡「要往 senior 走就得跨出瀏覽器邊界」這個出發點——作者不從框架開始,而是從最底層、每個前端每天都在用卻很少拆開看的 HTTP 開始。

推理因為要先建立一套共同語言,所以作者接著跑完整條路徑:瀏覽器發 GET → 伺服器開始送 index.html → 拆成 TCP 封包 → 客戶端把封包組回一份 HTTP response → 讀 Content-Type 決定怎麼渲染。中間他刻意把封包剖開:IP header 包著 data,而那份 data 裡面又是 TCP header 加 TCP payload;TCP 多花的那塊空間換到的是「不掉包、會照順序到」。最後他把 response 描述成一封信:狀態行、headers(資料的資料)、空行、然後才是內容。

AI 補充作者說 TCP「保證不會掉封包」,更精確的說法是:封包在網路上還是會掉,TCP 用序號、ACK 與重傳把掉的補回來,所以在應用層看起來像沒掉過,代價是延遲與那顆 header。他也跳過一步:TCP 連線本身要先三次交握才開始傳資料,這是之後談 TLS「更慢」時的基礎。另外畫面上的 HTTP Response 範例寫的是 403 Forbidden 而旁白講 200,兩者只是同一個結構的不同狀態行,不影響結構本身。

術語:HTTP header

HTTP

超文本傳輸協定

瀏覽器與伺服器之間一問一答交換資源的應用層協定。

HTTP 的核心特徵是「無狀態」與「客戶端發動」:伺服器不記得你上一次問過什麼,而且在沒有新機制之前,它也不能主動找你。這兩個限制解釋了後面幾乎所有東西——cookie 與 token 是為了補回狀態,polling、WebSocket、SSE 是為了補回「伺服器主動說話」的能力。常見誤解是把 HTTP 當成「網路」本身,實際上它只管請求與回應的格式,真正的傳輸交給下面的 TCP 與 IP。

相關術語: TCP (承載於)、HTTP header (組成部分)

出處:第 1 段「HTTP:一封信的來回」

TCP

傳輸控制協定

在不可靠的 IP 之上提供「不掉包、照順序、可重傳」保證的傳輸層協定。

TCP 的保證不是魔法,而是用序號、確認回覆與重傳換來的:每個封包帶序號,收方回 ACK,發方沒收到 ACK 就重送,收方再依序號把亂序的封包排好。代價是額外的 header 空間與等待——這也是為什麼影音串流與遊戲常改用不保證送達的 UDP,寧可掉一格畫面也不要卡住。前端很少直接碰到 TCP,但它解釋了「為什麼建立連線本身就有成本」。

相關術語: IP (建立於其上)、HTTP (承載)

出處:第 1 段「HTTP:一封信的來回」

HTTP header

HTTP 標頭

夾在狀態行與內容之間、描述這份資料本身的鍵值對。

把 header 想成信封上的註記:Content-Type 說裡面是什麼(text/html 才會被當網頁渲染)、Content-Length 說多長、Server 說誰寄的。前端絕大多數「明明資料對了畫面卻不對」的問題,最後都指向某個 header:CORS、快取、內容型別、認證。DevTools 的 Network 分頁裡那一整排 Response Headers,就是這支影片後面反覆回來看的地方。

相關術語: status code (同屬回應)、HTTP (定義於)

出處:第 1 段「HTTP:一封信的來回」

status code

狀態碼

HTTP 回應第一行的三位數字,一眼說明這次請求整體成功與否。

分成五個級距:1xx 資訊、2xx 成功、3xx 轉向、4xx 客戶端錯(你問錯了)、5xx 伺服器錯(它壞了)。4xx 與 5xx 的界線在除錯時特別重要,它決定該改前端還是找後端。影片後面會出現的 304 Not Modified 是個特例——它屬於 3xx,意思是「你手上那份還能用」,不是錯誤。

相關術語: HTTP header (同屬回應)

出處:第 1 段「HTTP:一封信的來回」

留給下一段 整條路徑都建立在「請求要送到某個 IP」上,可是你在網址列打的是 theseniordev.com 而不是一串數字——那個 IP 是誰告訴瀏覽器的?

2. DNS:先問到 IP 才能發請求 3:02–5:52

既然請求要送到 IP,那人類記不住 IP 怎麼辦?DNS 就坐在 client 與 server 中間,把 domain 換成 IP。作者示範在瀏覽器 Network 分頁看第一個 document 請求的 Remote Address,就能看到真正連上的 IP 與 443 埠。他再往上追:GoDaddy 只是經銷,域名空間來自 Verisign,最上層由 IANA 協調。

client → DNS → server 的位置圖,說明 DNS 發生在任何 HTTP 請求之前
3:45 · client → DNS → server 的位置圖,說明 DNS 發生在任何 HTTP 請求之前
DevTools 裡的 Remote Address,把抽象的 DNS 查詢對應到你自己能驗證的畫面
4:45 · DevTools 裡的 Remote Address,把抽象的 DNS 查詢對應到你自己能驗證的畫面
承上 上一段結尾問的是「瀏覽器怎麼知道 domain 對應哪個 IP」——DNS 就是那個回答者。

推理因為請求必須有 IP 才送得出去,所以作者把 DNS 畫在 client 與 server 中間:輸入網址或發 fetch 時,瀏覽器先做一次 DNS lookup 拿到 IP,之後才真的發 HTTP 請求。接著他讓你自己驗證這件事——DevTools 第一個 document 請求的 Remote Address 就是那個 IP 與 443 埠。最後他往上追誰在維護這張對應表:GoDaddy 只是經銷,域名空間來自 Verisign,最上層由 IANA 協調。

AI 補充作者說「去最近的 DNS server 問」,實際上瀏覽器與作業系統各有一層快取,命中就根本不會出去;沒命中才往遞迴解析器,再逐層問根、TLD 與權威伺服器,而每筆記錄自己也有 TTL。這一點值得記住,因為它和下一段要談的東西是同一種思路:把慢的查詢結果留下來重用。另外 DNS 查詢傳統上是明文的,這也是 DoH(DNS over HTTPS)出現的原因。

術語:domain name

DNS

網域名稱系統

把人看得懂的網域名稱對應到機器用的 IP 位址的全球分散式查詢系統。

DNS 是一棵樹:根伺服器知道誰管 .com,.com 的 TLD 伺服器知道誰管 theseniordev.com,那台權威伺服器才給出真正的 IP。中間每一層都會快取,所以改 DNS 記錄不會立刻全球生效——這就是換主機時「等 DNS 傳播」的由來,等的其實是各層快取的 TTL 到期。它也是最早、最成功的分散式快取系統,前面提過的 HTTP 快取幾乎照抄了同一套想法。

相關術語: domain name (查詢對象)、IP (查詢結果)

出處:第 2 段「DNS:先問到 IP 才能發請求」

domain name

網域名稱

人類可讀、可轉讓的網路位址名稱,例如 theseniordev.com。

網域名稱不是你「買下」的東西,而是租來的使用權,到期不續約就會被別人登記。它的層級由右往左讀:.com 是頂級網域,theseniordev 是你註冊的二級網域,www 是你自己決定的子網域。註冊商(GoDaddy)、註冊局(Verisign 管 .com)、與協調機構(IANA/ICANN)三者的分工,正是作者往上追的那條鏈。

相關術語: DNS (由其解析)、IANA (受其協調)

出處:第 2 段「DNS:先問到 IP 才能發請求」

IANA

網際網路號碼分配局

協調全球網域名稱、IP 位址與協定編號分配的機構。

作者說「網際網路沒有中央組織,但有些事技術上必須協調」,IANA 就是那個協調點:它不擁有網路,但維護根區檔案、把 IP 位址段批給五大區域註冊機構(RIR),也管理協定號碼與埠號登記。今天它由 ICANN 底下的 PTI 營運。知道它的存在,是理解「網域與 IP 為什麼有稀缺性、有價格」的前提。

相關術語: domain name (協調其分配)

出處:第 2 段「DNS:先問到 IP 才能發請求」

留給下一段 DNS 換來的是一串 IP 加一個埠號,但 IP 本身到底是什麼、為什麼會有「不夠用」這種事?

3. IP:機器之間如何找到彼此 5:52–10:04

再往下一層是 IP —— 讓機器在網路上互相定位的協定,封包裡寫著來源與目的 IP,中間的網路設備照著轉送。作者用海底電纜地圖說明「網際網路是實體的」,資訊以光速在光纖裡跑。接著談 IP 位址像不動產一樣稀缺又昂貴(17.x.x.x 整段是 Apple 的),這也是 2000 年前後推出 IPv6 的原因,但因為大量既有設備,至今仍在緩慢遷移。

海底電纜網路圖,把「網際網路」從抽象概念拉回實體基礎建設
7:08 · 海底電纜網路圖,把「網際網路」從抽象概念拉回實體基礎建設
IP 位址空間分配圖,看到 17 段屬於 Apple,才理解位址稀缺的具體感
9:00 · IP 位址空間分配圖,看到 17 段屬於 Apple,才理解位址稀缺的具體感
承上 上一段拿到了 198.202.211.1:443 這串位址,這一段就把 IP 本身拆開看。

推理因為那串位址是整條路徑的終點,所以作者往下走到網路層:每個 IP 封包裡都寫著來源與目的位址,中間的網路設備照著轉送。接著他用海底電纜地圖說明這一切跑在實體光纖上,資訊以接近光速前進——所以「快」有物理上限。最後他解釋位址為什麼像不動產:早期被企業與政府大量買走(17 開頭整段是 Apple),剩下的越來越貴,這正是 IPv6 的動機,只是既有設備太多,遷移至今仍在進行。

AI 補充作者提到 HTTPS 埠時口誤說成 440,實際是 443,畫面上的 Remote Address 也寫 443。另外「IPv4 不夠用」在實務上被 NAT 拖延了二十幾年:家裡與公司的所有裝置共用一個對外 IPv4,對內用私有位址,所以你雖然沒感覺,位址其實早就枯竭了。這也解釋了為什麼 IPv6 遷移遲遲沒有急迫性——痛點被一層轉譯吸收掉了。

術語:port

IP

網際網路協定

讓封包能在互連的眾多網路之間找到目的機器的網路層協定。

IP 只負責「盡力送達」:它不保證送到、不保證順序、也不保證只送一次,這些保證是上一層的 TCP 補上的。它的價值在於「互連」——每個小網路只要都講 IP,就能拼成一張全球網路,路由器靠封包裡的目的位址逐跳決定往哪送。前端很少直接操作 IP,但它決定了延遲的下限:地球另一端來回一趟,光速本身就要一百多毫秒。

相關術語: TCP (為其補保證)、IPv4 (其版本)

出處:第 3 段「IP:機器之間如何找到彼此」

IPv4

第四版網際網路協定位址

由四段 0–255 數字組成的 32 位元位址,例如 198.202.211.1。

32 位元代表理論上只有約 43 億個位址,扣掉保留與私有段後更少,2011 年起各區域註冊機構陸續宣告耗盡。作者展示的那張位址分配圖就是這個稀缺性的具象化:17.0.0.0/8 這一整段(一千六百多萬個位址)在早期被 Apple 拿走,今天要買下同等規模的空間是天價。私有段(10.x、192.168.x)不屬於任何人,靠 NAT 共用一個對外位址。

相關術語: IPv6 (被其取代中)、IP (一種)

出處:第 3 段「IP:機器之間如何找到彼此」

IPv6

第六版網際網路協定位址

128 位元、以冒號分隔十六進位表示的位址,用來解決 IPv4 位址枯竭。

128 位元的空間大到近乎用不完,同時也順手簡化了標頭、內建了自動設定與 IPsec。但它與 IPv4 不相容,所以遷移只能靠雙堆疊或轉譯共存,這是它推了將近三十年仍未完全普及的主因。作者展示的 DNS 表格裡那幾串長位址就是 IPv6 記錄(AAAA),今天大型網站幾乎都同時提供兩種。

相關術語: IPv4 (取代)

出處:第 3 段「IP:機器之間如何找到彼此」

port

通訊埠

同一個 IP 位址上區分不同服務的編號,像同一棟樓的不同門牌。

IP 位址帶你到機器,埠號帶你到機器上的哪個程式:80 是 HTTP、443 是 HTTPS、5432 是 PostgreSQL。前端開發時 localhost:3000 與 localhost:8080 之所以是兩個不同的「來源」,正是因為埠號不同——這也是本機開發最常撞到 CORS 的原因。1024 以下屬於需要特權才能綁定的知名埠。

相關術語: IP (搭配使用)、HTTPS (預設 443)

出處:第 3 段「IP:機器之間如何找到彼此」

見仁見智 9:26
「so expensive around the 2000 people came up with the idea of IPv6」
把 IPv6 的提出時間推晚了大約五年。IPv6 的第一份規格 RFC 1883 在 1995 年就發布,1998 年由 RFC 2460 定稿,並非「2000 年左右才有這個想法」。作者要表達的「因為位址枯竭才做 IPv6」這個因果本身是對的。
依據: RFC 1883 (1995-12)、RFC 2460 (1998-12)
留給下一段 既然跨網路取檔案受限於光速與實體線路,那有沒有辦法乾脆不要再跑那一趟?

4. HTTP 快取與 E-Tag 10:04–13:05

既然跨網路拿檔案慢,就把檔案留下來重用,這就是快取;能重用多久叫 TTL,在 HTTP 裡寫成 max-age。max-age 過期後不是直接重抓,而是拿 E-Tag(依內容產生的唯一識別碼)去問伺服器「我這份還是最新的嗎」,是就重設計時器,不是才下載新版。作者示範在 DevTools 看 200 OK (from memory cache)、age、cache-control 與 etag 這幾個 header 怎麼配合。

browser cache 坐在 client 與 server 之間的位置圖,說明快取為什麼能省掉整趟網路
10:30 · browser cache 坐在 client 與 server 之間的位置圖,說明快取為什麼能省掉整趟網路
cache-control: max-age=31536000, immutable 與 age、etag 三個 header 同時出現,是快取失效機制的實證
11:40 · cache-control: max-age=31536000, immutable 與 age、etag 三個 header 同時出現,是快取失效機制的實證
DevTools 顯示 200 OK (from memory cache),並圈出 age 672803 對上 max-age,證明資產真的沒走網路
12:35 · DevTools 顯示 200 OK (from memory cache),並圈出 age 672803 對上 max-age,證明資產真的沒走網路
承上 上一段留下的線索是「網路來回有物理成本」——省掉那趟路的辦法,就是把拿過的東西留下來。

推理因為跨網路慢,所以作者提出把檔案存在瀏覽器快取重用,並定義「能重用多久」就是 TTL,在 HTTP 裡寫成 max-age。接著他處理過期之後怎麼辦:不是直接重抓,而是帶著 E-Tag(依檔案內容產生的唯一識別碼)去問伺服器「我這份還是最新的嗎」,是就重設計時器,不是才下載新版。最後他用 DevTools 把 200 OK (from memory cache)、age、cache-control、etag 四個線索兜成一個完整故事。

AI 補充補一個作者沒說清楚的關鍵:age 是「這份資料在快取裡待了多久」,由中間的 CDN 回報,所以判斷是否過期就是拿 age 去比 max-age——畫面上 age 672803 對 max-age 31536000,還早得很。畫面裡那個 immutable 指令的意思是「這個 URL 的內容永遠不會變」,連重新整理時的驗證請求都可以省掉,這正是前端 build 工具在檔名裡塞內容雜湊的理由:檔案變了就換 URL,於是快取可以設到一年。

術語:HTTP caching

HTTP caching

HTTP 快取

把取回的資源存在本地或中介節點,之後直接重用而不再走網路。

快取分兩種:瀏覽器裡的私有快取(只服務你一個人,可以放個人化內容)與 CDN 之類的共享快取(服務所有人,放了個人化內容就會外洩)。Cache-Control 的 private/public 就是在區分這件事。快取真正困難的從來不是存,而是失效——什麼時候該承認手上這份過時了,這也是下面 max-age 與 ETag 兩個機制存在的理由。

相關術語: TTL (決定存活期)、ETag (用於驗證)

出處:第 4 段「HTTP 快取與 E-Tag」

TTL

存活時間

一份快取資料在被視為過期之前可以直接重用多久。

TTL 是所有快取系統的共同旋鈕,DNS 記錄、CDN 資產、Redis 鍵值都有。它的取捨永遠一樣:設短則常常白跑一趟驗證,設長則使用者可能看到舊資料。實務上的解法是「靜態資產設很長 TTL + 檔名帶內容雜湊」,把更新變成換 URL 而不是等過期。

相關術語: max-age (HTTP 的寫法)

出處:第 4 段「HTTP 快取與 E-Tag」

max-age

最大存活秒數

Cache-Control 標頭裡的欄位,以秒為單位指定這份資源可以直接重用多久。

它與回應裡的 age 搭配使用:age 說這份在快取裡待了多久,兩者一比就知道是否新鮮。同一個 Cache-Control 還能帶 no-cache(可以存但每次都要驗證)、no-store(完全不准存)、immutable(連驗證都免了),這幾個常被混淆——no-cache 並不是不快取。

相關術語: TTL (實作)、HTTP header (屬於)

出處:第 4 段「HTTP 快取與 E-Tag」

ETag

實體標籤

伺服器依資源內容產生的識別碼,用來判斷客戶端手上那份是否仍是最新。

過期之後客戶端會帶 If-None-Match: <etag> 再問一次,內容沒變伺服器就回 304 Not Modified 且不帶內容——省下的是傳輸量而不是那趟往返。Last-Modified 是同一件事的時間戳版本,精度只到秒,所以 ETag 較可靠。要注意 ETag 若由多台伺服器各自計算而不一致,驗證就會一直失敗、快取形同虛設。

相關術語: max-age (過期後接手)、status code (回應 304)

出處:第 4 段「HTTP 快取與 E-Tag」

確定錯誤/已過時 12:29
「Now that number it's in milliseconds.」
Cache-Control 的 max-age 單位是「秒」,不是毫秒。畫面上的 max-age=31536000 當成秒剛好是一年(也是規範建議的上限用法);若真是毫秒就只有約 8.7 小時,跟旁邊 age=672803 已經超過七天卻仍算新鮮的事實直接矛盾。
依據: RFC 9111 §5.2.2.1 max-age:delta-seconds
留給下一段 快取解決了速度,但從第一個封包到現在,整條連線都是明文的——坐在中間的人看得到你送了什麼。

5. TLS:為什麼要換兩種加密 13:05–17:38

HTTP 是明文,所以有人可以坐在中間攔截你的 header 與付款資料,這就是 man-in-the-middle 攻擊,在公共 Wi-Fi 特別容易。1996 年 Netscape 提出 HTTPS:先用非對稱加密完成交握——瀏覽器取得憑證(公鑰)、向憑證機構驗證它確實屬於這個網域、產生一把密鑰用憑證加密送回、伺服器用私鑰解開。之後改用對稱加密傳真正的資料,因為非對稱慢又貴,對稱快但需要雙方共有一個祕密,而那個祕密正是交握換來的。

man-in-the-middle 攻擊示意圖,說明 TLS 要解決的具體威脅
13:30 · man-in-the-middle 攻擊示意圖,說明 TLS 要解決的具體威脅
非對稱交握的起點:伺服器手上有 SSL Certificate,瀏覽器什麼都還沒有
15:05 · 非對稱交握的起點:伺服器手上有 SSL Certificate,瀏覽器什麼都還沒有
Asymmetric vs Symmetric 對照表(慢/兩把數學相連的金鑰 vs 快/一把共有金鑰),是換手的理由
17:30 · Asymmetric vs Symmetric 對照表(慢/兩把數學相連的金鑰 vs 快/一把共有金鑰),是換手的理由
承上 上一段結尾指出整條連線都是明文,這一段就從「明文會被誰看到」開始。

推理因為明文可被攔截,所以作者先描述威脅本身:有人坐在你與伺服器中間(公共 Wi-Fi 特別容易),把 IP 封包還原成 HTTP,就能讀到你的 authorization header 甚至信用卡資料。這在只看部落格的年代無所謂,電子商務出現後才變成災難,於是 Netscape 提出 HTTPS。接著他拆交握:瀏覽器取得憑證(公鑰)→ 向憑證機構驗證它確實屬於這個網域 → 產生一把 secret key、用憑證加密後送回 → 伺服器用私鑰解開。之後改走對稱加密,因為非對稱慢又貴、對稱快但需要一個雙方共有的祕密,而那個祕密正是交握換來的。

AI 補充有個常見誤解值得說清楚:憑證的作用不是加密資料,而是「證明這把公鑰屬於這個網域」;真正保護後續流量的是那把對稱金鑰。所以 HTTPS 同時給你兩件事——機密性來自加密,身分可信來自憑證鏈,缺一個都不算安全(自簽憑證加密照做,但沒人替它背書)。另外作者說交握「至少五個網路來回」是 TLS 1.2 以前(含 TCP 三次交握)的粗估;TLS 1.3 已把完整交握壓到 1-RTT、重連還能 0-RTT,所以今天 HTTPS 的額外延遲遠比影片描述的小。

術語:man-in-the-middle attackcertificate authority

TLS

傳輸層安全協定

在 TCP 之上加一層加密與身分驗證,讓上面的協定不必自己處理安全。

TLS 是 SSL 的後繼者,今天講 SSL 憑證其實指的都是 TLS。它做三件事:加密(別人看不到)、完整性(別人改不了而不被發現)、身分驗證(你確定對面是誰)。因為它是獨立的一層,所以不只 HTTP 能用——SMTP、WebSocket(wss://)、資料庫連線都能包在裡面。

相關術語: HTTPS (其應用)、TCP (建立於其上)

出處:第 5 段「TLS:為什麼要換兩種加密」

HTTPS

加密的 HTTP

跑在 TLS 之上的 HTTP,預設使用 443 埠。

HTTPS 不是新協定,就是「HTTP over TLS」——請求與回應的格式一字未改,只是外面包了一層。今天它已是預設而非選項:瀏覽器對純 HTTP 頁面標示不安全,而且 Service Worker、地理位置、剪貼簿等許多 Web API 只在安全來源下可用,所以「這個網站不需要加密」在 2020 年代已經不是有效理由。

相關術語: TLS (建立於其上)、HTTP (加密版)

出處:第 5 段「TLS:為什麼要換兩種加密」

man-in-the-middle attack

中間人攻擊

攻擊者插在客戶端與伺服器之間,讀取甚至竄改雙方以為是私密的通訊。

它不需要攻破任何一端,只要能坐在路徑上——惡意熱點、被入侵的路由器、ARP 欺騙都做得到。TLS 之所以能擋,靠的不只是加密,更是憑證驗證:攻擊者可以轉發你的封包,但拿不出一張被信任機構簽署、且網域相符的憑證。這也是為什麼「點掉憑證警告繼續前往」是危險動作——你等於親手關掉唯一的防線。

相關術語: TLS (被其防禦)、certificate authority (信任來源)

出處:第 5 段「TLS:為什麼要換兩種加密」

asymmetric encryption

非對稱加密

使用數學上成對的公鑰與私鑰,公鑰加密的只有私鑰能解。

它的價值在於「可以跟陌生人開始」:公鑰可以隨便公開,任何人都能用它加密送給你,只有你解得開。代價是運算昂貴、能處理的資料量小,所以幾乎沒有人用它加密整個連線,只拿它來交換一把對稱金鑰或做數位簽章。今天的 TLS 1.3 更進一步改用 Diffie-Hellman 金鑰交換,讓雙方各自算出同一把祕密而不必真的傳輸它。

相關術語: symmetric encryption (對照組)、certificate authority (簽署公鑰)

出處:第 5 段「TLS:為什麼要換兩種加密」

symmetric encryption

對稱加密

加密與解密使用同一把金鑰,速度快但雙方必須先共有那把金鑰。

現代 CPU 內建 AES 指令,對稱加密幾乎不花成本,所以 TLS 連線建立之後的所有資料都走這條路。它唯一的難題就是「怎麼安全地把金鑰交給對方」,而這正好是非對稱加密擅長的事——兩者的分工不是誰比較好,而是各自解決對方的短處。

相關術語: asymmetric encryption (對照組)

出處:第 5 段「TLS:為什麼要換兩種加密」

certificate authority

憑證機構(CA)

替網站簽發並背書憑證、讓瀏覽器能驗證公鑰確實屬於該網域的第三方機構。

瀏覽器與作業系統內建一份受信任的根憑證清單,網站憑證由根往下逐層簽署形成憑證鏈,任何一環對不上就會跳警告。作者說憑證「很貴」在今天已經不成立:Let's Encrypt 自 2015 年起免費簽發網域驗證憑證並自動續期,付費憑證主要買的是組織驗證與保險,不是更強的加密。

相關術語: asymmetric encryption (背書其公鑰)、domain name (驗證對象)

出處:第 5 段「TLS:為什麼要換兩種加密」

見仁見智 14:14
「in order to prevent this in 1996 which is basically 30 years ago Netscape」
Netscape 的 SSL 2.0 在 1995 年就隨 Navigator 出貨(SSL 1.0 從未公開),SSL 3.0 才是 1996;標準化並改名為 TLS 1.0 則要到 1999 年的 RFC 2246。說「1996 年 Netscape 提出 HTTPS」大方向沒錯,時間點略晚一年。
依據: SSL 2.0 (1995)、SSL 3.0 (1996)、RFC 2246 TLS 1.0 (1999)
留給下一段 到這裡「安全地把一份資源拿回來」已經完整了,但 HTTP 從頭到尾都只能由客戶端發問——想要「狀態一變就知道」該怎麼辦?

6. Polling:最土但最簡單的即時 17:38–19:26

HTTP 是一來一回的信件,那想要「狀態一變就知道」怎麼辦?最簡單的是 polling:客戶端每隔固定間隔(polling interval)打同一個端點,直到狀態改變為止。作者用付款狀態當例子,程式碼就是 fetch 包在 setInterval 裡,拿到想要的答案就 clearInterval。使用者不必手動重新整理,這是最早的「假即時」。

付款狀態輪詢的時序圖,看得出每 3–5 秒就打一次的成本
18:10 · 付款狀態輪詢的時序圖,看得出每 3–5 秒就打一次的成本
setInterval + fetch + clearInterval 的實際程式碼,說明它真的只需要瀏覽器原生 API
18:40 · setInterval + fetch + clearInterval 的實際程式碼,說明它真的只需要瀏覽器原生 API
承上 上一段結尾問的是「一問一答的協定怎麼做到即時」,而最土的答案就是:一直問。

推理因為 HTTP 只能由客戶端發動,所以最簡單的即時就是週期性重問。作者用付款狀態當例子:瀏覽器每 3 秒打一次 /payments/:id/status,伺服器回 pending 就繼續,回 completed 就 clearInterval 停下來。程式碼只是 fetch 包在 setInterval 裡,完全用瀏覽器原生 API,換到的是使用者不必再自己按重新整理——在那之前的做法真的就是「十秒後請重整頁面」。

AI 補充作者的虛擬碼有個在 React 裡會出事的地方:setInterval 直接寫在元件本體,每次 render 都會多開一個計時器,正確做法是放進 useEffect 並在 cleanup 裡 clearInterval。另外固定間隔在伺服器忙碌時會反過來放大壓力,生產環境通常改用指數退避——每次沒結果就把間隔加倍並設上限,讓等得越久問得越稀疏。

polling

輪詢

客戶端週期性重複請求同一個端點,直到狀態改變為止。

輪詢的最大優點是「什麼都不用改」——伺服器只要提供一個普通的 REST 端點,前端加一個計時器就完成,任何代理、快取、防火牆都不會擋。它的缺點同樣明顯:大部分請求都白跑,而且延遲最差等於一個間隔。介於輪詢與 WebSocket 之間還有一種 long polling,伺服器收到請求後先不回應、有資料才回,是 WebSocket 普及前聊天室的主流做法。

相關術語: polling interval (其參數)、WebSocket (被其取代)

出處:第 6 段「Polling:最土但最簡單的即時」

polling interval

輪詢間隔

兩次輪詢請求之間等待的時間。

這個數字是延遲與成本的直接兌換率:改成 1 秒,使用者感覺變快,伺服器負載變三倍。實務上會依情境調整——付款確認可以密集問幾次就放棄,背景同步則可以拉到分鐘級。指數退避的本質就是「讓間隔隨等待時間自動變大」。

相關術語: polling (屬於)

出處:第 6 段「Polling:最土但最簡單的即時」

留給下一段 輪詢的成本跟「問的頻率」成正比,一旦資料量變大或要做聊天這種雙向場景,它就撐不住了。

7. WebSocket:改成打電話 19:26–20:53

polling 在資料量大或聊天這種場景就不夠用了,因為每則訊息都要重新寄一封信。WebSocket 是打電話:開一條雙向通道,兩邊都能隨時送訊息,不必為每則訊息重新建立請求。作者強調實作其實很簡單,瀏覽器端 new WebSocket、Node 端監聽連線並回訊息,現代聊天與社群的即時推播就是靠這個。

「寄信 vs 打電話」的對比圖,一眼看出 HTTP 與 WebSocket 的本質差別
19:50 · 「寄信 vs 打電話」的對比圖,一眼看出 HTTP 與 WebSocket 的本質差別
瀏覽器端與 Node 端的對照程式碼,說明門檻沒有想像中高
20:15 · 瀏覽器端與 Node 端的對照程式碼,說明門檻沒有想像中高
user B → server → user A 的訊息流動圖,是聊天系統的最小模型
20:45 · user B → server → user A 的訊息流動圖,是聊天系統的最小模型
承上 上一段結尾說輪詢在聊天這種場景會撐不住,這一段就換掉連線的形態本身。

推理因為每則訊息都重新寄一封信太貴,所以作者把 WebSocket 比成打電話:開一條雙向通道之後,兩邊都能隨時送訊息,不必為每則訊息重新協商。他刻意把 client 與 server 的程式碼並排,讓你看到 new WebSocket("ws://localhost:8080") 與 wss.on("connection", ...) 其實都很短,門檻沒有想像中高。最後用 user B → server → user A 的圖收尾:現代聊天與社群的即時推播,本質上就是這張圖。

AI 補充補一步作者跳過的:WebSocket 連線其實是從一個普通的 HTTP 請求開始的,帶著 Upgrade: websocket 標頭請伺服器切換協定,所以它能沿用既有的 80/443 埠與 TLS(wss://),不必另外開防火牆。也因為連線是長期存在的,伺服器端得自己處理心跳偵測、斷線重連,以及「同一個使用者開了三個分頁」的狀態管理——這些才是規模化時真正的成本,而不是那幾行連線程式碼。

WebSocket

網頁通訊端

在單一 TCP 連線上提供全雙工訊息通道的協定,兩端都能隨時主動送資料。

它解決的是 HTTP 的根本限制——伺服器不能主動說話。代價是狀態:連線活著就佔著伺服器資源,水平擴展時同一個使用者的訊息必須送到他實際連著的那台機器,所以背後通常還要一層發布/訂閱(Redis、Kafka)做跨實例廣播。要注意它建立之後就不再是 HTTP,中途的快取、狀態碼、標準的重試機制都用不上,這些得自己補。

相關術語: polling (取代)、Server-Sent Events (單向對照組)

出處:第 7 段「WebSocket:改成打電話」

留給下一段 但很多場景其實只需要伺服器單向一直送,為了這個開一條雙向通道並不划算。

8. SSE:AI 應用的串流來源 20:53–22:06

第三種即時是 Server-Sent Events:客戶端只發一次請求並訂閱,之後由伺服器單向持續推事件。這正好對上 LLM 一個 token 一個 token 生成的模式,所以現代 AI 應用幾乎都用它。作者示範打開 ChatGPT 的 Network,找到 conversation 端點的 Event Stream,就能看到畫面上的字是怎麼一則一則被推過來的。

SSE 訂閱與伺服器單向推送的示意圖,對照前兩種即時方式的差別
21:30 · SSE 訂閱與伺服器單向推送的示意圖,對照前兩種即時方式的差別
ChatGPT DevTools 的 Event Stream 實況,證明 AI 介面底層就是老瀏覽器 API
21:52 · ChatGPT DevTools 的 Event Stream 實況,證明 AI 介面底層就是老瀏覽器 API
承上 上一段結尾指出雙向通道對「只需要伺服器單向推」的場景過重,SSE 正是那個較輕的選項。

推理因為只需要單向,所以作者介紹 Server-Sent Events:客戶端對 /conversation/:id 發一次請求並訂閱,之後伺服器就持續往同一條連線推事件。他馬上把它接到今天最熱的場景——LLM 一次生成一個 token,正好是單向串流,所以現代 AI 應用幾乎都用 SSE。打開 ChatGPT 的 DevTools 看 conversation 端點的 EventStream,那一排 delta 事件就是畫面上逐字浮現的字,證明看起來很新的介面底層是很老的瀏覽器 API。

AI 補充值得補的是 SSE 的兩個實用細節:它走純文字格式、自帶 id 與 retry 欄位,斷線後瀏覽器會自動帶 Last-Event-ID 續傳,這是 WebSocket 沒有的內建行為;代價是只能傳文字、只能單向,而且在 HTTP/1.1 下受同網域連線數上限拖累(HTTP/2 之後不再是問題)。至此三種即時方式構成一個清楚的梯度:輪詢最簡單但最浪費、SSE 單向且自動重連、WebSocket 雙向但要自己管狀態。

術語:EventSource

Server-Sent Events

伺服器推送事件(SSE)

客戶端訂閱一次後,伺服器透過同一條 HTTP 連線持續單向推送文字事件的機制。

它的格式極簡:每則事件就是 data: 開頭的幾行純文字,空行分隔。因為它就是一個沒有結束的 HTTP 回應(Content-Type: text/event-stream),所以代理、認證、CORS 全都沿用既有那一套,比 WebSocket 好部署得多。選擇標準很直接:只有伺服器要說話就用 SSE,兩邊都要說話才用 WebSocket。

相關術語: WebSocket (雙向對照組)、EventSource (瀏覽器 API)

出處:第 8 段「SSE:AI 應用的串流來源」

EventSource

事件來源 API

瀏覽器內建、用來訂閱 SSE 串流的介面。

用法是 new EventSource(url) 之後掛 onmessage,斷線自動重連也由它負責。它的限制是只支援 GET 且不能自訂標頭,所以要送 Authorization 的場景常改用 fetch 加 ReadableStream 自己解析串流——多數 AI 應用實際上走的是後者,這也是為什麼你在 DevTools 的 Fetch/XHR 分頁而不是別處看到那個 conversation 請求。

相關術語: Server-Sent Events (實作)

出處:第 8 段「SSE:AI 應用的串流來源」

留給下一段 前面談的都是「怎麼把資料搬過來」,還沒談「請求本身該長什麼樣」——如果請求可以直接是「執行對面的一個函式」呢?

9. RPC / tRPC 與 MCP 22:06–24:31

接著換一種思路:不是取資源,而是直接叫另一台電腦執行一個函式,這就是 RPC,比網際網路還老,最近因為 TypeScript 以 tRPC 之姿復活,好處是 client 與 server 之間有型別安全。但作者也給出它沒有普及的原因:client 與 server 高度耦合,伺服器程式碼會變得很有意見、很快變成義大利麵。有趣的是 RPC 在 AI 時代以 MCP 回來了——AI 幫你訂會議就是透過 MCP(走較輕量的 JSON-RPC)呼叫外部系統的函式。

遠端呼叫函式並取回結果的示意圖,區分 RPC 與 REST 的心智模型
22:25 · 遠端呼叫函式並取回結果的示意圖,區分 RPC 與 REST 的心智模型
tRPC client 發 mutation 的程式碼與型別安全示範
22:50 · tRPC client 發 mutation 的程式碼與型別安全示範
MCP 的定義投影片:連接 AI 應用與外部系統的開放標準,把老協定接回今天的 agent
23:52 · MCP 的定義投影片:連接 AI 應用與外部系統的開放標準,把老協定接回今天的 agent
承上 上一段結尾問的是「請求本身還能長成什麼樣」——RPC 給的答案是:長得像呼叫一個函式。

推理因為 HTTP 只規範傳輸、不規範請求的形狀,所以作者拿出比網際網路還老的 RPC:客戶端直接叫伺服器執行某個函式並取回結果。tRPC 是它在 TypeScript 生態的復活版,賣點是兩端共用型別、改壞了編譯期就會抓到。但他立刻給出它沒有普及的理由:這種寫法把 client 與 server 綁死,伺服器程式碼必須知道前端在做什麼,久了就是義大利麵,所以他建議要學就先學 REST。最後他指出 RPC 在 AI 時代以 MCP 回來了——AI 幫你訂會議,底層就是走 JSON-RPC 呼叫外部系統提供的函式。

AI 補充作者說 MCP「大概七個月前才出來」是錄影當下的說法,時效性見下方勘誤。另外有兩件常被混談的事值得分開:tRPC 是 TypeScript 專用、靠型別推導做到端到端型別安全的函式庫,它連線上格式都沒有規範;JSON-RPC 則是語言無關的線上協定,MCP 用的是後者。作者說的「RPC 讓程式碼耦合」也要分層看——真正的耦合來自「函式名稱即 API」這個設計,而不是 RPC 這個傳輸方式本身。

RPC

遠端程序呼叫

讓程式像呼叫本地函式一樣,觸發另一台機器執行某個函式並取回結果。

RPC 的心智模型是「動詞」(做這件事),REST 是「名詞」(操作這個資源),這個差別決定了兩者的優缺點。RPC 對「不是 CRUD 的操作」表達力更好——sendEmail、rebuildIndex 硬要套成資源會很彆扭;代價是每個函式都是新的介面,客戶端無法靠慣例猜測。gRPC 是它在後端服務之間最主流的現代實作。

相關術語: tRPC (TypeScript 實作)、REST (對照組)

出處:第 9 段「RPC / tRPC 與 MCP」

tRPC

TypeScript 遠端呼叫函式庫

在 TypeScript 全端專案裡讓前端直接呼叫後端函式、並自動共享型別的函式庫。

它沒有程式碼產生步驟,靠的是把後端 router 的型別直接 import 到前端做推導,所以後端改了參數,前端立刻紅字。這也劃出它的適用範圍:前後端同一個 repo、同一種語言、同一個團隊。一旦有第三方或別種語言的客戶端要串接,它就不適合,那正是作者說它沒被大規模採用的實際原因。

相關術語: RPC (一種)

出處:第 9 段「RPC / tRPC 與 MCP」

MCP

模型情境協定

讓 AI 應用以標準方式連接外部工具與資料來源的開放協定。

它解決的是 M×N 問題:沒有標準時,每個 AI 應用都得替每個外部系統寫一次整合。MCP 定義了 server 如何宣告自己提供哪些 tool、resource 與 prompt,模型讀了描述就知道能呼叫什麼、參數是什麼,然後由宿主程式實際執行並把結果送回。所以它本質上就是「給模型看的 API 文件 + 呼叫通道」,而呼叫通道用的是 JSON-RPC。

相關術語: JSON-RPC (使用)、RPC (一種應用)

出處:第 9 段「RPC / tRPC 與 MCP」

JSON-RPC

以 JSON 表示的遠端呼叫協定

用一個 JSON 物件表示「呼叫哪個方法、帶什麼參數、對應哪個 id」的輕量協定。

規格短到一頁能讀完:請求帶 method、params、id,回應帶 result 或 error 與同一個 id,靠 id 配對就能支援非同步與批次。它不綁定傳輸方式,HTTP、stdio、WebSocket 都能跑——MCP 正是利用這點,讓本機的 MCP server 可以直接透過標準輸入輸出溝通。

相關術語: MCP (被其採用)、RPC (一種)

出處:第 9 段「RPC / tRPC 與 MCP」

見仁見智 24:26
「it was only probably 7 months ago. So, this stuff is pretty recent.」
這是錄影當下的相對時間,現在讀會誤導。MCP 由 Anthropic 在 2024 年 11 月發布並開源,至今已超過一年,且已被多家 AI 廠商與 IDE 採用,不再是「剛出來七個月」的實驗性東西。
依據: Model Context Protocol 公開發布:2024-11
留給下一段 既然主流仍然是 REST,那 REST 到底規範了什麼,才讓它贏過 RPC?

10. REST:把 HTTP 標準化 24:31–28:51

HTTP 只規範傳輸,請求本身可以隨便自由發揮,結果每個 API 都要重新學一次。REST 的做法是把實體當成資源,用複數名詞的 URI(/products、/users)加上 HTTP 動詞形成統一介面,還可以加 query parameter 做分頁與搜尋,巢狀成 /products/:id/prices。作者用電商領域模型示範怎麼把 product、price、rating、review 對應成端點,並整理出 CRUD ↔ POST/GET/PUT 或 PATCH/DELETE 的對照(PUT 具冪等性,通常比 PATCH 好用)。實作良好時,你不看文件就知道這個 API 提供什麼。

電商領域模型(product 與其複合型別),說明 URI 是從領域模型長出來的
25:20 · 電商領域模型(product 與其複合型別),說明 URI 是從領域模型長出來的
/products?page=1&page_size=10&name=keyboard,query parameter 的實際樣子
26:30 · /products?page=1&page_size=10&name=keyboard,query parameter 的實際樣子
CRUD 與 HTTP 動詞的對照表,這張是面試最常被問的內容
28:10 · CRUD 與 HTTP 動詞的對照表,這張是面試最常被問的內容
承上 上一段結尾問「REST 憑什麼贏過 RPC」,這一段就是答案:它給了一套所有人都猜得到的規則。

推理因為人人自由發揮會讓每次串接都要重學一次,所以作者用「把實體當成資源」重新組織 HTTP:URI 用複數名詞(/products、/users),操作用 HTTP 動詞,篩選與分頁用 query parameter,關聯用巢狀路徑 /products/:id/prices。他先從電商領域模型出發——Product 底下的 Price、Rating、DeliveryTime 都是複合型別而不只是數字——再把 CRUD 對到 POST / GET / PUT 或 PATCH / DELETE,並指出 PUT 具冪等性、通常比 PATCH 好推理。結論是:實作得好的 API,你不看文件就知道它提供什麼。

AI 補充把作者一句話帶過的冪等性說清楚:同一個 PUT 送一次和送十次,伺服器的最終狀態一樣;PATCH 若是「數量加一」這種相對操作就不具此性質,重送會多加。這在網路不穩、客戶端會自動重試時是實際的正確性問題,也是除了 POST 之外還需要其他動詞的理由。順帶一提,字幕把 idempotent 誤聽成 important,讀 transcript 時別被誤導。

REST

表現層狀態轉移

把系統中的實體當成資源、以統一的 URI 與 HTTP 動詞操作它們的 API 設計風格。

REST 是 Roy Fielding 在 2000 年博士論文裡提出的架構風格,原始定義還包含無狀態、可快取、分層與 HATEOAS(回應裡帶著下一步可用的連結)等約束,其中 HATEOAS 幾乎沒人實作。它最大的價值其實是社會性的:因為大家都照同一套慣例,你看到 GET /products/42 就知道會發生什麼,不必讀文件。作者說「今天的 REST API 其實都不 RESTful」講的正是那些為了實務而破例的部分。

相關術語: URI (定位資源)、CRUD (映射自)

出處:第 10 段「REST:把 HTTP 標準化」

URI

統一資源識別碼

唯一標示一個資源的字串,在 REST 裡就是那個以複數名詞構成的路徑。

REST 的慣例是路徑只放名詞、動作交給 HTTP 動詞,所以 /getProduct?id=42 是 RPC 風格而 GET /products/42 才是 REST。巢狀路徑表達從屬關係(/products/42/prices),但層數超過兩層通常代表模型該重新切了。URL 是 URI 的子集,日常對話裡兩者常互換使用。

相關術語: REST (核心元素)、query parameter (附加於)

出處:第 10 段「REST:把 HTTP 標準化」

CRUD

增查改刪

建立、讀取、更新、刪除這四種基本資料操作的合稱。

REST 之所以好記,是因為它幾乎就是 CRUD 的 HTTP 化:CREATE→POST、READ→GET、UPDATE→PUT/PATCH、DELETE→DELETE。它的極限也在這裡——真實系統有很多操作不是 CRUD(結帳、退款、重新寄送驗證信),硬要塞進資源模型就會出現 POST /orders/42/refunds 這種折衷,或者乾脆退回 RPC 風格。

相關術語: REST (映射到)

出處:第 10 段「REST:把 HTTP 標準化」

query parameter

查詢參數

URI 問號之後的鍵值對,用來對同一個資源集合做篩選、排序與分頁。

判準是:改變「哪一個資源」用路徑,改變「這個集合怎麼呈現」用查詢參數。所以 /products/42 是路徑,而 ?page=1&page_size=10&name=keyboard 是查詢參數。因為它是 URL 的一部分,快取可以直接以它為鍵——這是 REST 相對於單一端點 POST 查詢(例如 GraphQL)的一個實際優勢。

相關術語: URI (附加於)

出處:第 10 段「REST:把 HTTP 標準化」

idempotency

冪等性

同一個請求執行一次與執行多次,伺服器的最終狀態相同。

GET、PUT、DELETE 在規範上是冪等的,POST 不是——這正是「重新整理付款頁面會不會重複扣款」背後的機制。因為網路會逾時、客戶端會重試,實務上處理付款這類操作時會另外加一個 Idempotency-Key 標頭,讓伺服器辨識出這是同一次請求的重送。它是分散式系統裡最實用的性質之一:有了它,重試才是安全的。

相關術語: CRUD (約束其動詞)

出處:第 10 段「REST:把 HTTP 標準化」

留給下一段 這套規則有個隱含假設:只有一種客戶端。一旦要同時服務桌面與手機,它就開始出現裂縫。

11. Under-fetch 與 Over-fetch 28:51–30:23

REST 在單一客戶端時很好,但同時要服務桌面與行動端就出問題。桌面畫面大、資料多,一個視圖得打十幾個端點才湊得齊,這叫 under-fetching;行動端畫面小、流量有限,若沿用桌面端點就會拿回一堆不顯示的 JSON,這叫 over-fetching。兩個問題方向相反,卻都源自「端點的形狀由後端決定,前端只能將就」。

桌面單一視圖打出數十個請求的圖,是 under-fetching 的具體樣子
29:15 · 桌面單一視圖打出數十個請求的圖,是 under-fetching 的具體樣子
行動端沿用桌面端點導致多拿資料的對照圖,看出 over-fetching 的浪費
30:00 · 行動端沿用桌面端點導致多拿資料的對照圖,看出 over-fetching 的浪費
承上 上一段結尾說 REST 在多客戶端時會出現裂縫,這一段把裂縫的兩個方向講清楚。

推理因為端點的形狀由後端決定,所以每種客戶端只能將就。桌面畫面大、清單與詳情混在一起,一個視圖要打十幾個端點才湊得齊資料,這是 under-fetching;手機畫面小、流量與電量都有限,沿用桌面端點就會拿回一堆根本不會顯示的 JSON,這是 over-fetching。作者刻意讓兩張圖並排:同一組端點,一邊嫌不夠、一邊嫌太多。

AI 補充這兩個詞常被當成「請求太多」與「資料太大」的別名,但它們真正的共同根源是控制權的位置——欄位由誰決定。在 REST 裡的常見解法是替每個畫面另開一個端點(/products/mobile-list),短期有效,代價是端點數量爆炸、而且已經不再是 RESTful 設計;作者說「今天的 REST API 其實都不 RESTful」指的就是這種折衷。認清楚問題是控制權而不是效能,才會理解下一步為什麼要換一整層。

under-fetching

取得不足

單一端點給不了畫面需要的全部資料,只好連續發多個請求補齊。

它最痛的地方不是流量而是延遲,而且常常是串行的:先拿產品清單,才知道要拿哪些價格,再依價格拿促銷。每一跳都要付一次網路來回,在行動網路上動輒累積成秒級。前端常見的補救是併發請求與預先載入,但那只是把症狀壓下去,端點形狀不對這件事沒有變。

相關術語: over-fetching (相反)、REST (其副作用)

出處:第 11 段「Under-fetch 與 Over-fetch」

over-fetching

取得過多

端點回傳的資料遠多於畫面實際會用到的部分。

浪費的不只是頻寬,還有伺服器序列化與客戶端解析的時間,在低階手機上後者往往更明顯。它跟 under-fetching 常常同時發生在同一個 App 的不同畫面,因為兩者是同一個原因(端點為別人設計)的兩種表現,所以個別修端點永遠修不完。

相關術語: under-fetching (相反)

出處:第 11 段「Under-fetch 與 Over-fetch」

留給下一段 如果問題出在「欄位由後端決定」,那把決定權交給前端會發生什麼事?

12. GraphQL:前端自己決定要什麼 30:23–32:13

2013 年 Facebook 為了同一組問題做出 GraphQL 並開源:一個資料層,讓前端用一次查詢跨多個資源、明確指定要哪些欄位,同時解掉 under-fetching 與 over-fetching。桌面把十幾個 REST 請求收斂成一次查詢,行動端只要改查詢就拿更少資料。附帶好處是 GraphQL 本身有型別,前端不必額外加工具就能寫型別安全的程式碼。

一次 GraphQL 查詢取回巢狀多資源的畫面,對照上一段的多次 REST 請求
30:45 · 一次 GraphQL 查詢取回巢狀多資源的畫面,對照上一段的多次 REST 請求
手機清單 → 一次 GraphQL 查詢的對照,前端自己列出要的欄位
31:40 · 手機清單 → 一次 GraphQL 查詢的對照,前端自己列出要的欄位
承上 上一段結尾問「把欄位的決定權交給前端會怎樣」,GraphQL 就是 Facebook 給出的答案。

推理因為那兩個問題同源,所以一個解法就能同時解掉:GraphQL 是一層資料層,前端用一次查詢跨多個資源、並明確列出要哪些欄位。桌面把十幾個 REST 請求收斂成一次查詢,under-fetching 消失;手機只要改查詢就拿更少資料,over-fetching 消失。附帶好處是 schema 本身有型別,前端不必另外接工具就能寫型別安全的程式碼——REST 要做到同一件事得再加一層 OpenAPI 之類的工具鏈。作者也指出這才是它真正發光的場景:多種客戶端各要各的資料。

AI 補充需要補上的是代價。把查詢形狀交給前端,等於讓「會有哪些查詢被送出」變成執行期才知道:快取不再能像 REST 那樣以 URL 為鍵(GraphQL 通常是對同一個 /graphql 端點發 POST),伺服器也必須加上查詢深度與複雜度限制,否則一個惡意的巢狀查詢就能拖垮服務。控制權的轉移從來不是免費的,這一點在下一段會用更具體的方式現形。

GraphQL

圖形查詢語言

由客戶端以查詢明確指定所需欄位、可一次跨多個資源取得資料的 API 查詢語言與執行層。

它由 Facebook 在 2012 年為了行動版 App 內部開發,2015 年開源。要注意它不是資料庫查詢語言——欄位背後可能是資料庫、也可能是別的微服務或第三方 API,由 resolver 決定。它適合「多種客戶端、資料關聯複雜」的場景;如果只有一個 Web 客戶端、資料模型也單純,REST 通常仍是成本更低的選擇。

相關術語: under-fetching (解決)、over-fetching (解決)、schema (以其為契約)

出處:第 12 段「GraphQL:前端自己決定要什麼」

schema

結構定義

以型別描述 API 提供哪些資料與操作的契約,前後端都以它為準。

在 GraphQL 裡 schema 是強制的:伺服器必須宣告每個型別與欄位,客戶端才查得動。好處是工具鏈可以從它自動產生型別、自動補完、甚至驗證查詢,這就是作者說的「開箱即用的開發工具」。它同時也是一份永遠不會過期的文件——因為程式跑不動的話它就先壞了。

相關術語: GraphQL (其契約)

出處:第 12 段「GraphQL:前端自己決定要什麼」

留給下一段 把決定權交給前端之後,後端要怎麼把那一次查詢變成資料庫操作?這裡藏著一個會把資料庫打爆的陷阱。

13. N+1 問題與 DataLoader 32:13–34:17

但 GraphQL 帶來新問題:查 24 個產品時,伺服器先查清單再逐一查細節,變成 24+1 次 SQL,客戶端一多就把資料庫打爆,效能反而比 REST 差。解法是用 DataLoader 這類函式庫做 batching:把同一輪的 id 收集起來合成一次較大的查詢再送出。作者強調重點不是實作細節,而是「凡是要聚合多筆查詢,就必須有一層批次化的機制」。

那一次 ProductList 查詢本身,下一張圖會展開它在資料庫端的代價
32:35 · 那一次 ProductList 查詢本身,下一張圖會展開它在資料庫端的代價
同一次查詢展開成 1+24 次 SELECT,右邊是解法 graphql/dataloader
33:32 · 同一次查詢展開成 1+24 次 SELECT,右邊是解法 graphql/dataloader
承上 上一段結尾預告了「那一次查詢在資料庫端的代價」,這一段就是那個陷阱。

推理因為一次 GraphQL 查詢可能展開成多層巢狀,所以 resolver 很容易先查一次清單(1),再為每一筆各查一次細節(N):24 個產品就變成 25 次 SQL。作者強調這時的效能會比原本的 REST 還差,等於白換一套架構。解法是用 DataLoader 這類函式庫做 batching:把同一輪收集到的 id 合併成一次較大的查詢再送出。他刻意不講實作細節,而是留下一條通則——凡是要聚合多筆查詢,就必須有一層批次化的機制。

AI 補充補上作者跳過的機制:DataLoader 利用事件迴圈的一個 tick 把這一輪所有的 .load(id) 收集起來,在 tick 結束時合併成一次 SELECT ... WHERE id IN (...),並且在同一次請求內對相同 id 去重與快取。也因為它「以請求為單位」,正確用法是每個請求 new 一個新的 DataLoader,跨請求共用會讓使用者看到別人的舊資料——這是實務上最常踩的雷。順帶一提,N+1 不是 GraphQL 的專利,ORM 的 lazy loading 產生的是一模一樣的問題。

術語:N+1 problem

N+1 problem

N+1 查詢問題

取得 N 筆資料時先查一次清單、再為每筆各查一次,總共送出 N+1 次查詢。

它的隱蔽之處在於本機開發完全看不出來:24 筆資料在本機資料庫也就多幾毫秒,上線後資料變成幾千筆、又有幾百個並發使用者,資料庫就被打爆了。診斷方法很直接——把 SQL 記錄打開,看一次 API 請求送出幾條查詢。它同時是 GraphQL resolver 與 ORM lazy loading 的共同陷阱。

相關術語: DataLoader (被其解決)、GraphQL (常見於)

出處:第 13 段「N+1 問題與 DataLoader」

DataLoader

批次載入器

把同一輪的多次單筆查詢自動合併成一次批次查詢的工具函式庫。

由 Facebook 開源,介面只有 load(key) 與 loadMany(keys),但你必須自己提供 batch 函式:給一組 id、回傳對應順序的一組結果,順序對不上就會拿到別人的資料。它同時做了兩件事——批次化與請求內快取,後者讓同一次查詢裡重複出現的 id 只查一次。務必每個請求建立新實例。

相關術語: batching (實作)、N+1 problem (解決)

出處:第 13 段「N+1 問題與 DataLoader」

batching

批次化

把短時間內的多個小請求合併成一個大請求再送出。

這是分散式系統裡最泛用的技巧之一,用固定的每次呼叫成本換取一點延遲:資料庫查詢、日誌上傳、指標回報、甚至 React 的狀態更新都用同一招。它的孿生兄弟是 debounce(等一下再做)與 coalescing(相同請求只做一次),三者常常一起出現。

相關術語: DataLoader (應用於)

出處:第 13 段「N+1 問題與 DataLoader」

留給下一段 資料層的問題解決了,但這些微服務各自都要處理認證、SSL、限流……前端每接一個新的資料來源就要重新面對一次。

14. API Gateway:重複的事只做一次 34:17–37:20

視角拉到架構層:微服務各自實作認證、SSL、rate limiting、快取這些重複的邊緣功能,非常浪費。API Gateway 是一種 reverse proxy——proxy 代表客戶端(例如 VPN),reverse proxy 代表伺服器——它坐在服務前面,把邊緣功能集中做一次再把請求轉給對應微服務。額外好處是憑證只需要買一張,Gateway 之後在私有雲內走 HTTP 就好,省掉每次至少五個來回的 TLS 交握。

proxy 與 reverse proxy 的方向對照圖,這是本段唯一的概念關卡
34:40 · proxy 與 reverse proxy 的方向對照圖,這是本段唯一的概念關卡
Rate Limiter / Auth / Caching 三個 edge function 擋在微服務前面
35:40 · Rate Limiter / Auth / Caching 三個 edge function 擋在微服務前面
Amazon API Gateway 的架構圖,看到雲廠商把這件事包成一個服務
36:18 · Amazon API Gateway 的架構圖,看到雲廠商把這件事包成一個服務
承上 上一段結尾點出每個微服務都要重複處理認證與限流,這一段就把那些重複抽出來。

推理因為每個微服務都得自己實作 rate limiter、認證中介層與快取,而這些邏輯彼此幾乎一樣,所以作者引入 API Gateway——一種 reverse proxy。他先把兩個方向分清楚:proxy 代表客戶端(例如 VPN,伺服器以為請求來自代理),reverse proxy 代表伺服器(負載平衡器、API Gateway,客戶端以為它就是伺服器)。Gateway 坐在服務前面,把這些 edge function 集中做一次,再把請求轉給對應的微服務。附帶好處是憑證只要買一張,Gateway 之後在 VPC 內走 HTTP 就好,省掉每次連線的 TLS 交握。他也提醒這東西可以在雲上一鍵買到,也可以用 nginx 加 Docker 自己搭。

AI 補充「內網走 HTTP 沒關係」這個結論值得標註前提:它成立的條件是你信任 VPC 內的所有東西。零信任(zero trust)架構的主流建議正好相反——服務之間仍應以 mTLS 互相驗證,因為一旦有一台被攻陷,平坦的內網就無險可守。在小團隊或單一雲帳號裡作者的做法沒問題,但這是個有前提的取捨,不是普遍原則。另外 Gateway 集中做認證也意味著它成為新的攻擊面與設定錯誤的單一來源,這在下一段會以另一種形式回來。

API Gateway

API 閘道

坐在所有後端服務前面、集中處理認證、限流、快取與路由的反向代理。

它是微服務架構幾乎必然的產物:服務一多,客戶端不可能記住每個服務在哪、也不該對每個服務各做一次認證。雲上(AWS API Gateway、Cloudflare、Kong)與自建(nginx、Envoy)都很成熟。要注意它容易變成「什麼都塞」的垃圾場——業務邏輯一旦寫進 Gateway,就成了所有團隊都要排隊修改的瓶頸。

相關術語: reverse proxy (一種)、edge function (集中執行)

出處:第 14 段「API Gateway:重複的事只做一次」

reverse proxy

反向代理

代表伺服器接收請求的中間層,客戶端只看得到它,看不到後面真正的服務。

它是同一個機制的兩種用法之一:正向代理保護/代表客戶端,反向代理保護/代表伺服器。因為所有流量都經過它,它是加 TLS 終結、壓縮、快取、A/B 導流、藍綠部署最自然的位置。nginx、HAProxy、Envoy 都是常見實作,CDN 本質上也是分佈在全球的反向代理。

相關術語: proxy (相反方向)、API Gateway (其應用)

出處:第 14 段「API Gateway:重複的事只做一次」

proxy

代理

代表客戶端發出請求的中間層,伺服器看到的是代理而不是真正的來源。

VPN 與企業內網的出口代理是最常見的例子:伺服器記錄到的 IP 是代理的 IP。它常被用來隱藏來源、繞過地理限制或在企業裡統一稽核出站流量。分辨正向與反向代理最快的方法是問一句:它是為誰工作的。

相關術語: reverse proxy (相反方向)

出處:第 14 段「API Gateway:重複的事只做一次」

edge function

邊緣功能

與業務邏輯無關、每個服務都需要的橫切功能,例如認證、限流、SSL 終結、快取。

作者用這個詞指的是「該在邊界做一次的事」。判斷標準很簡單:如果每個微服務的這段程式碼幾乎一模一樣,它就該往上提到 Gateway。反過來說,任何需要知道業務規則(這個使用者能不能買這件商品)的邏輯都不屬於這裡——那是服務自己的責任。

相關術語: API Gateway (執行於)

出處:第 14 段「API Gateway:重複的事只做一次」

microservice

微服務

把系統拆成多個各自獨立部署、各自擁有資料的小型服務。

它換到的是團隊自主:各團隊可以獨立開發、部署、擴展自己的服務。代價是原本的函式呼叫變成網路呼叫,於是延遲、部分失敗、資料一致性全部浮上檯面。作者提到自己待過有 300 個微服務的公司,那正是這個代價的極端形式——技術上可以獨立,組織上反而更難協調。

相關術語: API Gateway (被其統一入口)

出處:第 14 段「API Gateway:重複的事只做一次」

VPC

虛擬私有雲

雲端上一段與公網隔離、你自己控制網路規則的私有網段。

把資料庫與內部服務放進 VPC、只讓 Gateway 或負載平衡器對外,是雲上最基本的分層防禦。作者說「VPC 內沒有中間人攻擊的機會」是相對於公網而言;實務上仍要靠安全群組、私有子網與最小權限把爆炸半徑再切小。

相關術語: API Gateway (置於其前)

出處:第 14 段「API Gateway:重複的事只做一次」

見仁見智 36:39
「the TLS handshake which takes at least five round trips to the network」
這是 TLS 1.2 以前(含 TCP 三次交握)的粗估。TLS 1.3 已把完整交握壓到 1-RTT,對曾連過的伺服器還能 0-RTT 續傳。作者用這個數字論證「Gateway 之後走 HTTP 比較快」,結論方向仍成立,但省下的幅度被高估了。
依據: RFC 8446 (TLS 1.3, 2018)
留給下一段 技術上的重複被消掉了,但要出一個功能仍然要跟一堆團隊協調——瓶頸其實已經不在程式碼裡了。

15. BFF:前端擁有自己的後端 37:20–40:21

技術問題解決了,組織問題還在:前端要出一個功能,得同時和平台團隊、產品團隊、物流團隊協調,各自有各自的 backlog,作者待過有 300 個微服務的公司。BFF(Backend For Frontend)是另一個 reverse proxy,但為特定前端而建、且由前端團隊自己擁有,通常用 GraphQL 做成專屬資料層。這正是前端要懂全端的原因——BFF 是前端工程師自己要擴充的;行動端也能有自己的 BFF,架構因此在「人」的層面可擴展。

各服務分屬不同團隊的擁有權圖,說明瓶頸其實是組織不是技術
38:05 · 各服務分屬不同團隊的擁有權圖,說明瓶頸其實是組織不是技術
BFF 坐在前端與微服務之間、由前端團隊擁有的架構圖
39:00 · BFF 坐在前端與微服務之間、由前端團隊擁有的架構圖
桌面與行動端各有一套 BFF 的圖,呈現「以團隊為單位擴展」的結果
39:55 · 桌面與行動端各有一套 BFF 的圖,呈現「以團隊為單位擴展」的結果
承上 上一段結尾指出瓶頸已從技術轉到組織,這一段就直接處理組織。

推理因為每個微服務屬於不同團隊、各有各的 backlog 與產品經理,前端要出一個功能得同時協調平台團隊、產品團隊、物流團隊——作者說他待過有 300 個微服務的公司,光是實作一個功能就足以令人抓狂。所以他引入 BFF:同樣是 reverse proxy,但為特定前端而建、而且由前端團隊自己擁有,通常用 GraphQL 做成專屬資料層。這也是整支影片的落點——前端要懂全端,正是因為 BFF 本來就該由前端工程師自己擴充。手機端可以有自己的 Mobile BFF,於是架構在「人」的維度上終於可以擴展。

AI 補充值得補的是 BFF 的邊界。它該做的是聚合與裁剪:呼叫多個微服務、拼成這個畫面需要的形狀。它不該做的是塞進商業規則——一旦訂價或庫存邏輯寫進 BFF,你就把剛拆開的耦合又搬回來了,而且是搬到前端團隊身上。另一個常被低估的成本是:每多一個 BFF 就多一個要部署、監控、值班的服務,而承擔的人就是原本只寫前端的那個團隊。這是自主權的價碼,不是附贈品。

Backend For Frontend

為前端而生的後端(BFF)

為某一個前端客戶端量身打造、並由該前端團隊自己擁有的後端聚合層。

它與 API Gateway 的差別是「為誰服務」:Gateway 是全公司共用的入口,BFF 是某個客戶端專屬的資料層,所以 Web 與 Mobile 各有一個是正常的,而不是重複。判斷該不該建 BFF 的訊號很明確——前端每次改畫面都要等別的團隊改端點。它的失敗模式同樣明確:變成一個沒人敢動的巨大聚合層,或悄悄長出商業邏輯。

相關術語: API Gateway (位於其後)、GraphQL (常用實作)

出處:第 15 段「BFF:前端擁有自己的後端」

留給下一段 但所有流量仍然全部穿過同一個 API Gateway——它現在同時是壓力來源,也是單點故障。

16. 負載平衡:消除單點故障 40:21–41:57

但所有流量都經過 API Gateway,它同時變成壓力來源與單點故障。做法是把單一實例換成一群相同的實例加一台負載平衡器(LB),依演算法分流,某一台掛掉整體也不會倒,還能吃下更大的流量。最常見的演算法是 round-robin 輪流分派,另一種 least connections 則把流量送給連線數最少的實例,等於讓分流跟著實例的實際負載走。

Load Balancing 的定義與兩種演算法(round robin、least active connections)
40:48 · Load Balancing 的定義與兩種演算法(round robin、least active connections)
LB 把流量輪流分給三個 instance 的圖,看到單點故障如何被拆掉
41:22 · LB 把流量輪流分給三個 instance 的圖,看到單點故障如何被拆掉
承上 上一段結尾把 API Gateway 標成單點故障,這一段給出解法。

推理因為單一實例既有容量上限也有故障風險,所以作者把它換成一組相同的實例加一台負載平衡器:LB 依演算法把流量分給各實例,某一台掛掉整體仍然活著,總吞吐量也跟著堆疊。最常見的演算法是 round-robin(依序輪流),另一種 least connections 則把流量送給當下連線數最少的實例,等於讓分流跟著實例的實際負載走。講到這裡,整條路徑從第一個 TCP 封包一路走到了一整套可擴展的架構,作者也就收尾了。

AI 補充兩件作者沒說、但你一動手就會遇到的事。第一,能這樣水平擴展的前提是實例無狀態:session 一旦存在記憶體裡,使用者被分到另一台就等於登出,於是只能改用 sticky session(把人綁在同一台,代價是分流不均)或把 session 外置到 Redis。第二,LB 自己也是單點,雲上的做法是交給託管服務(跨可用區部署,再由 DNS 層做一次分散),否則你只是把單點往前挪了一格。健康檢查則是這一切的前提——LB 必須先知道哪台掛了,才有辦法不把流量送過去。

load balancing

負載平衡

依演算法把進來的流量分配給多個相同的服務實例。

它一次買到兩件事:容量(多台一起扛)與可用性(掛一台不影響整體)。分成 L4(看 IP 與埠,快)與 L7(看 HTTP 內容,可依路徑或標頭路由,功能多)兩種,API Gateway 通常屬於後者。真正讓它有效的是健康檢查:LB 定期探測每個實例,失敗就把它從輪替中移除,恢復再放回來。

相關術語: round robin (其演算法)、single point of failure (消除)

出處:第 16 段「負載平衡:消除單點故障」

round robin

輪流分派

把請求依固定順序輪流送給每個實例的最簡單分流演算法。

它假設所有實例效能相同、所有請求成本相同,兩個假設在真實系統裡常常不成立——一個慢查詢會讓某台實例塞住,但輪流分派照樣把下一個請求送過去。加權輪流(weighted round robin)可以讓規格較好的機器多拿一些,是最常見的改良。

相關術語: least connections (對照組)、load balancing (屬於)

出處:第 16 段「負載平衡:消除單點故障」

least connections

最少連線數

把新請求送給當下開啟連線數最少的實例。

它比輪流分派更貼近真實負載,因為連線數本身就反映了實例目前忙不忙——處理得慢的機器連線會堆積,自然分到比較少新請求。適合請求耗時差異大的服務(例如有長查詢也有快取命中)。代價是 LB 必須維護每個實例的即時狀態,成本稍高。

相關術語: round robin (對照組)

出處:第 16 段「負載平衡:消除單點故障」

single point of failure

單點故障

系統中一旦失效就會導致整體不可用的元件。

找出它的方法是逐一問「這個掛掉會怎樣」:Gateway、資料庫主節點、DNS、憑證到期、甚至只有一個人知道怎麼部署,都是單點。消除它的手段永遠是同一組——冗餘(多份)、自動故障轉移(發現壞了自動換)、以及優雅降級(部分失效時仍提供核心功能)。要注意每加一層冗餘就多一層複雜度,所以要先確認這個單點值得處理。

相關術語: load balancing (被其緩解)、API Gateway (常見案例)

出處:第 16 段「負載平衡:消除單點故障」

留給下一段 總結收束

4. 總結

整支影片是一條由缺口推動的直線。HTTP 建立了「一問一答」的基本模型,但請求需要 IP,於是有 DNS;IP 本身受限於實體線路與位址稀缺,於是往下看見封包與 IPv6。既然跨網路有成本,就用快取(max-age + ETag)省掉那趟路;既然連線是明文,就用 TLS 把它包起來,並在非對稱與對稱加密之間換手。到這裡「安全地取回一份資源」完整了,但 HTTP 只能由客戶端發問,於是 polling → WebSocket → SSE 構成一個由土到精緻的即時通訊梯度,而 SSE 正好是今天所有 LLM 串流介面的底層。接著焦點從「怎麼傳」換到「請求長什麼樣」:RPC 讓請求像呼叫函式卻把兩端綁死(它今天以 MCP 的形式回到 AI 場景),REST 用資源與動詞換來可預測性,卻在同時服務桌面與手機時裂成 under-fetching 與 over-fetching;GraphQL 把欄位的決定權交給前端而解掉兩者,代價是 N+1,再由 DataLoader 的批次化補上。最後兩層離開程式碼:API Gateway 把各微服務重複的認證、限流、SSL 抽出來做一次;BFF 讓前端團隊擁有自己的資料層,繞開跨團隊協調這個真正的瓶頸;而全部流量集中之後產生的單點故障,由負載平衡收尾。所以「前端要懂全端」在這支影片裡不是口號,而是一個結構性的結論:BFF 本來就該由前端自己擴充,而你得看得懂它前後每一層。

勘誤總整理

確定錯誤/已過時見仁見智(取決於版本或情境)

段落原話(transcript 逐字)說明
4. HTTP 快取與 E-Tag
12:29
「Now that number it's in milliseconds.」Cache-Control 的 max-age 單位是「秒」,不是毫秒。畫面上的 max-age=31536000 當成秒剛好是一年(也是規範建議的上限用法);若真是毫秒就只有約 8.7 小時,跟旁邊 age=672803 已經超過七天卻仍算新鮮的事實直接矛盾。
依據: RFC 9111 §5.2.2.1 max-age:delta-seconds
3. IP:機器之間如何找到彼此
9:26
「so expensive around the 2000 people came up with the idea of IPv6」把 IPv6 的提出時間推晚了大約五年。IPv6 的第一份規格 RFC 1883 在 1995 年就發布,1998 年由 RFC 2460 定稿,並非「2000 年左右才有這個想法」。作者要表達的「因為位址枯竭才做 IPv6」這個因果本身是對的。
依據: RFC 1883 (1995-12)、RFC 2460 (1998-12)
5. TLS:為什麼要換兩種加密
14:14
「in order to prevent this in 1996 which is basically 30 years ago Netscape」Netscape 的 SSL 2.0 在 1995 年就隨 Navigator 出貨(SSL 1.0 從未公開),SSL 3.0 才是 1996;標準化並改名為 TLS 1.0 則要到 1999 年的 RFC 2246。說「1996 年 Netscape 提出 HTTPS」大方向沒錯,時間點略晚一年。
依據: SSL 2.0 (1995)、SSL 3.0 (1996)、RFC 2246 TLS 1.0 (1999)
9. RPC / tRPC 與 MCP
24:26
「it was only probably 7 months ago. So, this stuff is pretty recent.」這是錄影當下的相對時間,現在讀會誤導。MCP 由 Anthropic 在 2024 年 11 月發布並開源,至今已超過一年,且已被多家 AI 廠商與 IDE 採用,不再是「剛出來七個月」的實驗性東西。
依據: Model Context Protocol 公開發布:2024-11
14. API Gateway:重複的事只做一次
36:39
「the TLS handshake which takes at least five round trips to the network」這是 TLS 1.2 以前(含 TCP 三次交握)的粗估。TLS 1.3 已把完整交握壓到 1-RTT,對曾連過的伺服器還能 0-RTT 續傳。作者用這個數字論證「Gateway 之後走 HTTP 比較快」,結論方向仍成立,但省下的幅度被高估了。
依據: RFC 8446 (TLS 1.3, 2018)

5. 推薦三個下一步

1. 往下挖深:TLS 交握與 HTTP/2、HTTP/3 的實際成本

影片用「至少五個網路來回」論證 Gateway 之後可以走 HTTP,但這是 TLS 1.2 以前的數字。搞清楚 TLS 1.3 的 1-RTT/0-RTT,以及 HTTP/2 多工與 HTTP/3 走 QUIC 之後連線成本的變化,才能判斷這類架構取捨今天還成不成立。

YouTube 搜尋:TLS 1.3 handshake explained HTTP/3 QUIC vs HTTP/2 TLS handshake round trips 0-RTT

2. 往旁邊對照:GraphQL 之外的選項與它的真實代價

影片把 GraphQL 當成 under/over-fetching 的解答,但沒談它在快取、查詢複雜度攻擊與伺服器複雜度上的代價,也沒提 tRPC 之外的同類方案。把 REST + OpenAPI、GraphQL、gRPC-Web 放在一起比較,才知道什麼時候不該用 GraphQL。

YouTube 搜尋:GraphQL vs REST tradeoffs GraphQL caching problems when not to use GraphQL

3. 往上應用:自己動手做一個 BFF

BFF 是整支影片的落點,也是最需要動手才會懂的一段——聚合幾個公開 API、決定要不要用 GraphQL、處理部署與監控,才會體會到作者說的「自主權有價碼」。

YouTube 搜尋:Backend for Frontend pattern tutorial BFF pattern Node.js GraphQL BFF architecture

📄 全部影片 · 主題區: 網路與 API 基礎