random sleep duration before reconnecting (#2816)

This commit is contained in:
fatedier 2022-02-24 11:59:36 +08:00 committed by GitHub
parent 10100c28d9
commit 19739ed31a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 14 deletions

View File

@ -17,7 +17,6 @@ package client
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"errors"
"fmt" "fmt"
"io" "io"
"net" "net"
@ -34,6 +33,7 @@ import (
"github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/pkg/transport"
"github.com/fatedier/frp/pkg/util/log" "github.com/fatedier/frp/pkg/util/log"
frpNet "github.com/fatedier/frp/pkg/util/net" frpNet "github.com/fatedier/frp/pkg/util/net"
"github.com/fatedier/frp/pkg/util/util"
"github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/version"
"github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/pkg/util/xlog"
libdial "github.com/fatedier/golib/net/dial" libdial "github.com/fatedier/golib/net/dial"
@ -109,7 +109,7 @@ func (svr *Service) Run() error {
if svr.cfg.LoginFailExit { if svr.cfg.LoginFailExit {
return err return err
} }
time.Sleep(10 * time.Second) util.RandomSleep(10*time.Second, 0.9, 1.1)
} else { } else {
// login success // login success
ctl := NewControl(svr.ctx, svr.runID, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter) ctl := NewControl(svr.ctx, svr.runID, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter)
@ -158,8 +158,11 @@ func (svr *Service) keepControllerWorking() {
// the first three retry with no delay // the first three retry with no delay
if reconnectCounts > 3 { if reconnectCounts > 3 {
time.Sleep(reconnectDelay) util.RandomSleep(reconnectDelay, 0.9, 1.1)
xl.Info("wait %v to reconnect", reconnectDelay)
reconnectDelay *= 2 reconnectDelay *= 2
} else {
util.RandomSleep(time.Second, 0, 0.5)
} }
reconnectCounts++ reconnectCounts++
@ -175,18 +178,12 @@ func (svr *Service) keepControllerWorking() {
xl.Info("try to reconnect to server...") xl.Info("try to reconnect to server...")
conn, session, err := svr.login() conn, session, err := svr.login()
if err != nil { if err != nil {
xl.Warn("reconnect to server error: %v", err) xl.Warn("reconnect to server error: %v, wait %v for another retry", err, delayTime)
time.Sleep(delayTime) util.RandomSleep(delayTime, 0.9, 1.1)
opErr := &net.OpError{} delayTime = delayTime * 2
// quick retry for dial error if delayTime > maxDelayTime {
if errors.As(err, &opErr) && opErr.Op == "dial" { delayTime = maxDelayTime
delayTime = 2 * time.Second
} else {
delayTime = delayTime * 2
if delayTime > maxDelayTime {
delayTime = maxDelayTime
}
} }
continue continue
} }

View File

@ -19,9 +19,11 @@ import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
mathrand "math/rand"
"net" "net"
"strconv" "strconv"
"strings" "strings"
"time"
) )
// RandID return a rand string used in frp. // RandID return a rand string used in frp.
@ -109,3 +111,17 @@ func GenerateResponseErrorString(summary string, err error, detailed bool) strin
} }
return summary return summary
} }
func RandomSleep(duration time.Duration, minRatio, maxRatio float64) time.Duration {
min := int64(minRatio * 1000.0)
max := int64(maxRatio * 1000.0)
var n int64
if max <= min {
n = min
} else {
n = mathrand.Int63n(max-min) + min
}
d := duration * time.Duration(n) / time.Duration(1000)
time.Sleep(d)
return d
}