proxy: support regex match in http(s) health checking

This commit is contained in:
nadoo 2021-12-23 00:17:28 +08:00
parent 71c7cd2823
commit 55ab44fc90
4 changed files with 23 additions and 11 deletions

View File

@ -103,8 +103,8 @@ glider -h
glider 0.15.2 usage: glider 0.15.2 usage:
-check string -check string
check=tcp[://HOST:PORT]: tcp port connect check check=tcp[://HOST:PORT]: tcp port connect check
check=http://HOST[:PORT][/URI][#expect=STRING_IN_RESP_LINE] check=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
check=https://HOST[:PORT][/URI][#expect=STRING_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
check=disable: disable health check (default "http://www.msftconnecttest.com/connecttest.txt#expect=200") check=disable: disable health check (default "http://www.msftconnecttest.com/connecttest.txt#expect=200")
-checkdisabledonly -checkdisabledonly

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.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.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=STRING_IN_RESP_LINE]\ncheck=https://HOST[:PORT][/URI][#expect=STRING_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\ncheck=disable: disable health check")
flag.IntVar(&conf.Strategy.CheckInterval, "checkinterval", 30, "fowarder check interval(seconds)") 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.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") 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

@ -192,8 +192,9 @@ maxfailures=3
# Forwarder health check: # Forwarder health check:
# check=tcp[://HOST:PORT]: tcp port connect check # check=tcp[://HOST:PORT]: tcp port connect check
# check=http://HOST[:PORT][/URI][#expect=STRING_IN_RESP_LINE] # check=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
# check=https://HOST[:PORT][/URI][#expect=STRING_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
# check=disable: disable health check # check=disable: disable health check
check=http://www.msftconnecttest.com/connecttest.txt#expect=200 check=http://www.msftconnecttest.com/connecttest.txt#expect=200

View File

@ -8,6 +8,7 @@ import (
"net" "net"
"os" "os"
"os/exec" "os/exec"
"regexp"
"strings" "strings"
"time" "time"
@ -48,12 +49,22 @@ type httpChecker struct {
uri string uri string
expect string expect string
timeout time.Duration timeout time.Duration
tlsConfig *tls.Config tlsConfig *tls.Config
serverName string serverName string
regex *regexp.Regexp
} }
func newHttpChecker(addr, uri, expect string, timeout time.Duration, withTLS bool) *httpChecker { func newHttpChecker(addr, uri, expect string, timeout time.Duration, withTLS bool) *httpChecker {
c := &httpChecker{addr: addr, uri: uri, expect: expect, timeout: timeout} c := &httpChecker{
addr: addr,
uri: uri,
expect: expect,
timeout: timeout,
regex: regexp.MustCompile(expect),
}
if _, p, _ := net.SplitHostPort(addr); p == "" { if _, p, _ := net.SplitHostPort(addr); p == "" {
if withTLS { if withTLS {
c.addr = net.JoinHostPort(addr, "443") c.addr = net.JoinHostPort(addr, "443")
@ -103,7 +114,7 @@ func (c *httpChecker) Check(dialer proxy.Dialer) (time.Duration, error) {
return 0, err return 0, err
} }
if !strings.Contains(line, c.expect) { if !c.regex.MatchString(line) {
return 0, fmt.Errorf("expect: %s, got: %s", c.expect, line) return 0, fmt.Errorf("expect: %s, got: %s", c.expect, line)
} }