如何限制在go中实现的HTTP Server的连接数?

Ale*_*hew 12 go httpserver

我试图在golang中实现HTTP服务器.

我的问题是,我必须将任何特定时间的最大活动连接数限制为20.

小智 14

如果您不想实现自己的包装器,可以使用该netutil.LimitListener函数net.Listener包装: -

connectionCount := 20

l, err := net.Listen("tcp", ":8000")

if err != nil {
    log.Fatalf("Listen: %v", err)
}

defer l.Close()

l = netutil.LimitListener(l, connectionCount)

log.Fatal(http.Serve(l, nil))
Run Code Online (Sandbox Code Playgroud)

  • 这是否消除了“http.ListenAndServe”的正常“tcpKeepAliveListener”行为? (2认同)

Kyl*_*ons 5

这样做的诀窍是实现自己的net.Listener.我有一个听众的例子这里(见waitConn和WaitListener)跟踪连接(但不限制他们),你可以为灵感的实现中使用.它将形成如下形状:

type LimitedListener struct {
    sync.Mutex
    net.Listener
    sem chan bool
}

func NewLimitedListener(count int, l net.Listener) *net.LimitedListener {
    sem := make(chan bool, count)
    for i := 0; i < count; i++ {
        sem <- true
    }
    return &net.LimitedListener{
        Listener: l,
        sem:      sem,
    }
}

func (l *LimitedListener) Addr() net.Addr { /* ... */ }
func (l *LimitedListener) Close() error { /* ... */ }
func (l *LimitedListener) Accept() (net.Conn, err) {
    <-l.sem // acquire
    // l.Listener.Accept (on error, release before returning)
    // wrap LimitedConn
    return c, nil
}

type LimitedConn struct { /* ... */ }

func (c *LimitedConn) Close() error {
    /* ... */
    c.sem <- true // release
}
Run Code Online (Sandbox Code Playgroud)

基本上它正在做的是创建你自己的net.Listener实现,你可以给Serve只能在它获取信号量时调用底层的Accept; 如此获得的信号量仅在(适当包装的)net.Conn关闭时释放.注意,从技术上讲,这种信号量的使用对于go1.2 内存模型是正确的.在Go的未来版本中,更简单的信号量将是合法的.