Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

grpc.md

maoxiaoyue edited this page May 14, 2026 · 2 revisions

pkg/grpc — gRPC Server 封裝

v0.8.5+ 此套件為 HypGo v0.8.5 新增功能,v0.8.1 版本不包含。

grpc 套件提供 gRPC Server 的統一封裝,包含 listener 管理、TLS、reflection、health check、interceptor(中間件)和 graceful shutdown。

設計理念

HypGo 的 gRPC 與 REST 採用獨立 Server 架構:

pkg/server → HTTP/1.1 + HTTP/2 + HTTP/3(REST + WebSocket) :8080
pkg/grpc → gRPC Server :9090
兩者共用:
 app/models/ ← 資料結構
 app/services/ ← 業務邏輯
 pkg/errors/ ← Error Catalog
 pkg/hidb/ ← 資料庫
 pkg/logger/ ← 日誌
 pkg/config/ ← 設定

快速上手

建立 gRPC 專案

hyp new grpc userservice && cd userservice && go mod tidy
make proto # 編譯 .proto → Go code
go run .

在既有專案中加入 gRPC

import (
 hypgrpc "github.com/maoxiaoyue/hypgo/pkg/grpc"
 "github.com/maoxiaoyue/hypgo/pkg/grpc/interceptor"
)
grpcSrv := hypgrpc.New(hypgrpc.Config{
 Addr: ":9090",
 EnableReflection: true,
 EnableHealthCheck: true,
}, logger,
 grpc.ChainUnaryInterceptor(
 interceptor.Recovery(logger),
 interceptor.Logger(logger),
 ),
)
// 註冊服務
pb.RegisterUserServiceServer(grpcSrv.GRPCServer(), &UserServer{})
// 啟動
go grpcSrv.Start()
// 優雅關閉
grpcSrv.GracefulStop()

Config

type Config struct {
 Addr string // 監聽地址(預設 ":9090")
 TLS *TLSConfig // TLS 配置(nil = plaintext)
 EnableReflection bool // 啟用 gRPC reflection(grpcurl 偵錯)
 EnableHealthCheck bool // 啟用 gRPC health check 服務
 MaxRecvMsgSize int // 最大接收訊息大小(預設 4MB)
 MaxSendMsgSize int // 最大發送訊息大小(預設 4MB)
}
type TLSConfig struct {
 CertFile string
 KeyFile string
}

Server API

方法 說明
New(cfg, logger, ...grpc.ServerOption) 建立 Server(自動配置 TLS、reflection、health)
GRPCServer() 取得底層 *grpc.Server(用於 pb.RegisterXxxServer)
Start() 啟動(阻塞)
GracefulStop() 優雅關閉(等待進行中的 RPC 完成)
Stop() 立即停止
Addr() 取得實際監聽地址
IsShuttingDown() 是否正在關閉(atomic.Bool)
SetServingStatus(service, status) 設定 health check 狀態

Interceptor(gRPC 中間件)

對應 pkg/middleware/ 的 HTTP 中間件:

Interceptor 功能 對應 HTTP middleware
interceptor.Recovery(logger) Panic → codes.Internal middleware.Recovery
interceptor.Logger(logger) 記錄方法、耗時、狀態碼 middleware.Logger
interceptor.Auth(authFn, skipMethods...) Token 驗證 + context 注入 middleware.JWT
interceptor.RateLimit(config) IP 限流 + 背景清理 middleware.RateLimit

使用 Interceptor

s := hypgrpc.New(cfg, logger,
 grpc.ChainUnaryInterceptor(
 interceptor.Recovery(logger), // 最外層:捕獲 panic
 interceptor.Logger(logger), // 記錄每個 RPC
 interceptor.Auth(myAuthFunc, // 驗證 token
 "/grpc.health.v1.Health/Check", // 跳過 health check
 ),
 interceptor.RateLimit(interceptor.RateLimitConfig{
 MaxRequests: 100, // 每分鐘 100 次
 Window: time.Minute,
 }),
 ),
)

Auth Interceptor 詳解

// 定義驗證函式
authFn := func(ctx context.Context, token string) (interface{}, error) {
 // 驗證 JWT token
 claims, err := jwt.Validate(token)
 if err != nil {
 return nil, err // → codes.Unauthenticated
 }
 return claims, nil // 存入 context
}
// 在 RPC handler 中取出使用者
func (s *Server) GetUser(ctx context.Context, req *pb.GetUserReq) (*pb.UserResp, error) {
 user, ok := interceptor.UserFromContext(ctx)
 if !ok {
 return nil, status.Error(codes.Internal, "no user in context")
 }
 // user 是 authFn 回傳的物件
}

RateLimit 安全設計

  • 根據客戶端 IP 限流(從 peer.FromContext 取得)
  • 背景 goroutine 定期清理過期 key(預設每 5 分鐘)
  • 超過限制回傳 codes.ResourceExhausted

專案結構

hyp new grpc userservice
userservice/
├── app/
│ ├── proto/userservicepb/
│ │ └── userservice.proto ← Protobuf 定義
│ ├── rpc/
│ │ └── userservice_server.go ← gRPC 服務實作
│ ├── models/ ← 共用資料結構
│ ├── services/ ← 共用業務邏輯
│ └── config/config.yaml
├── main.go
├── Makefile ← make proto
└── go.mod

新增更多服務

hyp generate proto order
# → app/proto/orderpb/order.proto
# → app/rpc/order_server.go

與 REST 的共存

同一個專案可以同時有 REST 和 gRPC:

func main() {
 // REST Server
 srv := server.New(cfg, log)
 routers.Setup(srv.Router())
 // gRPC Server
 grpcSrv := hypgrpc.New(hypgrpc.Config{Addr: ":9090"}, log)
 pb.RegisterUserServiceServer(grpcSrv.GRPCServer(), &UserServer{})
 // 同時啟動
 go srv.Start() // :8080 REST
 go grpcSrv.Start() // :9090 gRPC
 // 優雅關閉
 quit := make(chan os.Signal, 1)
 signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
 <-quit
 srv.Shutdown(ctx)
 grpcSrv.GracefulStop()
}

共用 Service 層

Controller (REST) ─┐
 ├─→ UserService (app/services/) ─→ Database
RPC Handler (gRPC) ─┘

Controller 和 RPC handler 都是薄 adapter,真正的邏輯在 app/services/ 中共用。

安全

  • TLS:支援 mTLS,MinVersion = TLS 1.2
  • Auth:未提供 token → codes.Unauthenticated(安全預設)
  • Auth skip:可跳過不需驗證的方法(如 Health check)
  • RateLimit:背景清理防記憶體洩漏
  • Recovery:panic 不 crash,回傳 codes.Internal
  • GracefulStop:atomic.Bool 防止重複關閉

必要工具

gRPC 開發需要安裝:

# protoc 編譯器
# https://github.com/protocolbuffers/protobuf/releases
# Go protobuf 插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# 偵錯工具(可選)
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

HypGo

繁體中文 | English


中文文件

設計文件

套件

AI 協作工具鏈

CLI 命令


English Docs

Design Docs

Packages

AI Collaboration Toolchain

CLI Commands

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /