mcpField
G
golang-pro

golang-pro

github.com/404kidwiz开发113 次安装
代码仓库

关于 golang-pro

golang-pro 是面向 Go 开发者的编程技能,适用于构建后端服务、命令行工具和分布式系统,重点涵盖 Go 1.21+、并发模式、性能优化及标准库惯用实践。

主要功能

  1. 01Go 1.21+ 语言指导
  2. 02Goroutine 与 channel 并发模式
  3. 03后端和网络服务模式
  4. 04性能分析与优化
  5. 05错误处理与测试实践

适用场景

  1. 01构建并发 Go 服务
  2. 02开发命令行工具
  3. 03优化 Go 应用性能
  4. 04设计分布式系统组件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/404kidwiz/claude-supercode-skills --skill golang-pro

安装后在 Claude Code 中输入/golang-pro确认已加载。

详细介绍

Go Pro 专家

用途

提供专业的 Go 编程能力,专精于 Go 1.21+ 特性、使用 goroutine 和 channel 构建并发系统,以及高性能后端服务。擅长运用惯用的 Go 模式和全面的标准库,构建可扩展的微服务、CLI 工具和分布式系统。

使用场景

  • 使用 Go 构建高性能微服务(HTTP 服务端、gRPC、API 网关)
  • 使用 goroutine 和 channel 实现并发系统(工作池、流水线)
  • 使用 cobra 或标准库开发 CLI 工具(系统实用程序、DevOps 工具)
  • 创建网络服务(TCP/UDP 服务端、WebSocket 服务端、代理)
  • 使用并发流处理构建数据处理流水线
  • 优化 Go 应用的性能(使用 pprof 进行性能分析、减少内存分配)
  • 实现分布式系统模式(服务发现、熔断器)
  • 使用 Go 1.21+ 泛型和类型参数

专精于 Go 1.21+ 特性、使用 goroutine 和 channel 进行并发编程,以及全面运用标准库来构建高性能并发系统的 Go 专家。



2. 决策框架

并发模式选择
Use Case Analysis
│
├─ Need to process multiple items independently?
│  └─ Worker Pool Pattern ✓
│     - Buffered channel for jobs
│     - Fixed number of goroutines
│     - WaitGroup for completion
│
├─ Need to transform data through multiple stages?
│  └─ Pipeline Pattern ✓
│     - Chain of channels
│     - Each stage processes and passes forward
│     - Fan-out for parallel processing
│
├─ Need to merge results from multiple sources?
│  └─ Fan-In Pattern ✓
│     - Multiple input channels
│     - Single output channel
│     - select statement for multiplexing
│
├─ Need request-scoped cancellation?
│  └─ Context Pattern ✓
│     - context.WithCancel()
│     - context.WithTimeout()
│     - Propagate through call chain
│
├─ Need to synchronize access to shared state?
│  ├─ Read-heavy workload → sync.RWMutex
│  ├─ Simple counter → sync/atomic
│  └─ Complex coordination → Channels
│
└─ Need to ensure single initialization?
   └─ sync.Once ✓
错误处理策略矩阵
场景模式示例
添加上下文信息包装错误fmt.Errorf("%w")return fmt.Errorf("failed to connect: %w", err)
自定义错误类型定义带有 Error() 方法的结构体type ValidationError struct { Field string }
哨兵错误var ErrNotFound = errors.New("not found")if errors.Is(err, ErrNotFound) { ... }
检查错误类型errors.As()var valErr *ValidationError; if errors.As(err, &valErr) { ... }
返回多个结果同时返回值和错误func Get(id string) (*User, error)
仅对程序员错误使用 panicpanic("unreachable code")对预期会发生的故障绝不使用 panic
HTTP 框架决策树
HTTP Server Requirements
│
├─ Need full-featured framework with middleware?
│  └─ Gin or Echo ✓
│     - Routing, middleware, validation
│     - JSON binding
│     - Production-ready
│
├─ Need microframework for simple APIs?
│  └─ Chi or Gorilla Mux ✓
│     - Lightweight routing
│     - stdlib-compatible
│     - Fine-grained control
│
├─ Need maximum performance and control?
│  └─ net/http stdlib ✓
│     - No external dependencies
│     - Full customization
│     - Good for learning
│
└─ Need gRPC services?
   └─ google.golang.org/grpc ✓
      - Protocol Buffers
      - Streaming support
      - Cross-language
危险信号 → 升级给 Oracle 处理
观察到的情况升级原因示例
goroutine 泄漏导致内存增长生命周期管理复杂“内存持续增长,怀疑 goroutine 未终止”
使用互斥锁后仍发生竞态条件隐晦的同步错误“go test -race 在生产代码中发现数据竞争”
context 取消未能传播分布式系统协调“客户端断开后,已取消的请求仍在运行”
泛型导致编译时间激增类型系统复杂“带约束的泛型函数导致编译时间超过 10 分钟”
CGO 内存损坏不安全代码交互“从 Go 调用 C 库时发生段错误”


工作流 2:支持优雅关闭的 HTTP 服务端

场景:具备中间件和优雅关闭功能、可用于生产环境的 HTTP 服务端

步骤 1:定义服务端结构

package main

import (
    "context"
    "errors"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

type Server struct {
    httpServer *http.Server
    logger     *log.Logger
}

func NewServer(addr string, handler http.Handler) *Server {
    return &Server{
        httpServer: &http.Server{
            Addr:         addr,
            Handler:      handler,
            ReadTimeout:  15 * time.Second,
            WriteTimeout: 15 * time.Second,
            IdleTimeout:  60 * time.Second,
        },
        logger: log.New(os.Stdout, "[SERVER] ", log.LstdFlags|log.Lmicroseconds),
    }
}

func (s *Server) Start() error {
    s.logger.Printf("Starting server on %s", s.httpServer.Addr)
    
    if err := s.httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
        return err
    }
    
    return nil
}

func (s *Server) Shutdown(ctx context.Context) error {
    s.logger.Println("Shutting down server...")
    return s.httpServer.Shutdown(ctx)
}

步骤 2:实现中间件

// Middleware for logging
func LoggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        
        // Wrap response writer to capture status code
        wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
        
        next.ServeHTTP(wrapped, r)
        
        log.Printf("%s %s %d %s", r.Method, r.URL.Path, wrapped.statusCode, time.Since(start))
    })
}

type responseWriter struct {
    http.ResponseWriter
    statusCode int
}

func (rw *responseWriter) WriteHeader(code int) {
    rw.statusCode = code
    rw.ResponseWriter.WriteHeader(code)
}

// Middleware for panic recovery
func RecoveryMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err := recover(); err != nil {
                log.Printf("Panic recovered: %v", err)
                http.Error(w, "Internal Server Error", http.StatusInternalServerError)
            }
        }()
        
        next.ServeHTTP(w, r)
    })
}

// Middleware for request timeout
func TimeoutMiddleware(timeout time.Duration) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            ctx, cancel := context.WithTimeout(r.Context(), timeout)
            defer cancel()
            
            r = r.WithContext(ctx)
            
            done := make(chan struct{})
            go func() {
                next.ServeHTTP(w, r)
                close(done)
            }()
            
            select {
            case <-done:
                return
            case <-ctx.Done():
                http.Error(w, "Request Timeout", http.StatusRequestTimeout)
            }
        })
    }
}

步骤 3:设置路由并实现优雅关闭

func main() {
    // Setup routes
    mux := http.NewServeMux()
    
    mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("OK"))
    })
    
    mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
        // Simulate slow endpoint
        time.Sleep(2 * time.Second)
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte(`{"users": []}`))
    })
    
    // Apply middleware chain
    handler := RecoveryMiddleware(LoggingMiddleware(TimeoutMiddleware(5 * time.Second)(mux)))
    
    // Create server
    server := NewServer(":8080", handler)
    
    // Start server in goroutine
    go func() {
        if err := server.Start(); err != nil {
            log.Fatalf("Server failed: %v", err)
        }
    }()
    
    // Wait for interrupt signal
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit
    
    // Graceful shutdown with 30s timeout
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()
    
    if err := server.Shutdown(ctx); err != nil {
        log.Printf("Server shutdown error: %v", err)
    }
    
    log.Println("Server stopped")
}

预期结果:

  • 可用于生产环境且带有超时设置的 HTTP 服务端
  • 中间件链(日志记录、恢复、超时)
  • 优雅关闭(完成正在处理的请求)
  • 不发生 goroutine 泄漏或资源泄漏


4. 模式与模板

模式 1:用于取消操作的上下文传播

使用场景:客户端断开连接时取消所有下游操作

// Template: Context-aware HTTP handler
func HandleRequest(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    
    // Pass context to all downstream calls
    result, err := fetchData(ctx)
    if err != nil {
        if errors.Is(err, context.Canceled) {
            // Client disconnected
            return
        }
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    json.NewEncoder(w).Encode(result)
}

func fetchData(ctx context.Context) (*Data, error) {
    // Check context before expensive operation
    select {
    case <-ctx.Done():
        return nil, ctx.Err()
    default:
    }
    
    // Simulate database call with timeout
    resultChan := make(chan *Data, 1)
    errChan := make(chan error, 1)
    
    go func() {
        // Actual database query
        time.Sleep(2 * time.Second)
        resultChan <- &Data{Value: "result"}
    }()
    
    select {
    case result := <-resultChan:
        return result, nil
    case err := <-errChan:
        return nil, err
    case <-ctx.Done():
        return nil, ctx.Err() // Canceled or timed out
    }
}


模式 3:表驱动测试

使用场景:以最少代码实现全面的测试覆盖

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"negative numbers", -2, -3, -5},
        {"mixed signs", -2, 3, 1},
        {"zero values", 0, 0, 0},
        {"large numbers", 1000000, 2000000, 3000000},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
            }
        })
    }
}


❌ 反模式:范围循环变量捕获

表现形式:

// WRONG: All goroutines reference same variable
for _, user := range users {
    go func() {
        fmt.Println(user.Name) // Captures loop variable by reference!
    }()
}
// Prints last user's name multiple times!

失败原因:

  • 变量复用:循环变量会在每次迭代中复用
  • 所有 goroutine 都会看到最终值:goroutine 运行时,循环可能已经结束
  • 数据竞争:多个 goroutine 访问同一个变量

正确做法:

// CORRECT: Pass variable as argument (Go 1.21 and earlier)
for _, user := range users {
    go func(u User) {
        fmt.Println(u.Name) // Each goroutine has own copy
    }(user)
}

// CORRECT: Use local variable (Go 1.21 and earlier)
for _, user := range users {
    user := user // Shadow variable
    go func() {
        fmt.Println(user.Name)
    }()
}

// Go 1.22+: Loop variable per iteration (automatic)
for _, user := range users {
    go func() {
        fmt.Println(user.Name) // Now safe in Go 1.22+
    }()
}


6. 集成模式

backend-developer:
  • 交接:后端开发人员定义业务逻辑 → golang-pro 使用符合 Go 惯用法的模式实现
  • 协作:REST API 设计、数据库集成、身份验证/授权
  • 工具:Chi/Gin 框架、GORM/sqlx、JWT 库
  • 示例:后端定义订单服务 → golang-pro 使用 goroutine 并发检查库存
database-optimizer:
  • 交接:Golang-pro 找出运行缓慢的数据库查询 → database-optimizer 创建索引
  • 协作:查询优化、连接池(pgx、database/sql)
  • 工具:database/sql、pgx 驱动、用于 PostgreSQL 的 sqlx
  • 示例:Golang-pro 使用 database/sql 预处理语句 → database-optimizer 调整 PostgreSQL 以优化连接池
devops-engineer:
  • 交接:Golang-pro 构建服务 → devops-engineer 将其容器化并部署
  • 协作:Dockerfile 优化、健康检查、指标端点
  • 工具:Docker 多阶段构建、Kubernetes 探针、Prometheus 指标
  • 示例:Golang-pro 暴露 /metrics 端点 → devops-engineer 配置 Prometheus 抓取指标
kubernetes-specialist:
  • 交接:Golang-pro 构建云原生应用 → kubernetes-specialist 将其部署到 K8s
  • 协作:优雅关闭(SIGTERM)、健康/就绪探针、资源限制
  • 工具:Kubernetes client-go、运算符模式、CRD
  • 示例:Golang-pro 实现优雅关闭 → kubernetes-specialist 设置 terminationGracePeriodSeconds
frontend-developer:
  • 交接:前端需要 API → golang-pro 提供 RESTful/gRPC 端点
  • 协作:API 合约设计、CORS 配置、WebSocket 连接
  • 工具:OpenAPI/Swagger、gRPC-web、WebSocket(gorilla/websocket)
  • 示例:前端使用 GraphQL → golang-pro 使用 DataLoader 实现 gqlgen 解析器

评论

支持 Markdown