2014-11-28 2 views
10

Wie würde ich die Upload- und Download-Geschwindigkeit vom Server in Golang begrenzen?Wie würde ich die Upload- und Download-Geschwindigkeit vom Server in Golang begrenzen?

Ich schreibe einen Golang-Server, damit Benutzer Dateien hochladen und herunterladen können. Und die Datei ist groß, etwa 1 GB. Ich möchte die Upload- und Download-Geschwindigkeit auf (zum Beispiel) 1MB/s begrenzen (konfigurierbar natürlich).

unten ist mein Upload-Code:

func uploadFile(w http.ResponseWriter, r *http.Request) { 
    file, _, err := r.FormFile("file") 

    if err != nil { 
     http.Error(w, err.Error(), 500) 
     return 
    } 

    defer file.Close() 

    os.MkdirAll(`e:\test`, os.ModePerm) 
    out, err := os.Create(`e:\test\test.mpg`) 
    if err != nil { 
     http.Error(w, err.Error(), 500) 
     return 
    } 

    defer out.Close() 

    _, err = io.Copy(out, file) 
    if err != nil { 
     http.Error(w, err.Error(), 500) 
    } 
} 

Antwort

14

Es gibt einen token bucket Algorithmus, der hilfreich sein kann, um das Ratenlimit zu implementieren. Ich eine Beispiel-Implementierung gefunden, die Sie verwenden können: https://github.com/juju/ratelimit

package main 

import (
    "bytes" 
    "fmt" 
    "io" 
    "time" 

    "github.com/juju/ratelimit" 
) 

func main() { 
    // Source holding 1MB 
    src := bytes.NewReader(make([]byte, 1024*1024)) 
    // Destination 
    dst := &bytes.Buffer{} 

    // Bucket adding 100KB every second, holding max 100KB 
    bucket := ratelimit.NewBucketWithRate(100*1024, 100*1024) 

    start := time.Now() 

    // Copy source to destination, but wrap our reader with rate limited one 
    io.Copy(dst, ratelimit.Reader(src, bucket)) 

    fmt.Printf("Copied %d bytes in %s\n", dst.Len(), time.Since(start)) 
} 

Nachdem er ausgeführt wird, ist der Ausgang:

Copied 1048576 bytes in 9.239607694s 

Sie verschiedene Eimer-Implementierungen verwenden kann das gewünschte Verhalten zu liefern. In Ihrem Code, nach rechts Token-Bucket-Einrichtung, würden Sie rufen:

_, err = io.Copy(out, ratelimit.Reader(file, bucket)) 
+0

Diese Geschwindigkeit Dateischreib begrenzen kann, aber ich sah Manager Form Aufgabe das Netzwerk halten hohe speed.I Netzwerk Datenübertragung speed.thanks begrenzen möchten trotzdem – waitwone

+0

Es ist mein Problem.Ich sollte r.MultipartReader() und reader.NextPart() anstelle von r.FromFile() verwenden, weil r.FromFile() Daten in einer temporären Systemdatei gespeichert werden.Vielen Dank! – waitwone

2

Sie konnten die Implementierung von PuerkitoBio/throttled Check-out, in this article präsentiert:

throttled, ein Go-Paket, das den Zugang zu steuern verschiedene Strategien implementiert zu HTTP-Handler.
Out-of-the-Box, es unterstützt Rate-Begrenzen der Anforderungen, konstanter Intervallfluss von Anforderungen und Speicherauslastung Schwellenwerte zu gewähren oder verweigern den Zugriff, aber es bietet auch Mechanismen, um seine Funktionalität zu erweitern.

Das Ratenlimit ist nicht genau das, was Sie brauchen, kann aber eine gute Idee für implementing a similar feature geben.

Verwandte Themen