第一章:Go语言微服务架构全景概览
Go 语言凭借其轻量级协程(goroutine)、内置并发模型、静态编译与极低的运行时开销,天然契合微服务对高性能、高密度部署与快速启停的核心诉求。在云原生演进背景下,Go 已成为构建 API 网关、服务注册中心、配置中心及业务微服务的主流语言之一,广泛应用于 Kubernetes 生态工具链(如 etcd、Docker CLI)及头部互联网企业的服务网格实践。
核心组件生态
- 服务发现:Consul、etcd 或基于 Kubernetes Service 的 DNS 发现机制,配合 Go 客户端(如
hashicorp/consul-api)实现自动服务注册与健康检查 - RPC 框架:gRPC(默认使用 Protocol Buffers)提供强类型接口与跨语言互通能力;亦可选用轻量级 HTTP/JSON-RPC(如
go-microv3 或kit) - 配置管理:支持从环境变量、Viper 驱动的 YAML/JSON 文件、或远程配置中心(如 Nacos、Apollo)动态加载配置
- 可观测性:OpenTelemetry Go SDK 统一采集 traces、metrics 和 logs,导出至 Jaeger、Prometheus 与 Loki
典型服务启动结构
以下为一个符合十二要素应用原则的微服务入口示例:
package main
import (
"log"
"net/http"
"os"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
func main() {
// 使用 OpenTelemetry 包装 HTTP 处理器,自动注入 trace 上下文
handler := otelhttp.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello from Go microservice"))
}), "api-handler")
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Printf("Starting server on :%s", port)
log.Fatal(http.ListenAndServe(":"+port, handler))
}
该代码通过 otelhttp.NewHandler 实现零侵入式链路追踪集成,并从环境变量读取端口,满足配置外置与进程隔离要求。
架构分层示意
| 层级 | 职责说明 | 典型 Go 技术选型 |
|---|---|---|
| 边界层 | 协议适配、认证鉴权、限流熔断 | Gin/Echo + go-chi + sentinel-go |
| 业务逻辑层 | 领域服务编排、事务协调 | Clean Architecture + wire DI |
| 数据访问层 | 多源数据整合(SQL/NoSQL/Cache) | sqlx + gorm + redis-go + ent |
| 基础设施层 | 日志、监控、配置、服务发现 | Zap + Prometheus Client + Viper + consul-api |
第二章:gRPC服务设计与订单核心逻辑实现
2.1 gRPC协议原理与ProtoBuf接口定义实践
gRPC 基于 HTTP/2 多路复用与二进制帧传输,天然支持流式通信与头部压缩。其核心依赖 Protocol Buffers(ProtoBuf)进行强类型接口契约定义。
ProtoBuf 接口定义示例
syntax = "proto3";
package example;
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}
message UserRequest {
int32 id = 1; // 用户唯一标识
}
message UserResponse {
string name = 1;
int32 age = 2;
}
该定义生成跨语言客户端/服务端桩代码,id = 1 中的字段序号决定二进制序列化顺序,不可随意变更;syntax = "proto3" 启用简洁语义(如默认字段可选、无 required 关键字)。
gRPC 通信流程(mermaid)
graph TD
A[Client] -->|HTTP/2 Stream| B[Server]
B -->|Serialized UserRequest| C[Deserialize]
C --> D[Business Logic]
D -->|UserResponse| E[Serialize]
E -->|HTTP/2 Frame| A
关键优势对比
| 特性 | REST/JSON | gRPC/ProtoBuf |
|---|---|---|
| 序列化体积 | 文本冗余高 | 二进制紧凑(≈1/3) |
| 类型安全 | 运行时校验 | 编译期强约束 |
| 流式能力 | 需 SSE/WS 扩展 | 原生支持四种模式 |
2.2 Go语言构建高并发订单服务端与客户端
高并发服务端核心设计
采用 net/http + goroutine 池处理订单请求,避免无限制协程创建导致调度压力。关键使用 sync.Pool 复用 Order 结构体实例,降低 GC 频率。
客户端连接复用与限流
使用 http.Transport 配置连接池,设置 MaxIdleConnsPerHost: 100,配合 golang.org/x/time/rate.Limiter 实现每秒 50 单并发压测控制。
订单处理流程(mermaid)
graph TD
A[HTTP Request] --> B{Valid?}
B -->|Yes| C[Generate OrderID]
B -->|No| D[400 Bad Request]
C --> E[Save to Redis Cache]
E --> F[Async Kafka Push]
示例:轻量订单结构体复用
var orderPool = sync.Pool{
New: func() interface{} {
return &Order{CreatedAt: time.Now()} // 预分配时间戳,避免每次 new
},
}
// 使用时:order := orderPool.Get().(*Order)
// 处理完需归还:orderPool.Put(order)
sync.Pool 显著降低高频订单场景下内存分配开销;CreatedAt 预设避免 time.Now() 多次调用竞争。
2.3 基于Context与中间件的请求生命周期管理
HTTP 请求在 Go 中并非孤立事件,而是嵌入 context.Context 的有界、可取消、可携带元数据的生命周期单元。
中间件链式编排机制
中间件通过闭包包装 http.Handler,形成责任链:
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 注入请求ID到ctx
ctx := context.WithValue(r.Context(), "req_id", uuid.New().String())
r = r.WithContext(ctx) // 关键:传递增强后的上下文
next.ServeHTTP(w, r)
})
}
逻辑分析:
r.WithContext()替换原请求的Context,确保下游处理器(含后续中间件及最终 handler)均可通过r.Context().Value("req_id")安全获取;context.WithValue仅适用于传递请求级元数据,不可用于传递可变状态或函数。
生命周期关键阶段对照表
| 阶段 | 触发时机 | Context 可操作性 |
|---|---|---|
| 请求进入 | 中间件首层执行前 | ✅ 可派生子ctx(超时/取消) |
| 业务处理中 | Handler 内部调用 | ✅ 可监听 Done() 通道 |
| 响应写出后 | ServeHTTP 返回后 |
❌ ctx 已失效,禁止访问 |
请求流拓扑(简化版)
graph TD
A[Client Request] --> B[Middleware 1]
B --> C[Middleware 2]
C --> D[Final Handler]
D --> E[Response Write]
2.4 订单状态机建模与事务一致性保障(Saga模式初探)
订单生命周期需严格遵循“创建→支付→履约→完成/取消”状态跃迁,避免脏状态。我们采用基于事件驱动的 Saga 模式解耦分布式事务。
状态机核心定义
public enum OrderStatus {
CREATED, PAID, SHIPPED, COMPLETED, CANCELLED, PAY_FAILED, SHIP_FAILED
}
该枚举明确边界状态,禁止非法跳转(如 CREATED → COMPLETED),所有变更必须经 StateTransitionValidator 校验。
Saga 协调流程
graph TD
A[CreateOrder] --> B[ReserveInventory]
B --> C[ProcessPayment]
C --> D[ScheduleDelivery]
D --> E[MarkCompleted]
B -.-> F[CompensateInventory]
C -.-> G[RefundPayment]
D -.-> H[CancelDelivery]
补偿动作设计原则
- 每个正向服务必须提供幂等、可逆的补偿接口
- 补偿操作按反向顺序执行(LIFO)
- 所有 Saga 步骤记录到
saga_log表,含saga_id,step,status,compensation_command
| 字段 | 类型 | 说明 |
|---|---|---|
saga_id |
UUID | 全局唯一 Saga 跟踪标识 |
step |
VARCHAR | 当前执行步骤名(如 “payment”) |
compensation_command |
JSON | 序列化后的补偿指令(含重试参数) |
2.5 gRPC流式API实现订单实时通知与进度推送
核心设计动机
传统 REST 轮询导致延迟高、连接冗余;gRPC 双向流(stream)天然适配订单生命周期事件的持续广播场景。
定义流式服务契约
service OrderService {
// 服务端流:客户端订阅单个订单的全生命周期事件
rpc WatchOrder (OrderRequest) returns (stream OrderEvent);
// 双向流:支持客户端动态启停多个订单监听,并接收系统级状态变更
rpc StreamOrderUpdates (stream OrderAction) returns (stream OrderEvent);
}
message OrderEvent {
string order_id = 1;
OrderStatus status = 2; // enum: CREATED, PAYING, SHIPPED, DELIVERED
int32 progress_percent = 3; // 0–100,用于前端进度条
string timestamp = 4;
}
逻辑分析:
WatchOrder采用服务端流(Server Streaming),轻量高效;StreamOrderUpdates支持动态增删监听目标(如通过OrderAction{type: "SUBSCRIBE", order_id: "o-123"}),提升资源利用率。progress_percent字段使前端无需轮询即可渲染实时进度。
事件类型对照表
| 事件类型 | 触发时机 | 前端响应动作 |
|---|---|---|
PAYING |
支付网关回调成功 | 启动物流轨迹轮播 |
SHIPPED |
仓库出库单生成 | 显示快递单号+ETA |
DELIVERED |
骑手上报签收 | 自动关闭通知通道 |
流控与可靠性保障
- 使用 gRPC
Keepalive参数维持长连接(time=30s,timeout=10s) - 每个
OrderEvent带event_id与sequence_number,支持断线重连时按序去重恢复
graph TD
A[客户端发起 WatchOrder] --> B[服务端校验权限 & 订单归属]
B --> C{订单存在且可读?}
C -->|是| D[打开流,推送当前状态 + 后续变更]
C -->|否| E[返回 FAILED_PRECONDITION]
D --> F[监听领域事件总线]
第三章:服务注册发现与动态配置治理
3.1 etcd分布式键值存储原理与Go客户端深度集成
etcd 基于 Raft 共识算法实现强一致性的分布式键值存储,所有写操作经 Leader 节点日志复制与多数派确认后才提交,保障线性一致性。
数据同步机制
Raft 日志复制流程:
- 客户端请求 → Leader 追加日志 → 并行发送 AppendEntries → Follower 持久化并响应 → Leader 提交日志 → 应用状态机
cli, _ := clientv3.New(clientv3.Config{
Endpoints: []string{"localhost:2379"},
DialTimeout: 5 * time.Second,
})
// Endpoints: etcd 集群访问地址列表
// DialTimeout: 建立 gRPC 连接超时阈值,避免初始化阻塞
Go 客户端核心能力对比
| 功能 | clientv3 支持 | 说明 |
|---|---|---|
| Watch 事件监听 | ✅ | 支持流式增量变更通知 |
| 事务(Txn) | ✅ | Compare-and-Swap 原子操作 |
| 租约(Lease) | ✅ | 自动续期、会话保活基础 |
graph TD
A[Client Write] --> B[Leader Append Log]
B --> C{Replicate to Followers?}
C -->|Yes| D[Quorum Ack]
C -->|No| E[Retry/Re-elect]
D --> F[Commit & Apply]
3.2 基于etcd的自动服务注册/注销与健康探针实践
核心机制:TTL租约 + 监听驱动
etcd通过Lease实现服务生命周期绑定:服务启动时创建带TTL的租约,并将服务元数据(如/services/api-v1/10.0.1.5:8080)以该租约为父节点写入;心跳续期失败则自动删除键,触发下线。
健康探针实现
# 启动服务并注册(含30秒TTL)
ETCDCTL_API=3 etcdctl lease grant 30
# 输出:lease 326a7c49d7b7e5fc
ETCDCTL_API=3 etcdctl put /services/web/10.0.1.5:8080 '{"ip":"10.0.1.5","port":8080}' --lease=326a7c49d7b7e5fc
逻辑说明:
lease grant 30创建30秒生存期租约;--lease=将键绑定至租约。后续需每15秒调用etcdctl lease keep-alive <ID>续期,否则键自动过期。
服务发现监听流
graph TD
A[服务实例] -->|注册+心跳| B[etcd集群]
B --> C[Watch /services/...]
C --> D[客户端实时感知增删]
探针策略对比
| 策略 | 频率 | 开销 | 适用场景 |
|---|---|---|---|
| TCP连接探测 | 5s | 低 | 通用端口存活验证 |
| HTTP GET /health | 10s | 中 | 应用层健康状态 |
| 自定义脚本执行 | 30s | 高 | 复杂依赖检查 |
3.3 配置中心化管理:订单超时策略与限流阈值热更新
传统硬编码的超时与限流参数导致每次变更需重启服务,严重影响业务连续性。引入配置中心(如 Nacos / Apollo)实现动态治理。
数据同步机制
配置中心监听变更事件,通过长轮询或 WebSocket 推送至各订单服务实例。
动态刷新示例(Spring Cloud Alibaba)
@RefreshScope
@Component
public class OrderPolicyConfig {
@Value("${order.timeout.seconds:300}") // 默认5分钟
private int timeoutSeconds; // 订单支付超时(秒)
@Value("${rate.limit.qps:100}") // 默认100 QPS
private int qpsLimit;
// getter 方法省略
}
逻辑分析:@RefreshScope 触发 Bean 重建;@Value 绑定配置项,支持运行时覆盖。timeoutSeconds 影响 OrderTimeoutTask 的调度周期,qpsLimit 被 Sentinel FlowRule 加载为并发控制阈值。
关键配置项对照表
| 配置项 | 含义 | 典型值 | 生效范围 |
|---|---|---|---|
order.timeout.seconds |
支付超时时间 | 300, 600, 1800 | 订单状态机、定时扫描任务 |
rate.limit.qps |
每秒订单创建上限 | 50, 100, 200 | API 网关 + 应用层双控 |
热更新流程
graph TD
A[配置中心修改] --> B[推送变更事件]
B --> C[应用监听并刷新Bean]
C --> D[Sentinel规则管理器重载FlowRule]
D --> E[订单服务立即生效新限流策略]
第四章:可观测性体系构建与生产级运维支撑
4.1 Prometheus指标建模:订单QPS、延迟、错误率自定义埋点
核心指标定义与选型
订单系统需聚焦三大黄金信号:
- QPS:
rate(order_created_total[1m])(每秒新建订单数) - 延迟:
histogram_quantile(0.95, rate(order_processing_duration_seconds_bucket[1m])) - 错误率:
rate(order_failed_total[1m]) / rate(order_created_total[1m])
自定义埋点代码示例
// 初始化Prometheus指标
var (
orderCreated = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "order_created_total",
Help: "Total number of orders created",
},
[]string{"source"}, // 按渠道维度打标
)
orderDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Name: "order_processing_duration_seconds",
Help: "Order processing latency in seconds",
Buckets: prometheus.ExponentialBuckets(0.01, 2, 8), // 10ms~1.28s
},
[]string{"status"}, // 成功/失败分桶
)
)
逻辑说明:
CounterVec支持多维标签聚合,便于按来源拆分QPS;HistogramVec自动构建_bucket、_sum、_count三类时序,支撑SLA延迟计算。ExponentialBuckets适配订单处理时间长尾分布。
指标关联关系
| 指标名 | 类型 | 关键标签 | 用途 |
|---|---|---|---|
order_created_total |
Counter | source="app" |
QPS分母 & 错误率基准 |
order_processing_duration_seconds_bucket |
Histogram | status="success" |
P95延迟计算源 |
graph TD
A[订单创建请求] --> B[orderCreated.Inc]
A --> C[Start timer]
C --> D{处理完成?}
D -->|Yes| E[orderDuration.WithLabelValues(status).Observe(latency)]
D -->|No| F[记录失败并计数]
4.2 Grafana可视化看板搭建与SLO告警规则配置
创建SLO核心指标看板
在Grafana中新建Dashboard,添加Panel,选择Prometheus数据源,查询表达式:
# 计算HTTP请求成功率(95% SLO目标)
100 * (
sum(rate(http_request_total{code=~"2.."}[1h]))
/
sum(rate(http_request_total[1h]))
)
该表达式以1小时滑动窗口统计成功请求占比;code=~"2.."精准匹配2xx响应,避免将302等重定向误计为成功。
配置SLO告警规则
在Prometheus alert.rules.yml中定义:
- alert: SLO_BurnRateHigh
expr: (1 - avg_over_time(http_request_success_ratio[1h])) > 0.05
for: 10m
labels: { severity: "warning" }
annotations: { summary: "SLO burn rate exceeds 5%" }
avg_over_time确保稳定性,for: 10m防止瞬时抖动误报。
告警通知路由表
| Route | Matcher | Receiver |
|---|---|---|
| SLO-Alerts | severity="warning" |
email+slack |
| SLO-Critical | severity="critical" |
pagerduty |
数据流闭环
graph TD
A[Prometheus采集指标] --> B[Grafana渲染SLO看板]
B --> C[Alertmanager触发SLO告警]
C --> D[多通道通知+自动工单]
4.3 分布式链路追踪:OpenTelemetry + Jaeger全链路注入实践
在微服务架构中,请求横跨多个服务节点,传统日志难以定位性能瓶颈。OpenTelemetry 作为云原生可观测性标准,与 Jaeger(后端存储与UI)组合,构建零侵入、高兼容的追踪体系。
部署轻量 Jaeger 后端(All-in-One)
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp \
-p 5778:5778 -p 16686:16686 -p 4317:4317 -p 4318:4318 \
-p 9411:9411 \
jaegertracing/all-in-one:1.49
该命令启动 Jaeger 全组件容器:UDP 端口接收 OpenTelemetry 的 otlp 协议数据(4317/4318),同时暴露 Zipkin 兼容接口(9411)及 Web UI(16686)。COLLECTOR_ZIPKIN_HOST_PORT 环境变量启用 Zipkin 接收器,便于多协议共存。
OpenTelemetry SDK 注入示例(Go)
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/trace"
)
func initTracer() {
exporter, _ := otlptracehttp.New(context.Background(),
otlptracehttp.WithEndpoint("localhost:4318"), // Jaeger OTLP HTTP 端点
otlptracehttp.WithInsecure(), // 开发环境禁用 TLS
)
tp := trace.NewTracerProvider(trace.WithBatcher(exporter))
otel.SetTracerProvider(tp)
}
此代码初始化 OpenTelemetry TracerProvider,通过 otlptracehttp 导出器将 span 数据以 HTTP+JSON 格式推送至 Jaeger 的 /v1/traces 接口(端口 4318)。WithInsecure() 表明跳过证书校验,适用于本地调试;生产环境需替换为 WithTLSClientConfig(...)。
关键配置对比表
| 组件 | 协议 | 默认端口 | 用途 |
|---|---|---|---|
| Jaeger UI | HTTP | 16686 | 可视化查询追踪链路 |
| OTLP HTTP | HTTP/JSON | 4318 | OpenTelemetry 推送 span |
| OTLP gRPC | gRPC | 4317 | 更高效,推荐生产使用 |
| Zipkin API | HTTP/JSON | 9411 | 兼容旧版 Zipkin 客户端 |
追踪数据流转流程
graph TD
A[Service A] -->|OTLP HTTP| B(Jaeger Collector)
B --> C[Jaeger Storage]
C --> D[Jaeger Query]
D --> E[Web UI 16686]
4.4 日志统一采集:结构化日志输出与ELK栈对接方案
为实现日志可检索、可分析、可告警,需从应用层输出结构化日志,并无缝接入ELK(Elasticsearch + Logstash + Kibana)栈。
结构化日志输出规范
采用 JSON 格式输出,关键字段包括 timestamp、level、service_name、trace_id、span_id 和 message:
{
"timestamp": "2024-05-20T08:32:15.123Z",
"level": "INFO",
"service_name": "order-service",
"trace_id": "a1b2c3d4e5f67890",
"span_id": "z9y8x7w6v5",
"message": "Order created successfully",
"order_id": "ORD-2024-78901"
}
逻辑分析:该格式兼容 Logstash 的
jsoncodec,trace_id与span_id支持全链路追踪对齐;order_id等业务字段作为 top-level 字段,可直接被 Elasticsearch 映射为 keyword 或 long 类型,避免嵌套解析开销。
ELK 接入拓扑
graph TD
A[Java App] -->|HTTP/Fluentd TCP| B(Logstash)
B --> C[Elasticsearch]
C --> D[Kibana]
Logstash 配置要点
- 输入插件:
tcp或beats(推荐 Filebeat 轻量采集) - 过滤插件:
json { source => "message" }解析原始日志 - 输出插件:
elasticsearch { hosts => ["es:9200"] index => "%{service_name}-%{+YYYY.MM.dd}" }
| 字段 | 说明 | 示例值 |
|---|---|---|
index 模板 |
按服务名+日期分索引 | order-service-2024.05.20 |
hosts |
ES 集群地址 | ["http://es-node1:9200", "http://es-node2:9200"] |
pipeline |
启用 ILM 生命周期管理 | true |
第五章:Docker Compose一键部署与实战验证
快速启动多容器应用的标准化流程
Docker Compose 通过 docker-compose.yml 文件声明式定义服务依赖、网络拓扑与卷挂载策略,彻底替代手动执行十余条 docker run 命令的繁琐操作。以部署一个典型的微服务前端(React)、后端(Spring Boot)与数据库(PostgreSQL)三组件系统为例,仅需一个 YAML 文件即可完成全栈环境初始化。
核心配置文件结构解析
以下为生产就绪型 docker-compose.yml 片段,已启用健康检查、资源限制与自定义桥接网络:
version: '3.8'
services:
web:
build: ./frontend
ports: ["3000:3000"]
depends_on:
api:
condition: service_healthy
api:
build: ./backend
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/appdb
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: appdb
POSTGRES_USER: appuser
POSTGRES_PASSWORD: changeme
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
volumes:
pgdata:
多环境差异化部署实践
通过 docker-compose.override.yml 和 docker-compose.prod.yml 实现开发与生产环境分离:开发环境启用热重载卷挂载与调试端口暴露,生产环境则关闭日志输出、启用 TLS 代理及 CPU 内存硬限制。执行 docker compose --profile prod up -d 即可按需激活生产配置集。
实战验证:从零构建并压测电商搜索服务
在阿里云 ECS(4C8G)上部署 Elasticsearch + Kibana + Logstash(ELK)栈用于商品搜索日志分析。使用 docker compose up -d 启动后,通过 docker compose exec kibana curl -X GET "http://localhost:9200/_cat/health?v" 验证集群状态;再运行 JMeter 脚本模拟 500 并发用户持续请求 /search?q=phone 接口,监控 docker stats 输出确认内存占用稳定在 2.1GB 以内,无 OOM kill 记录。
故障注入与恢复能力验证
人为停用 db 服务后,观察 api 容器因健康检查失败被自动重启(由 restart: on-failure 策略触发),并在 42 秒内恢复服务可用性;同时 web 层通过前端降级策略展示“搜索暂时不可用”提示,避免雪崩效应。
| 操作命令 | 说明 | 执行耗时(平均) |
|---|---|---|
docker compose up -d |
启动全部服务 | 18.3s |
docker compose logs -f api |
实时跟踪后端日志 | 即时响应 |
docker compose down --volumes |
彻底清理含数据卷 | 5.7s |
CI/CD 流水线集成关键点
在 GitLab CI 中配置 docker-compose 任务时,需预先加载 Docker socket 并设置 COMPOSE_DOCKER_CLI_BUILD=1 以支持 BuildKit 加速镜像构建;同时将 .env 文件设为受保护变量,防止数据库密码泄露至流水线日志。
网络连通性深度验证
使用 docker compose exec web ping -c 3 api 与 docker compose exec api telnet db 5432 组合命令,交叉验证服务间四层连通性;再通过 docker network inspect ecommerce_default 查看 IP 分配详情,确认所有容器均注册于同一自定义网络 ecommerce_default,子网为 172.20.0.0/16。
监控指标采集配置
在 docker-compose.yml 中为每个服务添加 labels,供 Prometheus 自动发现:
labels:
- "prometheus.io/scrape=true"
- "prometheus.io/port=9100"
启动 prometheus 服务后,其 targets 页面实时显示 web、api、db 三个 endpoint 的健康状态与抓取延迟。
性能瓶颈定位方法论
当搜索接口 P95 响应时间突增至 2.4s 时,执行 docker compose top api 发现 JVM 进程 CPU 占用率达 98%,结合 docker compose exec api jstat -gc $(pidof java) 输出确认频繁 Full GC;最终通过调整 -Xmx2g -XX:+UseG1GC JVM 参数并扩容 api 服务内存限制至 mem_limit: 3g 解决问题。
