为了账号安全,请及时绑定邮箱和手机立即绑定

如何限制在 Go 中实现的 HTTP 服务器的连接数?

如何限制在 Go 中实现的 HTTP 服务器的连接数?

Go
倚天杖 2021-07-29 09:49:36
我正在尝试在 Golang 中实现一个 HTTP 服务器。我的问题是,我必须将任何特定时间的最大活动连接数限制为 20。
查看完整描述

3 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

如果您不想实现自己的包装器,可以使用该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))


查看完整回答
反对 回复 2021-08-02
?
阿晨1998

TA贡献2037条经验 获得超6个赞

这个技巧是实现你自己的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

}

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


查看完整回答
反对 回复 2021-08-02
?
温温酱

TA贡献1752条经验 获得超4个赞

借助通道,您可以限制活动连接的数量。


1.在服务器启动时创建一个通道并将相同数量的限制计数(在您的情况下为 20)值放入该通道。


2.在处理一个请求时从通道中删除一个值。


网络上的一个例子


type limitHandler struct {

    connc   chan struct{}

    handler http.Handler

}


func (h *limitHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {

    select {

    case <-connc:

        h.handler.ServeHTTP(w, req)

        connc <- struct{}{}

    default:

        http.Error(w, "503 too busy", StatusServiceUnavailable)

    }

}


func NewLimitHandler(maxConns int, handler http.Handler) http.Handler {

    h := &limitHandler{

        connc:   make(chan struct{}, maxConns),

        handler: handler,

    }

    for i := 0; i < maxConns; i++ {

        connc <- struct{}{}

    }

    return h

}


查看完整回答
反对 回复 2021-08-02
  • 3 回答
  • 0 关注
  • 299 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信