Karp 的技术博客

全局视角

第一阶段  Go 基础          → 能写业务逻辑
第二阶段  单体服务          → 能跑一个完整的 HTTP 服务
第三阶段  拆分微服务        → 多个服务互相通信
第四阶段  服务治理          → 服务发现、配置中心、链路追踪
第五阶段  容器化            → Docker 打包,跑在任何地方
第六阶段  编排部署          → Kubernetes 管理成百上千个容器
第七阶段  流量治理          → Istio 控制服务间流量

第一阶段:Go 基础

目标:能用 Go 写业务逻辑,看懂别人的代码。

核心概念

// 1. 零值可用的结构体
var a phparray.Array
a.Set("name", "Tom")      // 直接用,无需 New()

// 2. 错误处理(Go 没有 try-catch)
data, err := json.Marshal(obj)
if err != nil {
    return fmt.Errorf("marshal failed: %w", err)
}

// 3. goroutine + channel(Go 的并发核心)
ch := make(chan string)
go func() {
    ch <- "hello"   // 另一个协程发送
}()
msg := <-ch         // 主协程接收

必须掌握

  • 切片 / map / struct / interface
  • goroutine / channel
  • defer / panic / recover
  • 包管理(go.mod / go.sum)

验收标准

能独立写一个读取文件、解析 JSON、并发处理数据的命令行工具。

第二阶段:单体 HTTP 服务

目标:跑起来一个完整的 HTTP 服务,能增删改查。

技术选型

HTTP 框架   →  Gin(最流行)或 Kratos(字节开源,适合微服务)
数据库      →  GORM(ORM)+ MySQL / PostgreSQL
配置管理    →  Viper(读取 yaml / env)
日志        →  Zap(高性能结构化日志)

项目结构

my-service/
├── main.go              ← 程序入口
├── go.mod
├── config/
│   └── config.go        ← 读取配置
├── handler/
│   └── user.go          ← HTTP 路由处理
├── service/
│   └── user.go          ← 业务逻辑
├── repository/
│   └── user.go          ← 数据库操作
└── model/
    └── user.go          ← 数据结构定义

核心代码示例

// handler/user.go
func (h *UserHandler) GetUser(c *gin.Context) {
    id := c.Param("id")

    user, err := h.svc.GetUser(c.Context(), id)
    if err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, user)
}

验收标准

能独立完成用户注册、登录、查询接口,带数据库读写和 JWT 鉴权。

第三阶段:拆分微服务

目标:把单体拆成多个服务,服务之间能互相通信。

为什么要拆?

单体服务                     微服务
────────────────────         ────────────────────────────────
一个进程跑所有逻辑            每个业务独立成一个服务
改一处要整体重新部署           独立部署,互不影响
一处崩溃全部崩溃              隔离故障
团队协作困难                  每个团队负责自己的服务

通信方式

HTTP / REST — 简单场景,同步调用

// 用户服务调用订单服务
resp, err := http.Get("http://order-service/orders?user_id=123")

gRPC — 高性能场景,强类型,适合内部服务间调用

// 先定义接口(.proto 文件)
service OrderService {
    rpc GetOrders (GetOrdersRequest) returns (GetOrdersResponse);
}
// 自动生成代码,直接调用,像调本地函数一样
orders, err := orderClient.GetOrders(ctx, &pb.GetOrdersRequest{
    UserId: "123",
})

消息队列(Kafka / RabbitMQ) — 异步场景,解耦服务

用户下单  →  发消息到队列  →  库存服务消费  →  扣减库存
                          →  通知服务消费  →  发短信

验收标准

用户服务、订单服务、商品服务三个独立进程,通过 gRPC 互相调用。

第四阶段:服务治理

目标:服务多了之后,解决"找到对方、配置统一、出问题能排查"的问题。

服务发现

服务多了,地址会动态变化,不能写死 IP:

没有服务发现:user-service 写死 order-service 的 IP → 对方一重启就挂
有服务发现:                order-service 启动时注册自己 → user-service 动态查询地址
// 用 Consul 或 etcd 做服务发现
// Kratos 框架内置支持
app := kratos.New(
    kratos.Name("order-service"),
    kratos.Registrar(consul.New(client)),  // 自动注册、自动发现
)

配置中心

本地配置文件:每次改配置要重新部署 ❌
配置中心:    在界面上改,服务自动热加载 ✅

常用工具:Nacos(阿里开源)、Apollo(携程开源)、etcd

链路追踪

一个请求经过:网关 → 用户服务 → 订单服务 → 商品服务
出问题了,怎么知道卡在哪一步?
// 每个请求生成唯一 traceID,串联所有日志
// 用 Jaeger 或 Zipkin 可视化调用链
ctx, span := tracer.Start(ctx, "GetUser")
defer span.End()

验收标准

服务重启后其他服务能自动感知,配置修改不需要重新部署,能在 Jaeger 上看到完整调用链。

第五阶段:Docker 容器化

目标:把服务打包成镜像,跑在任何地方。

为什么需要 Docker?

没有 Docker:  "在我电脑上能跑" → 换台机器环境不同就挂
有了 Docker:  把代码 + 环境一起打包 → 到哪都一样

Dockerfile

# 多阶段构建,减小镜像体积
FROM golang:1.25 AS builder
WORKDIR /app
COPY . .
RUN go build -o server ./main.go   # 编译成二进制

FROM alpine:3.18                   # 只用最小基础镜像
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]
# 打包镜像
docker build -t user-service:v1.0 .

# 运行容器
docker run -p 8080:8080 user-service:v1.0

验收标准

每个服务都有 Dockerfile,docker build 一条命令能跑起来。

第六阶段:Kubernetes 编排

目标:用 K8s 管理成百上千个容器,自动扩缩容、自动故障恢复。

K8s 解决什么问题?

Docker 只能管单台机器的容器
K8s 能管几百台机器上的几千个容器

自动调度    →  哪台机器资源富余就放哪里
自动恢复    →  容器挂了自动重启
自动扩缩容  →  流量大了自动加容器,流量小了自动缩减
滚动更新    →  更新服务不停机

核心资源

# Deployment:管理容器副本
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3                        # 跑 3 个副本
  template:
    spec:
      containers:
        - name: user-service
          image: user-service:v1.0
          resources:
            requests:
              cpu: "100m"            # 最少需要 0.1 核
            limits:
              cpu: "500m"            # 最多用 0.5 核

---
# Service:给 Deployment 一个固定访问地址
apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  selector:
    app: user-service
  ports:
    - port: 8080

Helm:K8s 的包管理器

原始 YAML:每个环境(开发/测试/生产)都要改一遍配置 ❌
Helm Chart:把 YAML 模板化,一条命令切换环境 ✅
# 部署到测试环境
helm install user-service ./chart -f values-test.yaml

# 部署到生产环境
helm install user-service ./chart -f values-prod.yaml

验收标准

所有服务跑在 K8s 上,能做滚动更新,压测时能自动扩容。

第七阶段:Istio 流量治理

目标:精细化控制服务间的流量,不改代码实现限流、熔断、灰度发布。

Istio 解决什么问题?

K8s 管"跑什么"
Istio 管"流量怎么走"

核心能力

灰度发布:新版本先给 10% 用户,没问题再全量

kind: VirtualService
spec:
  http:
    - route:
        - destination:
            subset: v1
          weight: 90      # 90% 流量走旧版本
        - destination:
            subset: v2
          weight: 10      # 10% 流量走新版本

熔断:下游服务挂了,自动断开不拖垮上游

kind: DestinationRule
spec:
  trafficPolicy:
    outlierDetection:
      consecutive5xxErrors: 5      # 连续 5 次错误
      interval: 30s                # 30 秒内
      baseEjectionTime: 30s        # 踢出 30 秒

限流:保护服务不被打垮

kind: EnvoyFilter
spec:
  # 每秒最多 100 个请求,超出返回 429
  rateLimit:
    requestsPerUnit: 100
    unit: SECOND

验收标准

能做灰度发布,下游服务故障时自动熔断,在 Kiali 面板上看到实时流量拓扑。

学习时间参考

阶段预计时间关键产出
Go 基础2 - 4 周能写命令行工具
单体服务2 - 3 周完整 CRUD 接口
微服务拆分3 - 4 周多服务 gRPC 通信
服务治理2 - 3 周服务发现 + 链路追踪
Docker3 - 5 天所有服务容器化
Kubernetes3 - 4 周服务跑在 K8s 上
Istio2 - 3 周灰度发布 + 熔断

推荐工具栈

语言框架    Kratos(微服务)/ Gin(简单服务)
通信协议    gRPC + Protobuf
消息队列    Kafka
数据库      MySQL + Redis
服务发现    Consul / etcd
配置中心    Nacos
链路追踪    Jaeger + OpenTelemetry
容器        Docker
编排        Kubernetes + Helm
流量治理    Istio
监控        Prometheus + Grafana

golang

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2026年04月04日 15:00
0

目录

来自 《 Go 微服务从零到生产:完整学习路径》