Go提供了强大的性能分析工具,帮助识别和解决性能瓶颈。
package main
import (
"net/http"
_ "net/http/pprof"
)
func main() {
// 启动pprof服务器
go func() {
http.ListenAndServe("localhost:6060", nil)
}()
// 你的应用代码
}
// 访问性能分析:
// http://localhost:6060/debug/pprof/
import (
"os"
"runtime/pprof"
)
func main() {
// 创建CPU profile文件
f, _ := os.Create("cpu.prof")
defer f.Close()
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// 你的代码
}
// 分析profile文件
// go tool pprof cpu.prof
// (pprof) top
// (pprof) list functionName
// (pprof) web
import (
"os"
"runtime/pprof"
)
func main() {
// 你的代码
// 创建内存profile
f, _ := os.Create("mem.prof")
defer f.Close()
pprof.WriteHeapProfile(f)
}
// 分析内存使用
// go tool pprof mem.prof
// 不好:每次循环都分配新切片
func bad() []int {
var result []int
for i := 0; i < 1000; i++ {
result = append(result, i)
}
return result
}
// 好:预分配容量
func good() []int {
result := make([]int, 0, 1000)
for i := 0; i < 1000; i++ {
result = append(result, i)
}
return result
}
// 不好:字符串拼接
func bad() string {
s := ""
for i := 0; i < 1000; i++ {
s += "a"
}
return s
}
// 好:使用strings.Builder
func good() string {
var sb strings.Builder
for i := 0; i < 1000; i++ {
sb.WriteString("a")
}
return sb.String()
}
var bufferPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
func processData(data []byte) {
buf := bufferPool.Get().(*bytes.Buffer)
defer bufferPool.Put(buf)
buf.Reset()
// 使用buffer处理数据
buf.Write(data)
}
// 使用worker pool限制并发数
func processItems(items []Item) {
const numWorkers = 10
jobs := make(chan Item, len(items))
results := make(chan Result, len(items))
// 启动workers
for w := 0; w < numWorkers; w++ {
go worker(jobs, results)
}
// 发送任务
for _, item := range items {
jobs <- item
}
close(jobs)
// 收集结果
for i := 0; i < len(items); i++ {
<-results
}
}
package main
import (
"context"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
srv := &http.Server{Addr: ":8080"}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
// 等待中断信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
// 优雅关闭
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("服务器强制关闭:", err)
}
log.Println("服务器已退出")
}
import (
"go.uber.org/zap"
)
func main() {
// 生产环境配置
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("服务启动",
zap.String("port", "8080"),
zap.Int("workers", 10),
)
logger.Error("处理失败",
zap.Error(err),
zap.String("user_id", "123"),
)
}
import (
"github.com/spf13/viper"
)
func loadConfig() {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath("/etc/myapp/")
// 环境变量
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
log.Fatal(err)
}
port := viper.GetInt("server.port")
dbHost := viper.GetString("database.host")
}
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
httpRequests = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "HTTP请求总数",
},
[]string{"method", "endpoint", "status"},
)
httpDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP请求延迟",
},
[]string{"method", "endpoint"},
)
)
func init() {
prometheus.MustRegister(httpRequests)
prometheus.MustRegister(httpDuration)
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}
# Dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
func healthHandler(w http.ResponseWriter, r *http.Request) {
// 检查数据库连接
if err := db.Ping(); err != nil {
w.WriteHeader(http.StatusServiceUnavailable)
json.NewEncoder(w).Encode(map[string]string{
"status": "unhealthy",
"error": err.Error(),
})
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{
"status": "healthy",
})
}
func main() {
http.HandleFunc("/health", healthHandler)
http.ListenAndServe(":8080", nil)
}
恭喜你完成了Go语言从入门到高级的完整学习!通过这15课的学习,你已经掌握了:
继续实践和探索,你将成为一名优秀的Go开发者!