jiajunhuang / guard

NOT MAINTAINED! A generic high performance circuit breaker & proxy server written in Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

试试调整 GOGC

dongzerun opened this issue · comments

试试调整 GOGC 再压测?一般转发类的 go 服务都要调高,默认肯定不行

试试 1000 吧,再看看压测结果,并发情况下 QPS 不如 nginx 是不可能的

谢谢,调整了之后性能确实提升了很多,不过和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里,非常感谢你的建议。欢迎继续讨论 👍

开 pprof 看下 cpu 和 内存的情况,再微调试试吧,看看 cpu 最多的耗在了哪里

之前有看过,最大的瓶颈在于http标准库里的proxy。昨天用fasthttp改写了一下,不开GOGC的情况下性能直接和Nginx打平了。除此之外,之前有如下性能瓶颈:

  • 获取时间 time.Now 消耗比较大
  • 统计状态用的是哈希表,查询时需要访问四次,这个目前已经重写了
  • 统计状态为了保证并发安全,加了锁,这个目前也通过前两天的重写解决了

所以目前把代理用 fasthttp 重写之后,性能超过Nginx还真的很有希望 😄

经过两个重要组件改写之后,现在申请内存的地方比较少(目前还有一部分有待改造)。刚压测了一下,性能已经是Nginx的1.7倍了。GOGC 几乎没什么影响了。

我先关闭这个issue了,继续优化性能和可用性了 😄