<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Grpc on Tarragon</title><link>https://tarrragon.github.io/blog/tags/grpc/</link><description>Recent content in Grpc on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 03 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/grpc/index.xml" rel="self" type="application/rss+xml"/><item><title>11.C28 protobuf 官方規範：field number 紀律</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-protobuf-field-number-discipline/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-protobuf-field-number-discipline/</guid><description>&lt;p>這個案例的核心責任是提供 proto 演進紀律的規範錨點。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>官方語言規範明文：field number 一旦訊息投入使用即不可變更、因為它就是 wire format 的欄位識別；刪欄位後必須 reserve 該編號、重用編號會使 wire 解碼歧義、後果列舉包括 parse / merge error、PII 洩漏、資料損毀。文件把 schema 變更分三類：wire-unsafe、wire-safe（加欄位、加 enum 值、刪欄位皆安全）、conditionally wire-compatible。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>契約相容性在 protobuf 是編碼格式的數學性質、不是 code review 慣例 —「加法演進 + 編號永不回收」是 protobuf 相對 JSON schema 的核心工程差異、也是所有 breaking-change 工具（C29）存在的前提。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>styles/grpc/「proto 演進紀律」（anchor）、11.6 向後相容的變更紀律交叉。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://protobuf.dev/programming-guides/proto3/">Language Guide (proto 3)（Protocol Buffers 官方文件）&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供 proto 演進紀律的規範錨點。</p>
<h2 id="觀察">觀察</h2>
<p>官方語言規範明文：field number 一旦訊息投入使用即不可變更、因為它就是 wire format 的欄位識別；刪欄位後必須 reserve 該編號、重用編號會使 wire 解碼歧義、後果列舉包括 parse / merge error、PII 洩漏、資料損毀。文件把 schema 變更分三類：wire-unsafe、wire-safe（加欄位、加 enum 值、刪欄位皆安全）、conditionally wire-compatible。</p>
<h2 id="判讀">判讀</h2>
<p>契約相容性在 protobuf 是編碼格式的數學性質、不是 code review 慣例 —「加法演進 + 編號永不回收」是 protobuf 相對 JSON schema 的核心工程差異、也是所有 breaking-change 工具（C29）存在的前提。</p>
<h2 id="對應大綱">對應大綱</h2>
<p>styles/grpc/「proto 演進紀律」（anchor）、11.6 向後相容的變更紀律交叉。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://protobuf.dev/programming-guides/proto3/">Language Guide (proto 3)（Protocol Buffers 官方文件）</a></li>
</ul>
]]></content:encoded></item><item><title>11.C29 Buf breaking detection：四級規則對應消費者依賴</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-buf-breaking-detection/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-buf-breaking-detection/</guid><description>&lt;p>這個案例的核心責任是說明相容性檢查如何工具化進 CI、以及檢查粒度的選擇邏輯。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>&lt;code>buf breaking&lt;/code> 對比歷史版本 schema、在 merge 前擋下如「Field 1 type int32 改 string」這類變更；規則分四級（FILE、PACKAGE、WIRE_JSON、WIRE、嚴格包含寬鬆）。文件明言「Catching this before merge is the point」、並指出破壞發生在多層 — 改名破壞 generated code、改 type 破壞 wire format — 人工 review 抓不全。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>這是 C28 紀律從「人的自律」升級成 CI gate 的論證。四級規則的核心主張：「選符合消費者實際依賴的等級」— 只走 wire 的消費者用 WIRE、有外部 Go import 的要 PACKAGE。教學重點是「相容性檢查粒度是產品決策、不是工具預設」。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>11.6 向後相容的變更紀律（工具層 anchor、已引用）、styles/grpc/「proto 演進紀律」、11.10 API 規範治理（linting 進 CI）交叉。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://buf.build/docs/breaking/">Breaking change detection（Buf 官方文件）&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明相容性檢查如何工具化進 CI、以及檢查粒度的選擇邏輯。</p>
<h2 id="觀察">觀察</h2>
<p><code>buf breaking</code> 對比歷史版本 schema、在 merge 前擋下如「Field 1 type int32 改 string」這類變更；規則分四級（FILE、PACKAGE、WIRE_JSON、WIRE、嚴格包含寬鬆）。文件明言「Catching this before merge is the point」、並指出破壞發生在多層 — 改名破壞 generated code、改 type 破壞 wire format — 人工 review 抓不全。</p>
<h2 id="判讀">判讀</h2>
<p>這是 C28 紀律從「人的自律」升級成 CI gate 的論證。四級規則的核心主張：「選符合消費者實際依賴的等級」— 只走 wire 的消費者用 WIRE、有外部 Go import 的要 PACKAGE。教學重點是「相容性檢查粒度是產品決策、不是工具預設」。</p>
<h2 id="對應大綱">對應大綱</h2>
<p>11.6 向後相容的變更紀律（工具層 anchor、已引用）、styles/grpc/「proto 演進紀律」、11.10 API 規範治理（linting 進 CI）交叉。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://buf.build/docs/breaking/">Breaking change detection（Buf 官方文件）</a></li>
</ul>
]]></content:encoded></item><item><title>11.C30 Buf Connect 發布文：對 grpc-go 的系統性批評</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-buf-connect-critique/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-buf-connect-critique/</guid><description>&lt;p>這個案例的核心責任是提供 gRPC 部署邊界的完整批評清單。Buf 是利益相關方、引用時標明；但 trailers 與瀏覽器不相容是可獨立驗證的協議事實。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>發布文指 grpc-go 有 13 萬行手寫程式碼、近百個設定選項、不用 Go 標準庫而自帶 HTTP/2 實作、導致無法與其他 HTTP 流量共存；gRPC 協議要求端到端 HTTP/2 加 trailers、瀏覽器支援需要翻譯 proxy；不遵守 semver、debug 時連 &lt;code>curl | jq&lt;/code> 都不可行。Connect 的對案：建在 net/http 上、同時支援 gRPC / gRPC-Web / Connect 三協議。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>gRPC 的部署邊界（瀏覽器、proxy、trailers）是風格選型時常被忽略的維度 — 協議能力表不會列「你的 LB 過不過 trailers」。與 C32 的獨立批評互證後、批評點的可信度不依賴 Buf 的立場。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>styles/grpc/「streaming 語意與部署邊界」（anchor）、11.2 風格選型（操作可及性軸、已引用）。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://buf.build/blog/connect-a-better-grpc">Connect: a better gRPC（Buf blog）&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供 gRPC 部署邊界的完整批評清單。Buf 是利益相關方、引用時標明；但 trailers 與瀏覽器不相容是可獨立驗證的協議事實。</p>
<h2 id="觀察">觀察</h2>
<p>發布文指 grpc-go 有 13 萬行手寫程式碼、近百個設定選項、不用 Go 標準庫而自帶 HTTP/2 實作、導致無法與其他 HTTP 流量共存；gRPC 協議要求端到端 HTTP/2 加 trailers、瀏覽器支援需要翻譯 proxy；不遵守 semver、debug 時連 <code>curl | jq</code> 都不可行。Connect 的對案：建在 net/http 上、同時支援 gRPC / gRPC-Web / Connect 三協議。</p>
<h2 id="判讀">判讀</h2>
<p>gRPC 的部署邊界（瀏覽器、proxy、trailers）是風格選型時常被忽略的維度 — 協議能力表不會列「你的 LB 過不過 trailers」。與 C32 的獨立批評互證後、批評點的可信度不依賴 Buf 的立場。</p>
<h2 id="對應大綱">對應大綱</h2>
<p>styles/grpc/「streaming 語意與部署邊界」（anchor）、11.2 風格選型（操作可及性軸、已引用）。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://buf.build/blog/connect-a-better-grpc">Connect: a better gRPC（Buf blog）</a></li>
</ul>
]]></content:encoded></item><item><title>11.C31 Dropbox Courier：百萬 RPS 規模的 gRPC 遷移</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-dropbox-courier/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-dropbox-courier/</guid><description>&lt;p>這個案例的核心責任是提供內部 RPC 選型的規模上限案例。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Dropbox 從 HTTP/1.1 加 protobuf 的自製 RPC 遷移到 gRPC、動機是保留既有 protobuf、取得 multiplexing 與雙向 streaming；在 gRPC 上疊了 mTLS 服務身分、per-method 統計、強制 deadline 傳播、LIFO queue 熔斷。踩雷紀錄：大規模重啟時 TLS 握手成本迫使 RSA 2048 換 ECDSA P-256、且 HTTP/1.1 與 gRPC 要拆成不同 server 處理。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>gRPC 在 Dropbox 的價值是「框架層集中加 infra-wide 可靠性」的載體、不是序列化效能本身 — 選型判準應該看組織要不要這一層集中點。「migration 比初始開發久得多」與 TLS 握手踩雷適合當規模判讀訊號。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>styles/grpc/「內部 RPC 的選型位置」（anchor）、11.2 風格選型（操作可及性軸、已引用）。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://dropbox.tech/infrastructure/courier-dropbox-migration-to-grpc">Courier: Dropbox migration to gRPC（Dropbox tech blog）&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供內部 RPC 選型的規模上限案例。</p>
<h2 id="觀察">觀察</h2>
<p>Dropbox 從 HTTP/1.1 加 protobuf 的自製 RPC 遷移到 gRPC、動機是保留既有 protobuf、取得 multiplexing 與雙向 streaming；在 gRPC 上疊了 mTLS 服務身分、per-method 統計、強制 deadline 傳播、LIFO queue 熔斷。踩雷紀錄：大規模重啟時 TLS 握手成本迫使 RSA 2048 換 ECDSA P-256、且 HTTP/1.1 與 gRPC 要拆成不同 server 處理。</p>
<h2 id="判讀">判讀</h2>
<p>gRPC 在 Dropbox 的價值是「框架層集中加 infra-wide 可靠性」的載體、不是序列化效能本身 — 選型判準應該看組織要不要這一層集中點。「migration 比初始開發久得多」與 TLS 握手踩雷適合當規模判讀訊號。</p>
<h2 id="對應大綱">對應大綱</h2>
<p>styles/grpc/「內部 RPC 的選型位置」（anchor）、11.2 風格選型（操作可及性軸、已引用）。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://dropbox.tech/infrastructure/courier-dropbox-migration-to-grpc">Courier: Dropbox migration to gRPC（Dropbox tech blog）</a></li>
</ul>
]]></content:encoded></item><item><title>11.C32 gRPC: The Bad Parts：cURL 測試不過的 API（反例）</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-kmcd-bad-parts/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/grpc-kmcd-bad-parts/</guid><description>&lt;p>這個案例的核心責任是提供非 vendor 立場的 gRPC 獨立批評、跟 C30 互證。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>批評點：非標準術語（unary RPC）墊高學習曲線、通不過「傳一個 cURL 範例給朋友」測試、瀏覽器無法處理 HTTP trailers 需 gRPC-Web 加 proxy、HTTP/3 採用遲緩、protobuf 要求完整解析整個訊息使大檔處理容易出錯、依賴管理長期無標準。文章同時承認 Buf CLI / ConnectRPC / Postman 支援已改善部分問題。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>「批評 + 承認生態已修補」的平衡結構適合直接當教材敘事骨架。cURL 測試是「debug 可及性」這個選型維度的好判準 — 協議效率表不會告訴你 on-call 時能不能徒手戳一個 endpoint。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>styles/grpc/「內部 RPC 的選型位置」（gRPC 邊界與代價段）、11.2 風格選型（操作可及性軸、已引用）。反例 / 邊緣。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://kmcd.dev/posts/grpc-the-bad-parts/">gRPC: The Bad Parts（Kevin McDonald）&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供非 vendor 立場的 gRPC 獨立批評、跟 C30 互證。</p>
<h2 id="觀察">觀察</h2>
<p>批評點：非標準術語（unary RPC）墊高學習曲線、通不過「傳一個 cURL 範例給朋友」測試、瀏覽器無法處理 HTTP trailers 需 gRPC-Web 加 proxy、HTTP/3 採用遲緩、protobuf 要求完整解析整個訊息使大檔處理容易出錯、依賴管理長期無標準。文章同時承認 Buf CLI / ConnectRPC / Postman 支援已改善部分問題。</p>
<h2 id="判讀">判讀</h2>
<p>「批評 + 承認生態已修補」的平衡結構適合直接當教材敘事骨架。cURL 測試是「debug 可及性」這個選型維度的好判準 — 協議效率表不會告訴你 on-call 時能不能徒手戳一個 endpoint。</p>
<h2 id="對應大綱">對應大綱</h2>
<p>styles/grpc/「內部 RPC 的選型位置」（gRPC 邊界與代價段）、11.2 風格選型（操作可及性軸、已引用）。反例 / 邊緣。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://kmcd.dev/posts/grpc-the-bad-parts/">gRPC: The Bad Parts（Kevin McDonald）</a></li>
</ul>
]]></content:encoded></item></channel></rss>