试试调整 GOGC
dongzerun opened this issue · comments
dongzerun commented
试试调整 GOGC 再压测?一般转发类的 go 服务都要调高,默认肯定不行
试试 1000 吧,再看看压测结果,并发情况下 QPS 不如 nginx 是不可能的
Jiajun Huang commented
谢谢,调整了之后性能确实提升了很多,不过和Nginx相比还是有差距。如下:
$ wrk --latency -H "Host: www.example.com" -c 2048 -d 30 -t 2 http://127.0.0.1:23456
Running 30s test @ http://127.0.0.1:23456
2 threads and 2048 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 106.34ms 37.45ms 288.37ms 71.04%
Req/Sec 4.71k 561.64 5.86k 73.66%
Latency Distribution
50% 117.73ms
75% 129.48ms
90% 142.78ms
99% 185.03ms
279620 requests in 30.02s, 214.93MB read
Socket errors: connect 1029, read 0, write 0, timeout 0
Requests/sec: 9315.66
Transfer/sec: 7.16MB
QPS不如Nginx应该是肯定的,Go和Nginx的底层都是用epoll/kqueue等I/O多路复用机制,主要区别在于:
- Nginx 使用epoll回调方式
- Nginx用C写,C和Go的性能还是有差距的(C大概是Go的十倍左右)
- Go有runtime和GC,抢占式调度,goroutine等,GC需要STW,goroutine把栈保存在操作系统的堆里,执行那个goroutine的时候才加载到P里,另外Go的函数调用参数不是直接往寄存器里塞,而是往栈里压。C我记得好象是前六个往寄存器里压,后面的才会丢栈里
不过压测上表明,Go的99%响应时间比Nginx好的多,这一点我估计应该是抢占式调度的功劳。
我会把你的建议更新在README里,非常感谢你的建议。欢迎继续讨论 👍
dongzerun commented
开 pprof 看下 cpu 和 内存的情况,再微调试试吧,看看 cpu 最多的耗在了哪里
Jiajun Huang commented
之前有看过,最大的瓶颈在于http标准库里的proxy。昨天用fasthttp改写了一下,不开GOGC的情况下性能直接和Nginx打平了。除此之外,之前有如下性能瓶颈:
- 获取时间
time.Now
消耗比较大 - 统计状态用的是哈希表,查询时需要访问四次,这个目前已经重写了
- 统计状态为了保证并发安全,加了锁,这个目前也通过前两天的重写解决了
所以目前把代理用 fasthttp
重写之后,性能超过Nginx还真的很有希望 😄
Jiajun Huang commented
经过两个重要组件改写之后,现在申请内存的地方比较少(目前还有一部分有待改造)。刚压测了一下,性能已经是Nginx的1.7倍了。GOGC
几乎没什么影响了。
我先关闭这个issue了,继续优化性能和可用性了 😄