当您在容器服务集群中部署 Golang 应用时,可以使用云原生观测对 Golang 应用进行监控。本文为您介绍在集群中监控 Golang 应用的方法和操作步骤。
Prometheus 提供了 官方版 Golang 库 用于采集并暴露监控数据。当您开发 Golang 应用时,可以使用该 Golang 库来暴露 Golang runtime 相关的数据。
说明
Golang Client API 相关的文档详见 GoDoc。
您可以通过 go get
命令来安装相关依赖,示例如下:
go get github.com/prometheus/client_golang/prometheus go get github.com/prometheus/client_golang/prometheus/collectors go get github.com/prometheus/client_golang/prometheus/promhttp
创建一个 HTTP 服务,路径使用 /metrics
。可以直接使用 prometheus/promhttp
里提供的 Handler
函数。
如下是一个简单的示例,通过 http://localhost:2023/metrics
暴露 Golang 应用的一些默认指标数据,包括:运行时指标、进程相关指标以及构建相关的指标。
package main
import (
"math"
"math/rand"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
// Create a new registry.
reg := prometheus.NewRegistry()
// Add Go module build info.
reg.MustRegister(collectors.NewBuildInfoCollector())
// Add go runtime metrics and process collectors.
reg.MustRegister(
collectors.NewGoCollector(),
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
)
http.Handle("/metrics", promhttp.HandlerFor(
reg, promhttp.HandlerOpts{},
))
http.ListenAndServe(":2023", nil)
}
执行以下命令,启动应用。
go run main.go
执行以下命令,即可查看运行时的指标数据。
curl http://localhost:2023/metrics
package main
import (
"math"
"math/rand"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var rpcDurations = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "rpc_durations_seconds",
Help: "RPC latency distributions.",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
},
[]string{"service"},
)
func main() {
// Create a new registry.
reg := prometheus.NewRegistry()
// Add Go module build info.
reg.MustRegister(collectors.NewBuildInfoCollector())
// Add go runtime metrics and process collectors.
reg.MustRegister(
collectors.NewGoCollector(),
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
)
reg.MustRegister(rpcDurations)
start := time.Now()
oscillationFactor := func() float64 {
return 2 + math.Sin(math.Sin(2*math.Pi*float64(time.Since(start))/float64(10*time.Minute)))
}
// Periodically record some sample latencies for the three services.
go func() {
for {
v := rand.Float64() * 0.0002
rpcDurations.WithLabelValues("uniform").Observe(v)
time.Sleep(time.Duration(100*oscillationFactor()) * time.Millisecond)
}
}()
go func() {
for {
v := (rand.NormFloat64() * 0.0002) + 0.00001
rpcDurations.WithLabelValues("normal").Observe(v)
time.Sleep(time.Duration(75*oscillationFactor()) * time.Millisecond)
}
}()
go func() {
for {
v := rand.ExpFloat64() / 1e6
rpcDurations.WithLabelValues("exponential").Observe(v)
time.Sleep(time.Duration(50*oscillationFactor()) * time.Millisecond)
}
}()
http.Handle("/metrics", promhttp.HandlerFor(
reg, promhttp.HandlerOpts{},
))
http.ListenAndServe(":2023", nil)
}
go run main.go
从输出结果我们可以看到curl http://localhost:2023/metrics
rpc_durations_seconds
计数器相关的信息,包括帮助文档、类型信息、指标名和当前值。# HELP rpc_durations_seconds RPC latency distributions.
# TYPE rpc_durations_seconds summary
rpc_durations_seconds{service="exponential",quantile="0.5"} 7.427294276581254e-07
rpc_durations_seconds{service="exponential",quantile="0.9"} 2.3157390817424027e-06
已开启云原生观测,详情请参见 开启观测。
说明
该 Dockerfile 仅为示例,您需要按需修改里面的参数。
FROM golang:1.19 as builder
COPY . /go/src/demo
WORKDIR /go/src/demo
RUN go env -w GOPROXY=https://goproxy.cn,direct && \
go mod init && \
go mod tidy && \
go mod vendor && \
go build -v -o /golang-demo
FROM buildpack-deps:bullseye-curl
RUN mkdir -p /app
COPY --from=builder /golang-demo /app
WORKDIR /app
ENV TZ Asia/Shanghai
EXPOSE 2023
ENTRYPOINT ["/app/golang-demo"]
说明
火山引擎镜像仓库的镜像推送方式,请参见 推送和拉取镜像。
您可以使用镜像仓库中的镜像,在容器服务 VKE 集群中部署应用。步骤如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: golang-demo # 配置应用的名称
namespace: volcano-metrics # 配置应用所在的命名空间
labels:
app: golang-demo # 配置应用的标签
spec:
replicas: 2 # 配置应用副本数
selector:
matchLabels:
app: golang-demo
template:
metadata:
labels:
app: golang-demo
spec:
containers:
- name: golang-demo # 配置容器名称
image: doc-cn-beijing.cr.volces.com/vmp/golang-demo:1.0 # 配置应用镜像的地址和版本
ports:
- containerPort: 2023 # 配置容器端口
apiVersion: v1
kind: Service
metadata:
name: golang-service-demo
namespace: volcano-metrics # 配置 Service 的命名空间
labels:
app: golang-service-demo # 配置 Service 的标签
spec:
selector:
app: golang-demo
ports:
- protocol: TCP
port: 2023
targetPort: 2023
name: metrics # 配置服务端口名称
type: ClusterIP
当应用部署并正常运行后,可以使用 ServiceMonitor 配置服务发现,具体的操作步骤如下:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: golang-demo # 填写一个唯一名称
namespace: default # 配置 ServiceMonitor 命名空间
labels:
volcengine.vmp: "true" # 配置 ServiceMonitor 的标签,允许被 Prometheus-agent 发现
spec:
endpoints:
- interval: 30s
port: metrics # 配置服务端口名称
path: /metrics
relabelings:
- action: replace
sourceLabels: [__meta_kubernetes_pod_label_app]
targetLabel: application
namespaceSelector:
matchNames:
- volcano-metrics # 配置服务所在的命名空间
selector:
matchLabels:
app: golang-service-demo # 配置服务的 Label 值,以定位目标服务
您可以使用托管 Prometheus 服务的 Explore 功能来查看监控指标数据。详情请参见 指标查询。
您也可以使用 Grafana 读取托管 Prometheus 服务中存储的数据,并创建指标大盘。详情请参见 将托管 Prometheus 数据接入自建 Grafana。