猿问

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

我正在尝试在 Golang 中实现一个 HTTP 服务器。

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


倚天杖
浏览 300回答 3
3回答

慕盖茨4494581

如果您不想实现自己的包装器,可以使用该netutil.LimitListener函数进行环绕net.Listener:-connectionCount := 20l, 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))

阿晨1998

这个技巧是实现你自己的net.Listener。我在这里有一个监听器示例(请参阅 waitConn 和 WaitListener),它跟踪连接(但不限制它们),您可以将其用作实现的灵感。它将被塑造成这样:type LimitedListener struct {&nbsp; &nbsp; sync.Mutex&nbsp; &nbsp; net.Listener&nbsp; &nbsp; sem chan bool}func NewLimitedListener(count int, l net.Listener) *net.LimitedListener {&nbsp; &nbsp; sem := make(chan bool, count)&nbsp; &nbsp; for i := 0; i < count; i++ {&nbsp; &nbsp; &nbsp; &nbsp; sem <- true&nbsp; &nbsp; }&nbsp; &nbsp; return &net.LimitedListener{&nbsp; &nbsp; &nbsp; &nbsp; Listener: l,&nbsp; &nbsp; &nbsp; &nbsp; sem:&nbsp; &nbsp; &nbsp; sem,&nbsp; &nbsp; }}func (l *LimitedListener) Addr() net.Addr { /* ... */ }func (l *LimitedListener) Close() error { /* ... */ }func (l *LimitedListener) Accept() (net.Conn, err) {&nbsp; &nbsp; <-l.sem // acquire&nbsp; &nbsp; // l.Listener.Accept (on error, release before returning)&nbsp; &nbsp; // wrap LimitedConn&nbsp; &nbsp; return c, nil}type LimitedConn struct { /* ... */ }func (c *LimitedConn) Close() error {&nbsp; &nbsp; /* ... */&nbsp; &nbsp; c.sem <- true // release}本质上,这样做是创建您自己的 net.Listener 实现,您可以将其提供给Serve,它仅在可以获取信号量时调用底层 Accept;如此获取的信号量仅在(适当包装的)net.Conn关闭时才释放。请注意,从技术上讲,这种信号量的使用对于 go1.2内存模型是正确的;在Go 的未来版本中,更简单的信号量将是合法的。

温温酱

借助通道,您可以限制活动连接的数量。1.在服务器启动时创建一个通道并将相同数量的限制计数(在您的情况下为 20)值放入该通道。2.在处理一个请求时从通道中删除一个值。网络上的一个例子type limitHandler struct {&nbsp; &nbsp; connc&nbsp; &nbsp;chan struct{}&nbsp; &nbsp; handler http.Handler}func (h *limitHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {&nbsp; &nbsp; select {&nbsp; &nbsp; case <-connc:&nbsp; &nbsp; &nbsp; &nbsp; h.handler.ServeHTTP(w, req)&nbsp; &nbsp; &nbsp; &nbsp; connc <- struct{}{}&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; http.Error(w, "503 too busy", StatusServiceUnavailable)&nbsp; &nbsp; }}func NewLimitHandler(maxConns int, handler http.Handler) http.Handler {&nbsp; &nbsp; h := &limitHandler{&nbsp; &nbsp; &nbsp; &nbsp; connc:&nbsp; &nbsp;make(chan struct{}, maxConns),&nbsp; &nbsp; &nbsp; &nbsp; handler: handler,&nbsp; &nbsp; }&nbsp; &nbsp; for i := 0; i < maxConns; i++ {&nbsp; &nbsp; &nbsp; &nbsp; connc <- struct{}{}&nbsp; &nbsp; }&nbsp; &nbsp; return h}
随时随地看视频慕课网APP

相关分类

Go
我要回答