gRPC
gRPC 是 Gortexa 的原生協定。外部連線走同一個 h2c port,由 mux 依 Content-Type: application/grpc 分派給 grpc-go 的 ServeHTTP 處理模式。
服務定義與產生碼
Section titled “服務定義與產生碼”服務定義在 proto。內建的 sample resource:
service ResourceService { rpc CreateResource(CreateResourceRequest) returns (Resource); rpc GetResource(GetResourceRequest) returns (Resource); rpc ListResources(ListResourcesRequest) returns (ListResourcesResponse); rpc UpdateResource(UpdateResourceRequest) returns (Resource); rpc DeleteResource(DeleteResourceRequest) returns (google.protobuf.Empty);}gortexa regen 把 stubs 產到 gen/,logic 實作放在 internal package,兩者不混。
本機測試若要用 grpcurl,先開 reflection(預設關閉):
GORTEXA_SERVER__REFLECTION=true gortexa rungrpcurl -plaintext \ -H 'authorization: Bearer <token>' \ -d '{"id":"x"}' \ localhost:8080 myapp.resource.v1.ResourceService/GetResourcemyapp 是 scaffold 專案的 proto namespace(自 v0.28.0 起由 module path 推出,見建立專案);在框架 checkout 內直接跑 sample 時,服務名是 resource.v1.ResourceService。
沒帶 token 會得到 UNAUTHENTICATED:auth 對三個協定一視同仁。
Health
Section titled “Health”三態健康狀態對應到標準 gRPC Health protocol。用 app.Health().Register(...) 註冊真實依賴檢查,/readyz 與 gRPC Health 才會反映 DB、cache、MQ 的實際可達性。每個 check 有 5 秒逾時,慢的依賴不會卡住整個 health 查詢。Health.Watch 因為同時豁免 auth 與 load shedding(伺服器正在 shed 時探測仍須能回答),另有自己的上限:最多 1,024 條並行 watch 串流,超過回 RESOURCE_EXHAUSTED;所有 watcher 共用每秒一次的 registry 評估,N 條串流不等於 N 次依賴探測。註冊同名 check 會 panic(開機期的接線錯誤應該吵,而不是默默覆蓋掉某個依賴的監控);真的要替換請用 Replace(name, check)。
Reflection
Section titled “Reflection”gRPC reflection 預設關閉,需要時以 config 或環境變數開啟:
GORTEXA_SERVER__REFLECTION=true開啟後 /grpc.reflection. 同時豁免 auth 與 in-flight 預算(串流整個生命週期都佔一個名額,若只豁免 auth 不豁免計數,未認證的 client 就能釘住預算)。生產環境建議保持關閉,理由見部署。
Go 可以不用 TLS 直接跑 gRPC(h2c)嗎?
Section titled “Go 可以不用 TLS 直接跑 gRPC(h2c)嗎?”可以。Go 1.24 起 http.Server.Protocols 原生支援 h2c,Gortexa 就是用它——不需要已被棄用的 x/net/http2/h2c wrapper。正式環境請在前面終結 TLS。
正式環境該開 gRPC reflection 嗎?
Section titled “正式環境該開 gRPC reflection 嗎?”不建議。開啟後 /grpc.reflection. 會同時豁免 auth 與 in-flight 預算,等於把完整的服務 schema 公開給未認證的呼叫端。它預設關閉,留給 buf curl --reflect 這類開發工具用。
keepalive 設定為什麼沒有生效?
Section titled “keepalive 設定為什麼沒有生效?”因為共用 h2c 埠上的對外 gRPC 跑的是 grpc-go 的 ServeHTTP handler 模式,傳輸層選項(KeepaliveParams、MaxStreams 等)在那裡是無效的。需要 keepalive 強制就得把 gRPC 拆到自己的 listener。