英文:
Limiting bandwidth of http get
问题
我是一个对golang初学者。
有没有办法限制golang的http.Get()的带宽使用?我找到了这个链接:http://godoc.org/code.google.com/p/mxk/go1/flowcontrol,但我不确定如何将它们组合在一起。我如何访问http Reader?
英文:
I'm a beginner to golang.
Is there any way to limit golang's http.Get() bandwidth usage? I found this: http://godoc.org/code.google.com/p/mxk/go1/flowcontrol, but I'm not sure how to piece the two together. How would I get access to the http Reader?
答案1
得分: 17
第三方包提供了方便的封装。但是如果你对底层的工作原理感兴趣,那就很容易了。
package main
import (
"io"
"net/http"
"os"
"time"
)
var datachunk int64 = 500 //字节
var timelapse time.Duration = 1 //每秒
func main() {
responce, _ := http.Get("http://google.com")
for range time.Tick(timelapse * time.Second) {
_, err := io.CopyN(os.Stdout, responce.Body, datachunk)
if err != nil {
break
}
}
}
没有什么魔法。
英文:
Thirdparty packages have convenient wrappers. But if you interested in how things work under the hood - it's quite easy.
package main
import (
"io"
"net/http"
"os"
"time"
)
var datachunk int64 = 500 //Bytes
var timelapse time.Duration = 1 //per seconds
func main() {
responce, _ := http.Get("http://google.com")
for range time.Tick(timelapse * time.Second) {
_, err :=io.CopyN(os.Stdout, responce.Body, datachunk)
if err!=nil {break}
}
}
Nothing magic.
答案2
得分: 6
你可以通过包装一个 io.Reader
来使用它。
下面是一个完整的示例,它会非常慢地显示 Google 的主页。
在 Go 中,通过包装接口来实现新功能是非常好的编码风格,在你学习 Go 的过程中会经常遇到。
package main
import (
"io"
"log"
"net/http"
"os"
"github.com/mxk/go-flowrate/flowrate"
)
func main() {
resp, err := http.Get("http://google.com")
if err != nil {
log.Fatalf("Get failed: %v", err)
}
defer resp.Body.Close()
// 每秒限制为 10 字节
wrappedIn := flowrate.NewReader(resp.Body, 10)
// 复制到标准输出
_, err = io.Copy(os.Stdout, wrappedIn)
if err != nil {
log.Fatalf("Copy failed: %v", err)
}
}
英文:
There is an updated version of the package on github
You use it by wrapping an io.Reader
Here is a complete example which will show the homepage of Google veeeery sloooowly.
This wrapping an interface to make new functionality is very good Go style, and you'll see a lot of it in your journey into Go.
package main
import (
"io"
"log"
"net/http"
"os"
"github.com/mxk/go-flowrate/flowrate"
)
func main() {
resp, err := http.Get("http://google.com")
if err != nil {
log.Fatalf("Get failed: %v", err)
}
defer resp.Body.Close()
// Limit to 10 bytes per second
wrappedIn := flowrate.NewReader(resp.Body, 10)
// Copy to stdout
_, err = io.Copy(os.Stdout, wrappedIn)
if err != nil {
log.Fatalf("Copy failed: %v", err)
}
}
答案3
得分: 0
你可以使用https://github.com/ConduitIO/bwlimit来限制服务器和客户端请求的带宽。它与其他库不同之处在于,它尊重读/写截止时间(超时时间),并且限制整个请求(包括标头)的带宽,而不仅仅是请求体。
以下是在客户端上如何使用它的示例代码:
package main
import (
"io"
"net"
"net/http"
"time"
"github.com/conduitio/bwlimit"
)
const (
writeLimit = 1 * bwlimit.Mebibyte // 写入限制为1048576 B/s
readLimit = 4 * bwlimit.KB // 读取限制为4000 B/s
)
func main() {
// 更改默认传输中的拨号器以使用带宽限制
dialer := bwlimit.NewDialer(&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}, writeLimit, readLimit)
http.DefaultTransport.(*http.Transport).DialContext = dialer.DialContext
// 默认客户端的请求现在遵守带宽限制
resp, _ := http.DefaultClient.Get("http://google.com")
_, _ = io.Copy(resp.Body)
}
然而,正如Graham King指出的那样,请记住,从远程读取的数据仍然会尽可能快地填充TCP缓冲区,而该库只会从缓冲区中慢慢读取。不过,限制写入的带宽会产生预期的结果。
英文:
You can use https://github.com/ConduitIO/bwlimit to limit the bandwidth of requests on the server and the client. It differs from other libraries, because it respects read/write deadlines (timeouts) and limits the bandwidth of the whole request including headers, not only the request body.
Here's how to use it on the client:
package main
import (
"io"
"net"
"net/http"
"time"
"github.com/conduitio/bwlimit"
)
const (
writeLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s
readLimit = 4 * bwlimit.KB // read limit is 4000 B/s
)
func main() {
// change dialer in the default transport to use a bandwidth limit
dialer := bwlimit.NewDialer(&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}, writeLimit, readLimit)
http.DefaultTransport.(*http.Transport).DialContext = dialer.DialContext
// requests through the default client respect the bandwidth limit now
resp, _ := http.DefaultClient.Get("http://google.com")
_, _ = io.Copy(resp.Body)
}
However, as Graham King pointed out, keep in mind that reads from remote will still fill the TCP buffer as fast as possible, this library will only read slowly from the buffer. Limiting the bandwidth of writes produces the expected result though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论