服务做个最大连接数限制

一般海量处理服务,都会对服务做个最大连接数限制,超过该限制之后,拒绝服务,避免发生雪崩,压坏服务。

使用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
}
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值