2014-11-28 12 views
10

Come potrei limitare il caricamento e la velocità di download dal server in golang?Come potrei limitare il caricamento e la velocità di download dal server in golang?

Sto scrivendo un server golang per consentire agli utenti di caricare e scaricare file. E il file è grande, circa 1 GB di byte. Voglio limitare la velocità di upload e download a (ad esempio) 1MB/s (configurabile ovviamente).

sotto è il mio codice di caricamento:

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) 
    } 
} 

risposta

14

C'è un algoritmo token bucket che può essere utile per implementare tale limite di velocità. Ho trovato un esempio di implementazione, che è possibile utilizzare: 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)) 
} 

Dopo l'esecuzione di esso, l'output è:

Copied 1048576 bytes in 9.239607694s 

È possibile utilizzare diverse implementazioni benna per fornire comportamento desiderato. Nel codice, dopo aver configurato secchio giusto modo, si potrebbe chiamare:

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

Questo può limitare file di velocità di scrittura, ma ho visto task manager modulo di rete a mantenere alti speed.I vogliono limitare speed.thanks di trasferimento dei dati di rete comunque – waitwone

+0

È un mio problema. Dovrei usare r.MultipartReader() e reader.NextPart() invece di r.FromFile(), perché r.FromFile() salverà i dati in un file temporaneo di sistema. Grazie! – waitwone

2

si potrebbe verificare l'attuazione di PuerkitoBio/throttled, presentato in this article:

throttled, un pacchetto Go che implementa varie strategie per controllare l'accesso alle Gestori HTTP.
supporta la limitazione della velocità delle richieste, il flusso di intervalli costante delle richieste e le soglie di utilizzo della memoria per concedere o negare l'accesso, ma fornisce anche meccanismi per estenderne le funzionalità.

Il limite di velocità non è esattamente quello che ti serve, ma può dare una buona idea per implementing a similar feature.

Problemi correlati