diff --git a/conf/systemd/frpc.service b/conf/systemd/frpc.service index dd88ce0..37a6a9b 100644 --- a/conf/systemd/frpc.service +++ b/conf/systemd/frpc.service @@ -9,6 +9,7 @@ Restart=on-failure RestartSec=5s ExecStart=/usr/bin/frpc -c /etc/frp/frpc.ini ExecReload=/usr/bin/frpc reload -c /etc/frp/frpc.ini +LimitNOFILE=1048576 [Install] WantedBy=multi-user.target diff --git a/conf/systemd/frpc@.service b/conf/systemd/frpc@.service index 46251ed..5914ff6 100644 --- a/conf/systemd/frpc@.service +++ b/conf/systemd/frpc@.service @@ -3,12 +3,13 @@ Description=Frp Client Service After=network.target [Service] -Type=idle +Type=simple User=nobody Restart=on-failure RestartSec=5s ExecStart=/usr/bin/frpc -c /etc/frp/%i.ini ExecReload=/usr/bin/frpc reload -c /etc/frp/%i.ini +LimitNOFILE=1048576 [Install] WantedBy=multi-user.target diff --git a/conf/systemd/frps.service b/conf/systemd/frps.service index 1daa267..c00f2dc 100644 --- a/conf/systemd/frps.service +++ b/conf/systemd/frps.service @@ -8,6 +8,7 @@ User=nobody Restart=on-failure RestartSec=5s ExecStart=/usr/bin/frps -c /etc/frp/frps.ini +LimitNOFILE=1048576 [Install] WantedBy=multi-user.target diff --git a/conf/systemd/frps@.service b/conf/systemd/frps@.service index 8b625ca..2942e0b 100644 --- a/conf/systemd/frps@.service +++ b/conf/systemd/frps@.service @@ -8,6 +8,7 @@ User=nobody Restart=on-failure RestartSec=5s ExecStart=/usr/bin/frps -c /etc/frp/%i.ini +LimitNOFILE=1048576 [Install] WantedBy=multi-user.target diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go index f26d73d..43c2c74 100644 --- a/server/proxy/proxy.go +++ b/server/proxy/proxy.go @@ -21,6 +21,7 @@ import ( "net" "strconv" "sync" + "time" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/msg" @@ -151,12 +152,28 @@ func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, net.Conn, xl := xlog.FromContextSafe(pxy.ctx) for _, listener := range pxy.listeners { go func(l net.Listener) { + var tempDelay time.Duration // how long to sleep on accept failure + for { // block // if listener is closed, err returned c, err := l.Accept() if err != nil { - xl.Info("listener is closed") + if err, ok := err.(interface{ Temporary() bool }); ok && err.Temporary() { + if tempDelay == 0 { + tempDelay = 5 * time.Millisecond + } else { + tempDelay *= 2 + } + if max := 1 * time.Second; tempDelay > max { + tempDelay = max + } + xl.Info("met temporary error: %s, sleep for %s ...", err, tempDelay) + time.Sleep(tempDelay) + continue + } + + xl.Warn("listener is closed: %s", err) return } xl.Info("get a user connection [%s]", c.RemoteAddr().String())