圖形註冊和數據演變
為什麼需要一個計劃註冊表
模式註冊表是數據合同(API,事件,線程,消息,存儲)的集中真理源,可提供:- 可預測的演變:兼容性規則和「切片」自動驗證。
- 可重復性和透明度:版本,誰/何時/為什麼更改的歷史記錄。
- 標準化:統一名稱、錯誤格式、跟蹤字段、PII標簽。
- 與CI/CD集成:阻止中斷更改直到生產。
註冊表將協議第一和合同互操作性聯系起來,從而使更改變得快速和安全。
格式和應用領域
JSON計劃:REST/HTTP有效載荷、文檔、配置。
Avro:事件總線(Kafka/Pulsar),通過ID字段進行壓縮/演變。
Protobuf:gRPC/RPC,二進制有效,嚴格的標簽。
SDL GraphQL:類型和指令圖,通過「@deprecated」演變。
SQL DDL作為工件:我們捕獲約定的視圖(例如外部店面)-謹慎。
兼容性模式
BACKWARD:新模式讀取舊數據/消息。適合以加法方式擴展付費的制作人。
FORWARD:老消費者正確閱讀新數據(需要tolerant reader)。
FULL:將兩者結合起來(更嚴格,更方便公共合同)。
NONE:沒有檢查-僅適用於沙箱。
- 事件:更常見的是BACKWARD(制作人可選地擴展付費負載)。
- 公共API:客戶端上的FULL或BACKWARD+嚴格的tolerant閱讀器。
- 內部原型:暫時NONE,但不在trunk上。
安全(加法)vs.危險變化
加法(OK):- 添加可選字段/類型。
- 擴展新值enum(在tolerant reader中)。
- 添加替代投影/事件(「.enriched」)。
- 放寬限制(「minLength」,「maximum」 ↑但不↓)。
- 刪除/重命名字段或更改其類型/強制性。
- 更改線程中的狀態/編解碼器/順序的語義。
- 重新使用protobuf標簽。
- 更改事件中的參與密鑰。
登記冊的組織
Neiming和尋址
組/空間:「payments」,「kyc」,「audit」。
名稱: 'payment。authorized.v1` (events), `payments.v1.CaptureRequest` (gRPC), `orders.v1.Order` (JSON Schema).
名稱中的專業,次要專業-在元數據/模式版本中。
元數據
「owner」(命令),「domain」,「slas」(SLO/SLA)和「security」。tier` (PII/PCI), `retention`, `compatibility_mode`, `sunset`, `changelog`.
生命周期管理
Draft → Review → Approved → Released → Deprecated → Sunset.
自動驗證器/linter,手動設計評論(API Guild),發布註釋。
集成到CI/CD中
1.預註:本地linters (Spectral/Buf/Avro工具)。
2.公關管道:schema-diff →可比性檢驗;阻止破裂。
3.Artifact publish:在註冊表中建立一致的計劃;生成SDK/模型。
4.Runtime-guard(可選):Gateway/Producer驗證付費與當前電路。
- `openapi-diff --fail-on-breaking`
- `buf breaking --against
` - `avro-compat --mode BACKWARD`
- 生成金色樣本並運行CDC測試。
模式演變: 實踐
Additive-first: новые поля — `optional/nullable` (JSON), `optional` (proto3), default в Avro.
反向金字塔模型:核心穩定,富集-相鄰且可選。
大調的雙emit/雙 write:我們同時發布「v1」和「v2」。
日落計劃:日期,用途,警告,適配器。
Tolerant reader:客戶忽略未知字段並正確處理新的enum。
模式和檢查示例
JSON計劃(片段,加法場)
json
{
"$id": "orders.v1.Order",
"type": "object",
"required": ["id", "status"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"status": { "type": "string", "enum": ["created", "paid", "shipped"] },
"risk_score": { "type": "number", "minimum": 0, "maximum": 1 }
},
"additionalProperties": true
}
Avro(默認兼容性)
json
{
"type": "record",
"name": "PaymentAuthorized",
"namespace": "payment.v1",
"fields": [
{ "name": "payment_id", "type": "string" },
{ "name": "amount", "type": "long" },
{ "name": "currency", "type": "string" },
{ "name": "risk_score", "type": ["null", "double"], "default": null }
]
}
Protobuf(不要重新使用標簽)
proto syntax = "proto3";
package payments.v1;
message CaptureRequest {
string payment_id = 1;
int64 amount = 2;
string currency = 3;
optional double risk_score = 4; // additive
}
// tag=4 зарезервирован под risk_score, его нельзя менять/удалять без v2
事件登記和聚會
事件命名: "域。action.v{major}` (`payment.captured.v1`).
分期付款密鑰是合同的一部分(「payment_id」,「user_id」)。
Core vs Enriched:'.v1'(內核)和'.enriched。v1'(零件)。
註冊表兼容性:主題/類型級別的模式;CI拒絕不兼容的更改。
移民管理
Expand → Migrate → Contract (REST/gRPC):
1.添加字段/表格;2)開始編寫/閱讀新字段;3)在日落後刪除舊的。
雙emit (Events):平行於「v1」/「v2」,遷移消費者/投影,然後刪除「v1」。
Replay:將投影從日誌重新組合到新方案(僅在兼容性和遷移器的情況下)。
適配器:為復雜客戶端翻譯「v1↔v2」的網關/代理。
安全和合規性
方案中的PII/PCI標簽:「x-pii:true」,「x-sensitivity:high」。
訪問策略:誰可以發布/修改模式(RBAC),簽名發布。
密碼學:模式的簽名版本,不可變審核日誌(WORM)。
遺忘權:指定需要加密/加密擦除的字段;註冊表中的指導。
可觀察性和審計
Dashbords:更改次數,類型(次要/專業),拒絕公關的比例以及版本的使用。
審核跟蹤:誰更改了模式,鏈接到PR/ADR和相關版本。
運行時度量:未通過驗證的消息百分比;兼容性事件。
工具(近似堆棧)
OpenAPI/JSON Schema: Spectral, OpenAPI Diff, Schemathesis.
Protobuf/gRPC: Buf, buf-breaking, protoc linters.
Avro/Events: Confluent/Redpanda Schema Registry, Avro-tools, Karapace.
GraphQL: GraphQL Inspector, GraphQL Codegen.
註冊表/目錄:Artifact註冊表,基於Git的註冊表,Backstage Catalog,定制UI。
文檔:Redocly/Stoplight,Swagger-UI,GraphiQL。
反模式
Swagger-wash:該方案不反映服務的現實(反之亦然)。
禁用的兼容性檢查:「我們必須緊急」→插件破裂。
重新使用protobuf標簽:安靜的數據損壞。
單一兼容模式「適用於所有」:不同的域需要不同的模式。
原始CDC作為公共計劃:DB模型向外泄漏,無法進化。
實施支票清單
- 跨域定義了工件格式和兼容性模式。
- 在CI中設置了林特和schema-diff,公關在斷裂時被鎖定。
- 包括客戶端的tolerant reader; 'additionalProperties=true'(如果適用)。
- 主要更改通過RFC/ADR進行,有日落計劃和雙emit/雙寫。
- 電路標有PII/PCI和訪問級別;已啟用審計。
- 版本使用和兼容性故障的Dashbords。
- 從註冊表生成SDK/模型是 pipline的一部分。
- 文檔和金色樣本自動更新。
FAQ
沒有註冊表-可以將電路存儲在Git中嗎?
是的,但是註冊表添加了兼容性API,搜索,元數據,集中式策略和「即時」驗證。最好的選擇是Git作為存儲+UI/策略。
如何選擇兼容性模式?
查看更改方向:如果制作人擴展了付費負載-BACKWARD。對於公共API/SDK-FULL。對於快速原型-暫時NONE(不在trunk上)。
如果需要切片,該怎麼辦?
準備v2: dual-emit/dual-run、日落日期、適配器、使用遙測、遷移海德。
是否需要在rantime中驗證付費負載?
對於關鍵域-是的:它可以防止「垃圾」消息並加快診斷速度。
結果
計劃註冊表將數據的演變從風險即興創作轉變為可管理的過程:統一的兼容性規則,自動驗證,可理解的版本和透明的歷史記錄。添加一個附加的第一,tolerant閱讀器,dual-emit和sunset的紀律-您的合同將迅速發展,沒有斷裂和夜間事件。