回答
這個把戲是實現自己的net.Listener。我有一個監聽器here(請參閱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只調用底層的接受時,它可以獲取的信號;如此獲得的信號量僅在(適當包裝的)net.Conn關閉時才被釋放。請注意,技術上這種信號量的使用對於go1.2 memory model是正確的;在Go的future versions中,一個更簡單的信號量將是合法的。
感謝您的回覆。你能告訴我 如何監視服務器(查看活動空閒連接的數量)? –
存儲原始計數,並從中減去len(l.sem)以獲取(即時)正在等待關閉的連接數。 –
這可能不安全。我偶爾在net/http/Server的同一個連接上看到多次調用Close()。根據io.Closer接口,這是未定義的行爲,在嘗試釋放(從chan讀取)時,會導致Close()調用阻塞。請考慮使用netutil.LimitListener,而不是另一個回答中所述;它有一個包裝來確保通道只能從每個連接讀取一次。 (儘管如此,它仍然將重複的Close調用傳遞給底層的Listener,但這仍然是未定義的行爲。) –
藉助通道,您可以限制活動連接的數量。
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
}
'connc < - struct {} {}'應該可能是'defer'-ed。然後,如果發生恐慌(從別處恢復),連接「插槽」仍然會返回到池中。 – justinas
從技術上講,這不會限制傳入連接,它只會限制您一次發送多少個響應。這是一種有用的模式,儘管可能基於例如加載而不是絕對連接計數。 –
可以使用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))
- 1. Web服務器的連接數限制
- 2. 限制Tomcat的HTTP連接器到Apache服務器
- 3. 打開http連接的Netty服務器限制
- 4. 限制連接到服務器
- 5. node.js服務器限制新連接
- 6. 限制在服務器端返回的行數(強制限制)
- 7. 如何在GET/PHP5中限制每秒連接服務器的數量?
- 8. Java執行器服務連接池
- 9. 如何根據ssh連接的服務器執行python腳本?
- 10. 如何在WCF數據服務的服務端執行連接操作
- 11. JxBrowser - 限制每個服務器/代理的最大連接數
- 12. 限制服務器端的併發連接數量?
- 13. 鏈接的服務器連接在哪裏執行計算?
- 14. 如何連接到在android模擬器中運行的http服務器?
- 15. 如何處理ThreadPool達到服務器連接限制
- 16. 如何限制WebSocket服務器連接只有一個?
- 17. Java連接池不限制向DB服務器打開的TCP連接數
- 18. 如何限制客戶端服務器程序中的連接數
- 19. 瀏覽器HTTP連接限制和YouTube
- 20. 連接到HTTP服務器的urllib.request連接的持久性
- 21. 如何限制用戶訪問HTTP服務器上的文件?
- 22. ASP.NET HTTP連接限制
- 23. HTTP持續連接限制
- 24. 限制SELECT語句的行數,與鏈接服務器
- 25. 如何在SQL中進行連接時限制行的上限?
- 26. Restlet和Apache http服務器的http連接器
- 27. 如何測試HTTP服務器中的持久連接?
- 28. IIS 6並行連接數限制Web服務
- 29. 如何在流星中使用限制強制執行服務器端分頁
- 30. 如何限制WCF服務的請求執行時間?
使用nginx的作爲反向代理是最簡單的。 http://stackoverflow.com/questions/17776584/webserver-for-go-golang-webservices-using-nginx-or-not – rmmh