次回予告「並列ダウンロードするHTTPクライアントをバンド幅制限するサーバをGoで実装した」 / “高速でダウンロードできるツールを Go で実装した。 - Qiita” https://t.co/6NfEyJCwbu
— Kazuho Oku (@kazuho) July 13, 2016
並列ダウンローダを使うと幾らかサーバに負荷が掛かってしまいます。golang のサーバ側で帯域制限を行う場合には2つ方法があります。
- 転送量制限する
- 接続数制限する
まずは転送量制限。転送量の制限には throttled が便利です。
GitHub - throttled/throttled: Package throttled implements rate limiting access to resources such as HTTP endpoints.http.Handler 互換のミドルウェアなので既存のサーバに埋め込む形で使えます。
README.md Throttled Package throttled implements rate limiting access to resources such as HTTP endp...
https://github.com/throttled/throttled
store, err := memstore.New(65536)
if err != nil {
log.Fatal(err)
}
quota := throttled.RateQuota{throttled.PerMin(20), 5}
rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
if err != nil {
log.Fatal(err)
}
httpRateLimiter := throttled.HTTPRateLimiter{
RateLimiter: rateLimiter,
VaryBy: &throttled.VaryBy{Path: true},
}
http.ListenAndServe(":8080", httpRateLimiter.RateLimit(myHandler))
次に接続数制限。接続数制限には netutil.LimitedListener を使います。
netutil - GoDoc
package netutil import "golang.org/x/net/netutil" Package netutil provides network utility functions...
https://godoc.org/golang.org/x/net/netutil#LimitListener
こちらは net.Listener にかぶせるだけで最大接続本数を制限できます。
package main
import (
"fmt"
"golang.org/x/net/netutil"
"log"
"net"
"net/http"
)
func main() {
l, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "")
})
http.Serve(netutil.LimitListener(l, 100), http.DefaultServeMux)
}
今年の夏も暑そうですが、頑張って乗り切りましょう。