我正在使用使用系统化套接字激活的标准库net/http包在Go中编写Web服务器。

我有一些基本的知识可以使服务器在第一次建立与侦听套接字的连接时启动,并且在发出信号时我可以执行正常关机(即systemctl stop将在不中断 Activity 请求的情况下工作)。

我想让服务器在闲置一段时间后自动退出。类似于以下内容:

  • 当最后一个 Activity 请求完成时,启动一个计时器(例如30秒)。
  • 如果在此期间到达任何新请求,请停止计时器。
  • 如果计时器到期,请执行正常关机。

  • 想法是释放服务器正在使用的资源,因为新客户出现时systemd将再次启动我们。

    我不确定部分(1)和(2)。理想情况下,我想要一个不涉及修改所有已注册处理程序的解决方案。

    最佳答案

    使用@CeriseLimón的建议,以下帮助程序类型似乎可以解决问题:

    type IdleTracker struct {
        mu     sync.Mutex
        active map[net.Conn]bool
        idle   time.Duration
        timer  *time.Timer
    }
    
    func NewIdleTracker(idle time.Duration) *IdleTracker {
        return &IdleTracker{
            active: make(map[net.Conn]bool),
            idle:   idle,
            timer:  time.NewTimer(idle),
        }
    }
    
    func (t *IdleTracker) ConnState(conn net.Conn, state http.ConnState) {
        t.mu.Lock()
        defer t.mu.Unlock()
    
        oldActive := len(t.active)
        switch state {
        case http.StateNew, http.StateActive, http.StateHijacked:
            t.active[conn] = true
            // stop the timer if we transitioned to idle
            if oldActive == 0 {
                t.timer.Stop()
            }
        case http.StateIdle, http.StateClosed:
            delete(t.active, conn)
            // Restart the timer if we've become idle
            if oldActive > 0 && len(t.active) == 0 {
                t.timer.Reset(t.idle)
            }
        }
    }
    
    func (t *IdleTracker) Done() <-chan time.Time {
        return t.timer.C
    }
    

    将其ConnState方法分配给服务器的ConnState成员将跟踪服务器是否繁忙,并在我们闲置请求的时间后向我们发送信号:
    idle := NewIdleTracker(5 * time.Second)
    server.ConnState = idle.ConnState
    
    go func() {
        <-idle.Done()
        if err := server.Shutdown(context.Background()); err != nil {
            log.Fatalf("error shutting down: %v\n", err)
        }
    }()
    

    关于http - 闲置一段时间后,如何使Go的http.Server退出?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56487495/

    10-09 06:24