Upgrade to Pro — share decks privately, control downloads, hide ads and more …

帯域制限とx/time/rate

FUJIWARA Shunichiro
September 16, 2016
590

 帯域制限とx/time/rate

FUJIWARA Shunichiro

September 16, 2016
Tweet

More Decks by FUJIWARA Shunichiro

Transcript

  1. GoͰଳҬ੍ݶ͕͍ͨ͠ • Ϧιʔε࢖͍͗͢๷ࢭ • StretcherͰμ΢ϯϩʔυଳҬ੍ݶ • ϕϯνϚʔΫ • Fluentd in_tail

    ϕϯνϚʔΫͷͨΊͷ go-dummer • (ࣾ಺)ISUCON ϕϯνϚʔΧʔͰଳҬΤϛϡϨʔγϣϯ • io.Reader, io.Writer ΠϯλʔϑΣʔεͩͱศར
  2. ͭ͘Γ·ͨ͠ (4݄) github.com/fujiwara/shapeio import "github.com/fujiwara/shapeio" r := shapeio.NewReader(reader) // io.Reader

    r.SetRateLimit(1024 * 10) // 10KB/sec // ͋ͱ͸ී௨ʹ io.Reader ͱͯ͠࢖͏ Writer΋͋Γ·͢
  3. x/time/rate Ͱॻ͖௚͠ before (ଳҬ੍ޚͰ଴ͭ෦෼) func (l *limiter) wait(n int, err

    error) (int, error) { if n == 0 || err != nil { return n, err } elapsed := time.Since(l.startedAt) l.bytes += int64(n) rate := float64(l.bytes) / elapsed.Seconds() if rate < l.bytesPerSec { return n, nil } d := time.Duration(float64(l.bytes)/l.bytesPerSec*float64(time.Second) - float64(elapsed)) time.Sleep(d) // reset shaping window l.startedAt = time.Now() l.bytes = 0 return n, nil }
  4. x/time/rate Ͱॻ͖௚͠ after func (s *Writer) Write(p []byte) (int, error)

    { if s.limiter == nil { return s.w.Write(p) } n, err := s.w.Write(p) if err != nil { return n, err } // ଴ͭͱ͜Ζ͸͚ͩ͜͜ if err := s.limiter.WaitN(s.ctx, n); err != nil { return n, err } return n, err }
  5. x/time/rate ಋೖͷ෭࢈෺ context ͕࢖͑ΔΑ͏ʹ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Seconds) r

    := shapeio.NewReaderWithContext(reader, ctx) shapeio.SetRateLimit(1024 * 1024) io.Copy(w, r) ... ଳҬ੍ݶͭͭ͠λΠϜΞ΢τ΍Ωϟϯηϧ΋