proxy: add new env: FORWARDER_URL to script health check (#310)

This commit is contained in:
nadoo 2022-01-27 12:42:49 +08:00
parent fac4b86f60
commit 9b2f00f4c8
7 changed files with 21 additions and 15 deletions

View File

@ -106,7 +106,7 @@ glider 0.16.0 usage:
check=tcp[://HOST:PORT]: tcp port connect check
check=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
check=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR
check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR,FORWARDER_URL
check=disable: disable health check (default "http://www.msftconnecttest.com/connecttest.txt#expect=200")
-checkdisabledonly
check disabled fowarders only

View File

@ -51,7 +51,7 @@ func parseConfig() *Config {
flag.StringSliceVar(&conf.Forwards, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]")
flag.StringVar(&conf.Strategy.Strategy, "strategy", "rr", "forward strategy, default: rr")
flag.StringVar(&conf.Strategy.Check, "check", "http://www.msftconnecttest.com/connecttest.txt#expect=200", "check=tcp[://HOST:PORT]: tcp port connect check\ncheck=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR\ncheck=disable: disable health check")
flag.StringVar(&conf.Strategy.Check, "check", "http://www.msftconnecttest.com/connecttest.txt#expect=200", "check=tcp[://HOST:PORT]: tcp port connect check\ncheck=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR,FORWARDER_URL\ncheck=disable: disable health check")
flag.IntVar(&conf.Strategy.CheckInterval, "checkinterval", 30, "fowarder check interval(seconds)")
flag.IntVar(&conf.Strategy.CheckTimeout, "checktimeout", 10, "fowarder check timeout(seconds)")
flag.IntVar(&conf.Strategy.CheckTolerance, "checktolerance", 0, "fowarder check tolerance(ms), switch only when new_latency < old_latency - tolerance, only used in lha mode")

View File

@ -195,7 +195,7 @@ maxfailures=3
# check=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
# check=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
# e.g. check=https://www.netflix.com/title/81215567#expect=301|404
# check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR
# check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR,FORWARDER_URL
# check=disable: disable health check
check=http://www.msftconnecttest.com/connecttest.txt#expect=200

2
go.mod
View File

@ -11,7 +11,7 @@ require (
github.com/nadoo/conflag v0.2.3
github.com/nadoo/ipset v0.4.0
github.com/xtaci/kcp-go/v5 v5.6.1
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce
golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
)

4
go.sum
View File

@ -104,8 +104,8 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8 h1:kACShD3qhmr/3rLmg1yXyt+N4HcwutKyPRB93s54TIU=
golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=

View File

@ -13,12 +13,11 @@ import (
"time"
"github.com/nadoo/glider/pkg/pool"
"github.com/nadoo/glider/proxy"
)
// Checker is a forwarder health checker.
type Checker interface {
Check(dialer proxy.Dialer) (elap time.Duration, err error)
Check(fwdr *Forwarder) (elap time.Duration, err error)
}
type tcpChecker struct {
@ -34,9 +33,9 @@ func newTcpChecker(addr string, timeout time.Duration) *tcpChecker {
}
// Check implements the Checker interface.
func (c *tcpChecker) Check(dialer proxy.Dialer) (time.Duration, error) {
func (c *tcpChecker) Check(fwdr *Forwarder) (time.Duration, error) {
startTime := time.Now()
rc, err := dialer.Dial("tcp", c.addr)
rc, err := fwdr.Dial("tcp", c.addr)
if err != nil {
return 0, err
}
@ -80,9 +79,9 @@ func newHttpChecker(addr, uri, expect string, timeout time.Duration, withTLS boo
}
// Check implements the Checker interface.
func (c *httpChecker) Check(dialer proxy.Dialer) (time.Duration, error) {
func (c *httpChecker) Check(fwdr *Forwarder) (time.Duration, error) {
startTime := time.Now()
rc, err := dialer.Dial("tcp", c.addr)
rc, err := fwdr.Dial("tcp", c.addr)
if err != nil {
return 0, err
}
@ -131,10 +130,11 @@ type fileChecker struct{ path string }
func newFileChecker(path string) *fileChecker { return &fileChecker{path} }
// Check implements the Checker interface.
func (c *fileChecker) Check(dialer proxy.Dialer) (time.Duration, error) {
func (c *fileChecker) Check(fwdr *Forwarder) (time.Duration, error) {
cmd := exec.Command(c.path)
cmd.Stdout = os.Stdout
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "FORWARDER_ADDR="+dialer.Addr())
cmd.Env = append(cmd.Env, "FORWARDER_ADDR="+fwdr.Addr())
cmd.Env = append(cmd.Env, "FORWARDER_URL="+fwdr.URL())
return 0, cmd.Run()
}

View File

@ -18,6 +18,7 @@ type StatusHandler func(*Forwarder)
// Forwarder associates with a `-forward` command, usually a dialer or a chain of dialers.
type Forwarder struct {
proxy.Dialer
url string
addr string
priority uint32
maxFailures uint32 // maxfailures to set to Disabled
@ -30,7 +31,7 @@ type Forwarder struct {
// ForwarderFromURL parses `forward=` command value and returns a new forwarder.
func ForwarderFromURL(s, intface string, dialTimeout, relayTimeout time.Duration) (f *Forwarder, err error) {
f = &Forwarder{}
f = &Forwarder{url: s}
ss := strings.Split(s, "#")
if len(ss) > 1 {
@ -107,6 +108,11 @@ func (f *Forwarder) Addr() string {
return f.addr
}
// URL returns the forwarder's full url.
func (f *Forwarder) URL() string {
return f.url
}
// Dial dials to addr and returns conn.
func (f *Forwarder) Dial(network, addr string) (c net.Conn, err error) {
c, err = f.Dialer.Dial(network, addr)