buaazp / fasthttprouter

A high performance fasthttp request router that scales well
http://godoc.org/github.com/buaazp/fasthttprouter
BSD 3-Clause "New" or "Revised" License
876 stars 91 forks source link

random fail response from server #32

Open smthpickboy opened 7 years ago

smthpickboy commented 7 years ago

Refer to: https://github.com/valyala/fasthttp/issues/261

Go 1.8.1 fasthttp version: b154429 fasthttprouter version: ade4e2031af3aed7fffd241084aad80a58faf421

Get random fail response when testing: curl: (52) Empty reply from server curl: (56) Failure when receiving data from the peer

The problem disappeared when I don't use router. So I guess maybe it's incompatible between fasthttprouter and new fasthttp?

buaazp commented 7 years ago

Can you paste the test codes here? I need to reproduce this issue.

smthpickboy commented 7 years ago

Sorry. After further testing, I found that it's caused by ReadTimeout/WriteTimeout of fasthttp.Server

func main() {
    m := func(ctx *fasthttp.RequestCtx) {
        switch string(ctx.Path()) {
        case "/foo":
            foo(ctx)
        default:
            ctx.Error("not found", fasthttp.StatusNotFound)
        }
    }

    s := fasthttp.Server{
        Handler: m,
        ReadTimeout:  time.Second + 500*time.Millisecond,
        //WriteTimeout: time.Second,
        MaxRequestBodySize: 2 * 1024,
    }

    fmt.Println("testing with ReadTimeout 1.5s")
    err := s.ListenAndServe("127.0.0.1:8000")
    if err != nil {
        fmt.Println(err)
    }
}

func foo(ctx *fasthttp.RequestCtx) {
    ctx.WriteString("Success")
}

If I set ReadTimeout to 1.5 second on my test machine, It's no problem. But if set to less than 1.5 sec, such as 1 sec, there would be some random fail response.

Is there any additional config that I should do to use ReadTimeout/WriteTimeout of fasthttp.Server?

buaazp commented 7 years ago

How do you send the requests? Can you show your test req sender code or cmd? If your client and server are in same side, I guess your test machine is in high pressure.

smthpickboy commented 7 years ago

I just do curl -sS "http://127.0.0.1:8000/foo" in a loop.

Test code:

SCNT=0;
FCNT=0;
START=$(gdate +%s.%N);
for (( i=0; i<1000; i++ )); do
    RRR=$(curl -sS "http://127.0.0.1:8000/foo");
    if [ $? -ne 0 ]; then
        FCNT=$((FCNT+1));
    else
        SCNT=$((SCNT+1)); 
    fi;
done;
echo "$SCNT succeeded";
echo "$FCNT failed";
END=$(gdate +%s.%N);
echo $END-$START | bc -l

My test machine is not under high pressure. When I set ReadTimeout to 2 sec, I got:

1000 succeeded
0 failed
6.585148000

So I guess it's maybe related to how fasthttp handles ReadTimeout.