性能优化
1. Go性能分析工具
CPU分析
import "runtime/pprof"
func main() {
f, err := os.Create("cpu.prof")
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal(err)
}
defer pprof.StopCPUProfile()
// 你的应用代码
}
内存分析
import "runtime/pprof"
func main() {
f, err := os.Create("mem.prof")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// 你的应用代码
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal(err)
}
}
使用pprof工具
# 分析CPU性能
go tool pprof cpu.prof
# 分析内存
go tool pprof mem.prof
# 实时Web分析(适用于HTTP服务)
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/profile
2. CPU和内存优化
减少内存分配
// 不好的做法:频繁分配
func process(data []byte) string {
return string(data) // 每次分配新字符串
}
// 优化做法:复用缓冲区
var bufPool = sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(make([]byte, 0, 1024))
},
}
func processOptimized(data []byte) string {
buf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(buf)
buf.Reset()
buf.Write(data)
return buf.String()
}
使用值类型而非指针
// 指针类型(可能增加GC压力)
type User struct {
Name *string
Age *int
}
// 值类型(更高效)
type User struct {
Name string
Age int
}
3. 并发模式优化
工作池模式
func workerPool(jobs <-chan Job, results chan<- Result) {
var wg sync.WaitGroup
for i := 0; i < runtime.NumCPU(); i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs {
results <- process(job)
}
}()
}
wg.Wait()
close(results)
}
批量处理
func batchProcess(items []Item) {
batchSize := 100
var wg sync.WaitGroup
for i := 0; i < len(items); i += batchSize {
wg.Add(1)
go func(start int) {
defer wg.Done()
end := start + batchSize
if end > len(items) {
end = len(items)
}
processBatch(items[start:end])
}(i)
}
wg.Wait()
}
4. HTTP服务优化
连接池配置
func createHTTPClient() *http.Client {
return &http.Client{
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
},
Timeout: 60 * time.Second,
}
}
Gin性能优化
func main() {
// 生产模式(禁用调试和彩色日志)
gin.SetMode(gin.ReleaseMode)
r := gin.New()
// 使用中间件
r.Use(gin.Recovery())
// 禁用控制台颜色
gin.DisableConsoleColor()
// 路由分组
api := r.Group("/api")
{
api.GET("/users", getUsers)
api.GET("/orders", getOrders)
}
// 静态文件服务(带缓存控制)
r.Static("/static", "./public")
// 启动服务
s := &http.Server{
Addr: ":8080",
Handler: r,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 120 * time.Second,
}
s.ListenAndServe()
}
5. 数据库查询优化
批量插入
// 不好的做法:单条插入
for _, user := range users {
_, err := db.Exec("INSERT INTO users (name, email) VALUES (?, ?)",
user.Name, user.Email)
if err != nil {
return err
}
}
// 优化做法:批量插入
valueStrings := make([]string, 0, len(users))
valueArgs := make([]interface{}, 0, len(users)*2)
for _, user := range users {
valueStrings = append(valueStrings, "(?, ?)")
valueArgs = append(valueArgs, user.Name)
valueArgs = append(valueArgs, user.Email)
}
stmt := fmt.Sprintf("INSERT INTO users (name, email) VALUES %s",
strings.Join(valueStrings, ","))
_, err := db.Exec(stmt, valueArgs...)
使用预处理语句
// 创建预处理语句
stmt, err := db.Prepare("SELECT id, name FROM users WHERE email = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
// 复用预处理语句
for _, email := range emails {
var user User
err := stmt.QueryRow(email).Scan(&user.ID, &user.Name)
if err != nil {
log.Println(err)
continue
}
// 处理用户...
}
索引优化
-- 添加索引
CREATE INDEX idx_users_email ON users(email);
-- 复合索引
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- 使用EXPLAIN分析查询
EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';
提示:性能优化应该基于实际测量,而不是猜测。始终使用分析工具识别真正的瓶颈,然后有针对性地优化。
