Go Web 编程实战Go Web 编程实战
首页
课程导读
首页
课程导读
  • 课程导读
  • 课程目录

    • Go基础语法精要
    • Web基础与HTTP处理
    • Gin框架入门
    • 路由与中间件
    • 数据库操作
    • 模板渲染
    • 错误处理与日志
    • 测试与部署
    • 高级中间件模式
    • 微服务架构
    • 性能优化
    • 安全最佳实践
    • 项目结构与代码组织

微服务架构

1. 微服务基本概念

微服务架构是将单一应用拆分为一组小型服务的风格:

// 用户服务示例
type UserService struct {
    repo UserRepository
}

func (s *UserService) GetUser(id string) (*User, error) {
    return s.repo.FindByID(id)
}

// 订单服务示例
type OrderService struct {
    repo OrderRepository
}

func (s *OrderService) CreateOrder(userID string, items []Item) (*Order, error) {
    // 验证用户存在(可能调用用户服务)
    // 创建订单
    return s.repo.Create(userID, items)
}

微服务特点:

  • 每个服务有独立的代码库
  • 独立部署和扩展
  • 轻量级通信(通常HTTP/REST或gRPC)
  • 独立的数据存储

2. 服务间通信方式

REST API

// 用户服务HTTP客户端
type UserServiceClient struct {
    baseURL string
    client  *http.Client
}

func (c *UserServiceClient) GetUser(id string) (*User, error) {
    resp, err := c.client.Get(fmt.Sprintf("%s/users/%s", c.baseURL, id))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var user User
    if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
        return nil, err
    }
    return &user, nil
}

gRPC

// user_service.proto
service UserService {
    rpc GetUser (GetUserRequest) returns (UserResponse);
}

message GetUserRequest {
    string id = 1;
}

message UserResponse {
    string id = 1;
    string name = 2;
    string email = 3;
}
// gRPC客户端实现
conn, err := grpc.Dial("user-service:50051", grpc.WithInsecure())
if err != nil {
    log.Fatalf("连接失败: %v", err)
}
defer conn.Close()

client := pb.NewUserServiceClient(conn)
user, err := client.GetUser(context.Background(), &pb.GetUserRequest{Id: "123"})

3. 服务发现与负载均衡

使用Consul服务发现

// 服务注册
func registerService(serviceName, address string, port int) {
    config := api.DefaultConfig()
    client, err := api.NewClient(config)
    if err != nil {
        panic(err)
    }
    
    registration := &api.AgentServiceRegistration{
        ID:      fmt.Sprintf("%s-%s", serviceName, uuid.New().String()),
        Name:    serviceName,
        Port:    port,
        Address: address,
        Check: &api.AgentServiceCheck{
            HTTP:     fmt.Sprintf("http://%s:%d/health", address, port),
            Interval: "10s",
            Timeout:  "5s",
        },
    }
    
    if err := client.Agent().ServiceRegister(registration); err != nil {
        panic(err)
    }
}

// 服务发现
func discoverService(serviceName string) (string, error) {
    config := api.DefaultConfig()
    client, err := api.NewClient(config)
    if err != nil {
        return "", err
    }
    
    services, _, err := client.Health().Service(serviceName, "", true, nil)
    if err != nil {
        return "", err
    }
    
    if len(services) == 0 {
        return "", fmt.Errorf("服务 %s 未找到", serviceName)
    }
    
    service := services[0]
    return fmt.Sprintf("http://%s:%d", service.Service.Address, service.Service.Port), nil
}

4. API网关模式

// 使用Gin实现简单API网关
func main() {
    r := gin.Default()
    
    // 用户服务路由
    userGroup := r.Group("/users")
    {
        userGroup.GET("/:id", func(c *gin.Context) {
            // 调用用户服务
            userServiceURL := getServiceURL("user-service")
            resp, err := http.Get(fmt.Sprintf("%s/users/%s", userServiceURL, c.Param("id")))
            // 处理响应...
        })
    }
    
    // 订单服务路由
    orderGroup := r.Group("/orders")
    {
        orderGroup.POST("/", func(c *gin.Context) {
            // 调用订单服务
            orderServiceURL := getServiceURL("order-service")
            resp, err := http.Post(orderServiceURL+"/orders", "application/json", c.Request.Body)
            // 处理响应...
        })
    }
    
    r.Run(":8080")
}

5. 分布式系统挑战与解决方案

挑战解决方案
服务发现Consul, Eureka, etcd
配置管理Consul KV, etcd, Spring Cloud Config
负载均衡Nginx, Traefik, Envoy
断路器Hystrix, Resilience4j, gobreaker
分布式追踪Jaeger, Zipkin, OpenTelemetry
日志聚合ELK, Fluentd, Loki
监控Prometheus, Grafana
// 使用gobreaker实现断路器
func main() {
    cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
        Name:    "user-service",
        Timeout: 30 * time.Second,
        ReadyToTrip: func(counts gobreaker.Counts) bool {
            return counts.ConsecutiveFailures > 5
        },
    })
    
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        _, err := cb.Execute(func() (interface{}, error) {
            return callUserService(r)
        })
        
        if err != nil {
            http.Error(w, err.Error(), http.StatusServiceUnavailable)
            return
        }
        
        // 处理成功响应...
    })
    
    http.ListenAndServe(":8080", nil)
}

提示:微服务架构提供了灵活性和可扩展性,但也带来了复杂性。建议从单体架构开始,只在真正需要时拆分服务。

Prev
高级中间件模式
Next
性能优化