没有最后一个字节的HTTP请求?

huangapple go评论64阅读模式
英文:

HTTP request without last byte?

问题

我正在寻找一种在Golang中测试负载的方法。我在已有的工具中没有找到这个功能,我已经尝试了所有的工具。以下是我想要做的事情:

  • 创建100个完全相同的HTTP请求(作为goroutines)
  • 每个goroutine连接到HTTP服务器并发送响应的主体(可能高达几MB),除了最后一个字节
  • 在所有goroutines之间进行同步 - 等待直到所有线程都到达只剩下1个字节要发送的点
  • 根据终端的输入(例如,当我按下Enter键),发送剩余的字节,以便我可以测试服务器如何处理这种类型的负载 - 同时发送100个大请求

我查看了标准HTTP库的文档,我不认为它可以使用标准工具实现。我打算重写HTTP库的某些部分来实现这个支持,或者甚至使用旧的操作系统套接字来执行这种类型的功能。这将需要很多时间来实现。

我想知道我是否遗漏了什么,是否有一些HTTP库的特性可以轻松实现这个?感谢任何可能在不进行完全重写的情况下起作用的建议。

英文:

I'm looking to test load my app in Golang. I haven't found this functionality in already existing tools, I tried all of them. Here is what I'm trying to do:

  • Create 100 exactly the same HTTP requests (as goroutines)
  • From each goroutine connect to HTTP server and send the body of the response (which can be up to few MB), except the last byte
  • Synchronize between all goroutines - pretty much wait until all threads are at the point where there is only 1 byte left to send
  • Based on input from Terminal (for example, when I hit Enter), send the remaining byte, so I can test how the server handles this type of load - 100 large requests at the same time

I looked at the docs of the standard HTTP library, and I don't think it's possible wit standard tools. I'm looking to rewrite some parts of HTTP library to have this support, or maybe even use the plain old OS sockets to perform this type of functionality. It will require a lot of time just to implement that.

I'm wondering if I'm missing something here, some kind of HTTP library feature that allows to do that easily? Appreiate any suggestion that might work without a full rewrite.

答案1

得分: 1

据我了解,没有办法在HTTP请求的一部分发送后再发送剩余部分,但我相信我可以帮助你处理并发部分。

这里有两个变量,threads(注意Python的术语)表示同时运行的goroutine数量,number表示运行次数。

func main() {
    fmt.Println("输入运行次数")
    var number int
    fmt.Scan(&number)
    fmt.Println("输入线程数")
    var threads int
    fmt.Scan(&threads)
    swg := sizedwaitgroup.New(threads)
    for i := 0; i < number; i++ {
        swg.Add()
        go func(i int) {
            defer swg.Done() //确保在此行之后放置你的请求

            //进行请求


        }(i)
    }
    swg.Wait()

}

这段代码使用了github.com/remeh/sizedwaitgroup库。

请注意,如果其中一个最初的请求完成了,它会立即开始下一个请求,而不会等待其他请求完成。

以下是实际应用的示例:
https://codeshare.io/3A3dj4
https://pastebin.com/DP1sn1m4

编辑:
如果你进一步并设法发送除了最后一个字节之外的所有HTTP请求,你将需要使用通道来通信何时发送最后一个字节。我对通道不太熟悉,但这篇指南非常好:
https://go.dev/blog/pipelines

英文:

To my understanding there is no way to send part of a http request then the rest at the end, but I believe I can help with the concurrency part.

Two variables here, threads (mind the python terminology) = number of simultaneous goroutines, number = number of times to

func main() {
	fmt.Println(&quot;Input # of times to run&quot;)
	var number int
	fmt.Scan(&amp;number)
	fmt.Println(&quot;Input # of threads&quot;)
	var threads int
	fmt.Scan(&amp;threads)
	swg := sizedwaitgroup.New(threads)
	for i := 0; i &lt; number; i++ {
		swg.Add()
		go func(i int) {
			defer swg.Done()//Ensure to put your request after this line

            //Do request


		}(i)
	}
	swg.Wait()

}

This code uses the github.com/remeh/sizedwaitgroup library

Bear in mind, if one of the first requests is completed, it will start another without waiting for others to finish.

Here's it in practice:
https://codeshare.io/3A3dj4
https://pastebin.com/DP1sn1m4

Edit:
If you further and manage to send all but the last byte of the http request, you'll be wanted to use channels to communicate when to send the last byte, I'm not too good at them but this guide is great:
https://go.dev/blog/pipelines

huangapple
  • 本文由 发表于 2022年3月10日 23:23:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/71426624.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定