golang官方實現如何對httpserver做頻率限制(最大連接數限制)


 

一般海量處理服務,都會對服務做個最大連接數限制,超過該限制之后,拒絕服務,避免發生雪崩,壓壞服務。

使用golang來編寫httpserver時,如何進行呢?官方已經有實現好的包。

使用示例:

 

import(
"golang.org/x/net/netutil"
)

l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { fmt.Fatalf("Listen: %v", err) } defer l.Close() l = LimitListener(l, max) http.Serve(l, http.HandlerFunc()) //bla bla bla.................

 

 

源碼如下(url : https://github.com/golang/net/blob/master/netutil/listen.go),基本思路就是為連接數計數,通過make chan來建立一個最大連接數的channel, 每次accept就+1,close時候就-1. 當到達最大連接數時,就等待空閑連接出來之后再accept。

// Copyright 2013 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package netutil provides network utility functions, complementing the more
// common ones in the net package.
package netutil // import "golang.org/x/net/netutil"

import (
    "net"
    "sync"
)

// LimitListener returns a Listener that accepts at most n simultaneous
// connections from the provided Listener.
func LimitListener(l net.Listener, n int) net.Listener {
    return &limitListener{l, make(chan struct{}, n)}
}

type limitListener struct {
    net.Listener
    sem chan struct{}
}

func (l *limitListener) acquire() { l.sem <- struct{}{} } func (l *limitListener) release() { <-l.sem }

func (l *limitListener) Accept() (net.Conn, error) {
//若connect chan已滿,則會阻塞在此處 l.acquire() c, err :
= l.Listener.Accept() if err != nil { l.release() return nil, err } return &limitListenerConn{Conn: c, release: l.release}, nil } type limitListenerConn struct { net.Conn releaseOnce sync.Once release func() } func (l *limitListenerConn) Close() error { err := l.Conn.Close() l.releaseOnce.Do(l.release) return err }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM