LoginSignup
3
2

More than 3 years have passed since last update.

golang Echoでhttpの最大接続数を設定する

Posted at

golang + Echoで実装されたWebサーバの最大接続数を制限する方法です。

前提条件

Custom Listenerを利用する

Echoはnet.Listenerを設定できるようになっているので同時接続数を制限したListenerを設定してやる。

cf. https://github.com/labstack/echo/blob/master/echo.go#L79
    Echo struct {
        common
        StdLogger        *stdLog.Logger
        colorer          *color.Color
        premiddleware    []MiddlewareFunc
        middleware       []MiddlewareFunc
        maxParam         *int
        router           *Router
        routers          map[string]*Router
        notFoundHandler  HandlerFunc
        pool             sync.Pool
        Server           *http.Server
        TLSServer        *http.Server
        Listener         net.Listener
        TLSListener      net.Listener
        AutoTLSManager   autocert.Manager
        DisableHTTP2     bool
        Debug            bool
        HideBanner       bool
        HidePort         bool
        HTTPErrorHandler HTTPErrorHandler
        Binder           Binder
        Validator        Validator
        Renderer         Renderer
        Logger           Logger
    }

netutilを使ってListenerを作成する

ln, err := net.Listen("tcp", ポート番号)
if err != nil {
    log.Fatal(err)
}
 // LimitListenerの作成
listener := netutil.LimitListener(ln, 同時接続数)

実装例


package main

import (
    "log"
    "net"
    "net/http"
    "time"

    "golang.org/x/net/netutil"

    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
)

func main() {
    e := echo.New()

    e.HideBanner = true
    e.HidePort = true

    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    e.GET("/", func(c echo.Context) error {
        time.Sleep(995 * time.Millisecond)
        return c.String(http.StatusOK, "Hello, World!\n")
    })

    ln, err := net.Listen("tcp", ":1323")
    if err != nil {
        log.Fatal(err)
    }

    // LimitListenerの作成
    listener := netutil.LimitListener(ln, 2)
    e.Listener = listener

    e.Logger.Fatal(e.Start(""))
}

ざっくりと検証

vegetaでリクエストした結果、多少の誤差はありますがほぼ期待した動作をしているようです。


$ echo "GET http://localhost:1323/" | vegeta attack -rate=3 -duration=10s | vegeta report
Requests      [total, rate]            30, 3.10
Duration      [total, attack, wait]    39.337579882s, 9.663924965s, 29.673654917s
Latencies     [mean, 50, 95, 99, max]  12.601428969s, 1.000919979s, 30.005719753s, 30.005729277s, 30.005729277s
Bytes In      [total, mean]            252, 8.40
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  60.00%
Status Codes  [code:count]             0:12  200:18
Error Set:
Get http://localhost:1323/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2