40分钟学 Go 语言高并发:【实战】高并发系统综合实战

【实战】高并发系统综合实战

一、知识要点总览

模块核心内容关键技术难度
架构设计系统设计、数据模型、接口定义分层架构、微服务、消息队列
性能优化缓存设计、异步处理、数据库优化Redis、Kafka、MySQL
压力测试性能测试、稳定性测试、容量测试JMeter、Gotest
问题排查日志分析、性能分析、故障定位pprof、Jaeger、ELK

让我们开始实现一个高性能的秒杀系统:

1. 系统架构设计

首先展示系统的整体架构:
在这里插入图片描述

2. 核心代码实现

让我们实现系统的核心组件:

// seckill/model.go
package seckill

import (
    "time"
)

type Product struct {
    ID            int64     `json:"id" gorm:"primary_key"`
    Name          string    `json:"name"`
    Price         float64   `json:"price"`
    Stock         int       `json:"stock"`
    StartTime     time.Time `json:"start_time"`
    EndTime       time.Time `json:"end_time"`
    LimitPerUser  int       `json:"limit_per_user"`
}

type Order struct {
    ID          int64     `json:"id" gorm:"primary_key"`
    UserID      int64     `json:"user_id"`
    ProductID   int64     `json:"product_id"`
    Quantity    int       `json:"quantity"`
    Status      int       `json:"status"`
    CreateTime  time.Time `json:"create_time"`
    UpdateTime  time.Time `json:"update_time"`
}

// seckill/service.go
package seckill

import (
    "context"
    "fmt"
    "github.com/go-redis/redis/v8"
    "github.com/Shopify/sarama"
    "gorm.io/gorm"
)

type SeckillService struct {
    db          *gorm.DB
    redisClient *redis.Client
    producer    sarama.SyncProducer
    cache       *Cache
}

func NewSeckillService(db *gorm.DB, redisClient *redis.Client, producer sarama.SyncProducer) *SeckillService {
    return &SeckillService{
        db:          db,
        redisClient: redisClient,
        producer:    producer,
        cache:       NewCache(redisClient),
    }
}

// 秒杀入口
func (s *SeckillService) Seckill(ctx context.Context, userID, productID int64, quantity int) error {
    // 1. 参数校验
    if err := s.validateParams(ctx, userID, productID, quantity); err != nil {
        return err
    }

    // 2. 检查秒杀是否开始
    if err := s.checkSeckillTime(ctx, productID); err != nil {
        return err
    }

    // 3. 检查用户购买限制
    if err := s.checkUserLimit(ctx, userID, productID); err != nil {
        return err
    }

    // 4. 预扣库存
    if err := s.preDeductStock(ctx, productID, quantity); err != nil {
        return err
    }

    // 5. 发送创建订单消息
    if err := s.sendOrderMessage(ctx, userID, productID, quantity); err != nil {
        // 恢复库存
        s.revertStock(ctx, productID, quantity)
        return err
    }

    return nil
}

// 参数校验
func (s *SeckillService) validateParams(ctx context.Context, userID, productID int64, quantity int) error {
    if userID <= 0 || productID <= 0 || quantity <= 0 {
        return fmt.Errorf("invalid parameters")
    }
    return nil
}

// 检查秒杀时间
func (s *SeckillService) checkSeckillTime(ctx context.Context, productID int64) error {
    product, err := s.cache.GetProduct(ctx, productID)
    if err != nil {
        return err
    }

    now := time.Now()
    if now.Before(product.StartTime) {
        return fmt.Errorf("seckill not started")
    }
    if now.After(product.EndTime) {
        return fmt.Errorf("seckill ended")
    }
    return nil
}

// 检查用户购买限制
func (s *SeckillService) checkUserLimit(ctx context.Context, userID, productID int64) error {
    count, err := s.cache.GetUserBuyCount(ctx, userID, productID)
    if err != nil {
        return err
    }

    product, err := s.cache.GetProduct(ctx, productID)
    if err != nil {
        return err
    }

    if count >= product.LimitPerUser {
        return fmt.Errorf("exceed purchase limit")
    }
    return nil
}

// 预扣库存
func (s *SeckillService) preDeductStock(ctx context.Context, productID int64, quantity int) error {
    script := `
        local stock = redis.call('get', KEYS[1])
        if not stock or tonumber(stock) < tonumber(ARGV[1]) then
            return 0
        end
        redis.call('decrby', KEYS[1], ARGV[1])
        return 1
    `
    stockKey := fmt.Sprintf("product:%d:stock", productID)
    result, err := s.redisClient.Eval(ctx, script, []string{stockKey}, quantity).Result()
    if err != nil {
        return err
    }
    if result.(int64) == 0 {
        return fmt.Errorf("insufficient stock")
    }
    return nil
}

// 发送订单消息
func (s *SeckillService) sendOrderMessage(ctx context.Context, userID, productID int64, quantity int) error {
    message := &OrderMessage{
        UserID:    userID,
        ProductID: productID,
        Quantity:  quantity,
        Time:      time.Now(),
    }

    data, err := json.Marshal(message)
    if err != nil {
        return err
    }

    msg := &sarama.ProducerMessage{
        Topic: "orders",
        Value: sarama.ByteEncoder(data),
    }

    _, _, err = s.producer.SendMessage(msg)
    return err
}

// 恢复库存
func (s *SeckillService) revertStock(ctx context.Context, productID int64, quantity int) {
    stockKey := fmt.Sprintf("product:%d:stock", productID)
    s.redisClient.IncrBy(ctx, stockKey, int64(quantity))
}

3. 缓存设计

让我们实现缓存层:

// cache/cache.go
package cache

import (
    "context"
    "encoding/json"
    "fmt"
    "github.com/go-redis/redis/v8"
    "time"
)

type Cache struct {
    client *redis.Client
}

func NewCache(client *redis.Client) *Cache {
    return &Cache{client: client}
}

// 获取商品信息
func (c *Cache) GetProduct(ctx context.Context, productID int64) (*Product, error) {
    key := fmt.Sprintf("product:%d", productID)
    data, err := c.client.Get(ctx, key).Bytes()
    if err != nil {
        if err == redis.Nil {
            // 缓存未命中,从数据库加载
            product, err := loadProductFromDB(productID)
            if err != nil {
                return nil, err
            }
            // 写入缓存
            if err := c.setProduct(ctx, product); err != nil {
                return nil, err
            }
            return product, nil
        }
        return nil, err
    }

    var product Product
    if err := json.Unmarshal(data, &product); err != nil {
        return nil, err
    }
    return &product, nil
}

// 设置商品信息
func (c *Cache) setProduct(ctx context.Context, product *Product) error {
    key := fmt.Sprintf("product:%d", product.ID)
    data, err := json.Marshal(product)
    if err != nil {
        return err
    }
    return c.client.Set(ctx, key, data, time.Hour).Err()
}

// 获取库存
func (c *Cache) GetStock(ctx context.Context, productID int64) (int, error) {
    key := fmt.Sprintf("product:%d:stock", productID)
    stock, err := c.client.Get(ctx, key).Int()
    if err != nil {
        if err == redis.Nil {
            // 缓存未命中,从数据库加载
            stock, err := loadStockFromDB(productID)
            if err != nil {
                return 0, err
            }
            // 写入缓存
            if err := c.setStock(ctx, productID, stock); err != nil {
                return 0, err
            }
            return stock, nil
        }
        return 0, err
    }
    return stock, nil
}

// 设置库存
func (c *Cache) setStock(ctx context.Context, productID int64, stock int) error {
    key := fmt.Sprintf("product:%d:stock", productID)
    return c.client.Set(ctx, key, stock, time.Hour).Err()
}

// 获取用户购买次数
func (c *Cache) GetUserBuyCount(ctx context.Context, userID, productID int64) (int, error) {
    key := fmt.Sprintf("user:%d:product:%d", userID, productID)
    count, err := c.client.Get(ctx, key).Int()
    if err != nil && err != redis.Nil {
        return 0, err
    }
    return count, nil
}

// 增加用户购买次数
func (c *Cache) IncrUserBuyCount(ctx context.Context, userID, productID int64) error {
    key := fmt.Sprintf("user:%d:product:%d", userID, productID)
    return c.client.Incr(ctx, key).Err()
}

// 实现分布式锁
type Lock struct {
    client    *redis.Client
    key       string
    value     string
    expiration time.Duration
}

func NewLock(client *redis.Client, key string) *Lock {
    return &Lock{
        client:     client,
        key:        fmt.Sprintf("lock:%s", key),
        value:      uuid.New().String(),
        expiration: time.Second * 10,
    }
}

// 获取锁
func (l *Lock) Acquire(ctx context.Context) (bool, error) {
    return l.client.SetNX(ctx, l.key, l.value, l.expiration).Result()
}

// 释放锁
func (l *Lock) Release(ctx context.Context) error {
    script := `
        if redis.call('get', KEYS[1]) == ARGV[1] then
            return redis.call('del', KEYS[1])
        end
        return 0
    `
    result, err := l.client.Eval(ctx, script, []string{l.key}, l.value).Result()
    if err != nil {
        return err
    }
    if result.(int64) != 1 {
        return fmt.Errorf("lock already released")
    }
    return nil
}

// 缓存预热
func (c *Cache) WarmUp(ctx context.Context, productIDs []int64) error {
    for _, productID := range productIDs {
        product, err := loadProductFromDB(productID)
        if err != nil {
            return err
        }
        
        if err := c.setProduct(ctx, product); err != nil {
            return err
        }
        
        stock, err := loadStockFromDB(productID)
        if err != nil {
            return err
        }
        
        if err := c.setStock(ctx, productID, stock); err != nil {
            return err
        }
    }
    return nil
}

让我们继续完成压力测试部分的实现:

4. 压力测试实现

// test/stress_test.go
package test

import (
    "context"
    "testing"
    "time"
    "sync"
    "github.com/stretchr/testify/assert"
)

// 压力测试配置
type StressConfig struct {
    Concurrent    int           // 并发用户数
    TotalRequests int           // 总请求数
    QPS          int           // 每秒请求数
    Duration     time.Duration // 测试持续时间
}

// 压力测试结果
type StressResult struct {
    TotalRequests  int           // 总请求数
    SuccessCount   int           // 成功请求数
    FailureCount   int           // 失败请求数
    MinLatency     time.Duration // 最小延迟
    MaxLatency     time.Duration // 最大延迟
    AvgLatency     time.Duration // 平均延迟
    TotalDuration  time.Duration // 总耗时
    QPS            float64       // 实际QPS
}

func TestSeckillStress(t *testing.T) {
    config := StressConfig{
        Concurrent:    100,
        TotalRequests: 10000,
        QPS:          1000,
        Duration:     time.Minute,
    }

    result := runStressTest(t, config)

    // 检查测试结果
    assert.True(t, result.SuccessCount > 0)
    assert.True(t, result.QPS >= float64(config.QPS)*0.8) // QPS不低于目标的80%
    assert.True(t, result.AvgLatency < time.Millisecond*100) // 平均延迟小于100ms
}

func runStressTest(t *testing.T, config StressConfig) *StressResult {
    var (
        wg sync.WaitGroup
        mu sync.Mutex
        result = &StressResult{
            MinLatency: time.Hour, // 初始化为一个较大值
        }
    )

    // 创建限速器
    limiter := time.NewTicker(time.Second / time.Duration(config.QPS))
    defer limiter.Stop()

    // 创建上下文
    ctx, cancel := context.WithTimeout(context.Background(), config.Duration)
    defer cancel()

    // 启动并发goroutine
    for i := 0; i < config.Concurrent; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()

            for {
                select {
                case <-ctx.Done():
                    return
                case <-limiter.C:
                    if result.TotalRequests >= config.TotalRequests {
                        return
                    }

                    start := time.Now()
                    err := seckill(ctx)
                    duration := time.Since(start)

                    mu.Lock()
                    result.TotalRequests++
                    if err == nil {
                        result.SuccessCount++
                    } else {
                        result.FailureCount++
                    }

                    // 更新延迟统计
                    if duration < result.MinLatency {
                        result.MinLatency = duration
                    }
                    if duration > result.MaxLatency {
                        result.MaxLatency = duration
                    }
                    result.TotalDuration += duration
                    mu.Unlock()
                }
            }
        }()
    }

    // 等待所有请求完成
    wg.Wait()

    // 计算最终结果
    result.AvgLatency = result.TotalDuration / time.Duration(result.TotalRequests)
    result.QPS = float64(result.SuccessCount) / result.TotalDuration.Seconds()

    return result
}

// 模拟秒杀请求
func seckill(ctx context.Context) error {
    // 初始化服务
    service := initSeckillService()
    
    // 模拟用户ID和商品ID
    userID := rand.Int63n(10000)
    productID := int64(1) // 假设只有一个商品
    quantity := 1

    // 发起秒杀请求
    err := service.Seckill(ctx, userID, productID, quantity)
    if err != nil {
        // 记录错误日志
        log.Printf("Seckill failed: %v", err)
        return err
    }

    return nil
}

// HTTP压力测试
func BenchmarkHTTPSeckill(b *testing.B) {
    // 启动HTTP服务器
    server := startTestServer()
    defer server.Close()

    // 创建HTTP客户端
    client := &http.Client{
        Timeout: time.Second * 5,
    }

    b.ResetTimer()
    b.RunParallel(func(pb *testing.PB) {
        for pb.Next() {
            // 构造请求
            req, err := http.NewRequest("POST", "http://localhost:8080/seckill", nil)
            if err != nil {
                b.Fatal(err)
            }

            // 发送请求
            resp, err := client.Do(req)
            if err != nil {
                b.Fatal(err)
            }
            resp.Body.Close()

            // 检查响应状态
            if resp.StatusCode != http.StatusOK {
                b.Errorf("Expected status OK but got %v", resp.Status)
            }
        }
    })
}

// 启动测试服务器
func startTestServer() *httptest.Server {
    // 初始化handler
    handler := NewSeckillHandler(initSeckillService())
    
    // 创建路由
    router := chi.NewRouter()
    router.Post("/seckill", handler.Seckill)
    
    // 启动服务器
    return httptest.NewServer(router)
}

// 性能监控
type Performance struct {
    CPU    float64
    Memory uint64
    GC     struct {
        Count     uint32
        Pause     time.Duration
        PauseAvg  time.Duration
    }
}

func monitorPerformance(ctx context.Context) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            var m runtime.MemStats
            runtime.ReadMemStats(&m)

            perf := Performance{
                Memory: m.Alloc,
                GC: struct {
                    Count     uint32
                    Pause     time.Duration
                    PauseAvg  time.Duration
                }{
                    Count:    m.NumGC,
                    Pause:    time.Duration(m.PauseNs[(m.NumGC+255)%256]),
                    PauseAvg: time.Duration(m.PauseTotal / uint64(m.NumGC)),
                },
            }

            // 获取CPU使用率
            percentage, err := cpu.Percent(time.Second, false)
            if err == nil && len(percentage) > 0 {
                perf.CPU = percentage[0]
            }

            // 记录性能指标
            log.Printf("Performance: CPU=%.2f%% Memory=%dMB GC=%d",
                perf.CPU,
                perf.Memory/1024/1024,
                perf.GC.Count,
            )
        }
    }
}

5. 问题排查工具

让我们实现一些问题排查的工具:

// troubleshoot/profiler.go
package troubleshoot

import (
    "fmt"
    "net/http"
    "runtime/pprof"
    "os"
    "time"
)

type Profiler struct {
    enabled bool
    dir     string
}

func NewProfiler(dir string) *Profiler {
    return &Profiler{
        enabled: true,
        dir:     dir,
    }
}

// CPU性能分析
func (p *Profiler) StartCPUProfile() error {
    if !p.enabled {
        return nil
    }

    filename := fmt.Sprintf("%s/cpu_%s.prof", p.dir, time.Now().Format("20060102_150405"))
    f, err := os.Create(filename)
    if err != nil {
        return err
    }

    return pprof.StartCPUProfile(f)
}

func (p *Profiler) StopCPUProfile() {
    if p.enabled {
        pprof.StopCPUProfile()
    }
}

// 内存性能分析
func (p *Profiler) WriteHeapProfile() error {
    if !p.enabled {
        return nil
    }

    filename := fmt.Sprintf("%s/heap_%s.prof", p.dir, time.Now().Format("20060102_150405"))
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    return pprof.WriteHeapProfile(f)
}

// Goroutine分析
func (p *Profiler) WriteGoroutineProfile() error {
    if !p.enabled {
        return nil
    }

    filename := fmt.Sprintf("%s/goroutine_%s.prof", p.dir, time.Now().Format("20060102_150405"))
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    return pprof.Lookup("goroutine").WriteTo(f, 1)
}

// HTTP处理器
func (p *Profiler) RegisterHandlers() {
    if !p.enabled {
        return
    }

    http.HandleFunc("/debug/pprof/", pprof.Index)
    http.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
    http.HandleFunc("/debug/pprof/profile", pprof.Profile)
    http.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
    http.HandleFunc("/debug/pprof/trace", pprof.Trace)
}

// 日志分析器
type LogAnalyzer struct {
    patterns map[string]*regexp.Regexp
}

func NewLogAnalyzer() *LogAnalyzer {
    return &LogAnalyzer{
        patterns: make(map[string]*regexp.Regexp),
    }
}

func (a *LogAnalyzer) AddPattern(name, pattern string) error {
    re, err := regexp.Compile(pattern)
    if err != nil {
        return err
    }
    a.patterns[name] = re
    return nil
}

func (a *LogAnalyzer) Analyze(logFile string) (map[string]int, error) {
    content, err := ioutil.ReadFile(logFile)
    if err != nil {
        return nil, err
    }

    results := make(map[string]int)
    lines := strings.Split(string(content), "\n")

    for _, line := range lines {
        for name, pattern := range a.patterns {
            if pattern.MatchString(line) {
                results[name]++
            }
        }
    }

    return results, nil
}

// 系统诊断工具
type Diagnostics struct {
    metrics *metrics.Collector
    tracer  *tracing.Tracer
    logger  *logging.Logger
}

func NewDiagnostics(metrics *metrics.Collector, tracer *tracing.Tracer, logger *logging.Logger) *Diagnostics {
    return &Diagnostics{
        metrics: metrics,
        tracer:  tracer,
        logger:  logger,
    }
}

func (d *Diagnostics) CollectSystemStatus() map[string]interface{} {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)

    return map[string]interface{}{
        "goroutines": runtime.NumGoroutine(),
        "memory": map[string]uint64{
            "alloc":      m.Alloc,
            "total_alloc": m.TotalAlloc,
            "sys":        m.Sys,
            "heap_alloc": m.HeapAlloc,
            "heap_sys":   m.HeapSys,
        },
        "gc": map[string]uint32{
            "num_gc": m.NumGC,
        },
    }
}

func (d *Diagnostics) CheckHealth() error {
    // 检查数据库连接
    if err := d.checkDatabase(); err != nil {
        return fmt.Errorf("database check failed: %w", err)
    }

    // 检查Redis连接
    if err := d.checkRedis(); err != nil {
        return fmt.Errorf("redis check failed: %w", err)
    }

    // 检查Kafka连接
    if err := d.checkKafka(); err != nil {
        return fmt.Errorf("kafka check failed: %w", err)
    }

    return nil
}

// 慢查询分析
type SlowQueryAnalyzer struct {
    threshold time.Duration
    queries   []SlowQuery
    mu        sync.Mutex
}

type SlowQuery struct {
    SQL      string
    Duration time.Duration
    Time     time.Time
    Params   []interface{}
}

func NewSlowQueryAnalyzer(threshold time.Duration) *SlowQueryAnalyzer {
    return &SlowQueryAnalyzer{
        threshold: threshold,
        queries:   make([]SlowQuery, 0),
    }
}

func (a *SlowQueryAnalyzer) Record(query string, duration time.Duration, params ...interface{}) {
    if duration >= a.threshold {
        a.mu.Lock()
        defer a.mu.Unlock()

        a.queries = append(a.queries, SlowQuery{
            SQL:      query,
            Duration: duration,
            Time:     time.Now(),
            Params:   params,
        })
    }
}

func (a *SlowQueryAnalyzer) GetSlowQueries() []SlowQuery {
    a.mu.Lock()
    defer a.mu.Unlock()
    
    result := make([]SlowQuery, len(a.queries))
    copy(result, a.queries)
    return result
}

6. 性能调优策略

6.1 具体实现代码:
// optimization/pool.go
package optimization

import (
    "context"
    "sync"
)

// 对象池
type Pool struct {
    pool    sync.Pool
    maxSize int
    size    int
    mu      sync.RWMutex
}

func NewPool(maxSize int, factory func() interface{}) *Pool {
    return &Pool{
        pool: sync.Pool{
            New: factory,
        },
        maxSize: maxSize,
    }
}

func (p *Pool) Get() interface{} {
    p.mu.Lock()
    if p.size >= p.maxSize {
        p.mu.Unlock()
        return nil
    }
    p.size++
    p.mu.Unlock()
    
    return p.pool.Get()
}

func (p *Pool) Put(x interface{}) {
    p.pool.Put(x)
    
    p.mu.Lock()
    p.size--
    p.mu.Unlock()
}

// 批处理优化
type Batcher struct {
    size     int
    timeout  time.Duration
    items    []interface{}
    process  func([]interface{}) error
    mu       sync.Mutex
    timer    *time.Timer
}

func NewBatcher(size int, timeout time.Duration, process func([]interface{}) error) *Batcher {
    return &Batcher{
        size:    size,
        timeout: timeout,
        process: process,
        items:   make([]interface{}, 0, size),
    }
}

func (b *Batcher) Add(item interface{}) error {
    b.mu.Lock()
    defer b.mu.Unlock()

    b.items = append(b.items, item)

    // 首次添加项目时启动定时器
    if len(b.items) == 1 {
        b.resetTimer()
    }

    // 达到批处理大小,立即处理
    if len(b.items) >= b.size {
        return b.flush()
    }

    return nil
}

func (b *Batcher) flush() error {
    if len(b.items) == 0 {
        return nil
    }

    // 处理批量项目
    items := make([]interface{}, len(b.items))
    copy(items, b.items)
    b.items = b.items[:0]

    // 停止定时器
    if b.timer != nil {
        b.timer.Stop()
        b.timer = nil
    }

    return b.process(items)
}

func (b *Batcher) resetTimer() {
    if b.timer != nil {
        b.timer.Stop()
    }
    b.timer = time.AfterFunc(b.timeout, func() {
        b.mu.Lock()
        b.flush()
        b.mu.Unlock()
    })
}

// 本地缓存优化
type LocalCache struct {
    cache    map[string]*cacheItem
    mu       sync.RWMutex
    maxSize  int
    onEvict  func(key string, value interface{})
}

type cacheItem struct {
    value      interface{}
    expireTime time.Time
    size       int
}

func NewLocalCache(maxSize int, onEvict func(key string, value interface{})) *LocalCache {
    cache := &LocalCache{
        cache:   make(map[string]*cacheItem),
        maxSize: maxSize,
        onEvict: onEvict,
    }
    
    // 启动清理过期项的goroutine
    go cache.cleanExpired()
    
    return cache
}

func (c *LocalCache) Set(key string, value interface{}, ttl time.Duration, size int) {
    c.mu.Lock()
    defer c.mu.Unlock()

    // 检查容量
    for c.getCurrentSize()+size > c.maxSize {
        c.evictOne()
    }

    c.cache[key] = &cacheItem{
        value:      value,
        expireTime: time.Now().Add(ttl),
        size:       size,
    }
}

func (c *LocalCache) Get(key string) (interface{}, bool) {
    c.mu.RLock()
    item, exists := c.cache[key]
    c.mu.RUnlock()

    if !exists || time.Now().After(item.expireTime) {
        return nil, false
    }

    return item.value, true
}

func (c *LocalCache) getCurrentSize() int {
    var size int
    for _, item := range c.cache {
        size += item.size
    }
    return size
}

func (c *LocalCache) evictOne() {
    var oldestKey string
    var oldestTime time.Time

    for key, item := range c.cache {
        if oldestKey == "" || item.expireTime.Before(oldestTime) {
            oldestKey = key
            oldestTime = item.expireTime
        }
    }

    if oldestKey != "" {
        if c.onEvict != nil {
            c.onEvict(oldestKey, c.cache[oldestKey].value)
        }
        delete(c.cache, oldestKey)
    }
}

func (c *LocalCache) cleanExpired() {
    ticker := time.NewTicker(time.Minute)
    defer ticker.Stop()

    for range ticker.C {
        c.mu.Lock()
        now := time.Now()
        for key, item := range c.cache {
            if now.After(item.expireTime) {
                if c.onEvict != nil {
                    c.onEvict(key, item.value)
                }
                delete(c.cache, key)
            }
        }
        c.mu.Unlock()
    }
}

// 协程池优化
type WorkerPool struct {
    workers    int
    tasks      chan func()
    wg         sync.WaitGroup
    quit       chan struct{}
}

func NewWorkerPool(workers int) *WorkerPool {
    pool := &WorkerPool{
        workers: workers,
        tasks:   make(chan func(), workers*2),
        quit:    make(chan struct{}),
    }
    
    pool.Start()
    return pool
}

func (p *WorkerPool) Start() {
    for i := 0; i < p.workers; i++ {
        p.wg.Add(1)
        go func() {
            defer p.wg.Done()
            for {
                select {
                case task, ok := <-p.tasks:
                    if !ok {
                        return
                    }
                    task()
                case <-p.quit:
                    return
                }
            }
        }()
    }
}

func (p *WorkerPool) Submit(task func()) {
    select {
    case p.tasks <- task:
    case <-p.quit:
    }
}

func (p *WorkerPool) Stop() {
    close(p.quit)
    close(p.tasks)
    p.wg.Wait()
}

7. 监控指标

让我们通过一个图表来展示需要监控的关键指标:
在这里插入图片描述

8. 优化要点总结

  1. 架构层面

    • 采用分层架构,合理解耦
    • 使用微服务架构提升扩展性
    • 实现无状态设计便于水平扩展
    • 采用异步处理提升吞吐量
  2. 缓存优化

    • 多级缓存策略
    • 热点数据预加载
    • 缓存更新机制
    • 防止缓存击穿和雪崩
  3. 数据库优化

    • 索引优化
    • 读写分离
    • 分库分表
    • 批量处理
  4. 并发控制

    • 使用协程池
    • 合理设置并发数
    • 实现请求限流
    • 熔断降级保护
  5. 性能监控

    • 实时监控系统指标
    • 及时发现性能瓶颈
    • 自动报警机制
    • 问题快速定位

怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值