http1.1协议支持长连接,支持pipelining;
1)http头设置keep-alive选项,tcp socket连接服务器后,双方不再轻易断开,这样可以减少建立连接所需要的开销;
2)pipelining是服务器支持流水线机制,客户端不需要等待response,而不停的发送request,异步等待应答并解析;
在网络时延比较大的情况下,如果使用pipelining机制可以很好的避免网络时延造成的性能下降;但是我所使用的HttpLib客户端是使用同步获取的;即便是Curl在目前的版本也并不支持pipelining机制;
1)HttpLib使用每线程一个连接模型,比较土,开50线程,在目前笔记本上也最多到2W左右的RPC调用;
2)Curl也类似,可使用MultiWait机制实现异步(epoll模式,我没有调通);能达到5W左右;
而典型的HTTP压力测试工具wrk对简单的gohttp测试,可以达到12w tps;
所以我决定自己重新造一个轮子;
目前测试使用dell笔记本,4核i7-11,16G内存,本地开启go-http-server,把CPU打满,请求和应答都是使用小包:
测试结果:
1)异步等待模式:3线程,9连接,能到11w tps;
2)pipelining模式:2线程,4连接,能15w tps;
附加:go-http-server测试代码:
package main
import (
"fmt"
"net/http"
)
func IndexHandlers(w http.ResponseWriter, r *http.Request){
// fmt.Println("============================")
id := r.Header["Pipeline-Id"][0]
// if len(r.Header) > 0 {
// for k,v := range r.Header {
// if (k == "Pipeline-Id"){
// id = v[0]
// }
// fmt.Printf("%s=%sn", k, v[0])
// }
// }
// fmt.Println("");
fmt.Fprintln(w, "hello, world =========> " + id)
}
func main (){
http.HandleFunc("/", IndexHandlers)
http.HandleFunc("/hi", IndexHandlers)
err := http.ListenAndServe("10.128.6.15:80", nil)
if err != nil {
fmt.Printf("listen error:[%v]", err.Error())
}
}
等代码测试稳定,我传到github上;



