perf: check internet with DNS lookup (#1034)

DNS lookups are much cheaper than HTTP requests since we only need to check if the Internet is available.

See: https://stackoverflow.com/a/50058255
This commit is contained in:
WaterLemons2k
2024-03-07 21:31:33 +08:00
committed by GitHub
parent ea853832b9
commit ae0f47f537
8 changed files with 158 additions and 90 deletions

View File

@ -4,7 +4,7 @@ import (
"time"
"github.com/jeessy2/ddns-go/v6/config"
"github.com/jeessy2/ddns-go/v6/dns/internal"
"github.com/jeessy2/ddns-go/v6/dns/internet"
"github.com/jeessy2/ddns-go/v6/util"
)
@ -34,7 +34,7 @@ var (
// RunTimer 定时运行
func RunTimer(delay time.Duration) {
internal.WaitForNetworkConnected(addresses)
internet.Wait(addresses)
for {
RunOnce()

View File

@ -1,48 +0,0 @@
package internal
import (
"strings"
"time"
"github.com/jeessy2/ddns-go/v6/util"
)
// waitForNetworkConnected 等待网络连接后继续
//
// addresses用于测试网络是否连接的域名
func WaitForNetworkConnected(addresses []string) {
// 延时 5 秒
timeout := time.Second * 5
loopbackServer := "[::1]:53"
find := false
for {
for _, addr := range addresses {
// https://github.com/jeessy2/ddns-go/issues/736
client := util.CreateHTTPClient()
resp, err := client.Get(addr)
if err != nil {
// 如果 err 包含回环地址([::1]:53则表示没有 DNS 服务器,设置 DNS 服务器
if strings.Contains(err.Error(), loopbackServer) && !find {
server := "1.1.1.1:53"
util.Log("本机DNS异常! 将默认使用 %s, 可参考文档通过 -dns 自定义 DNS 服务器", loopbackServer, server)
util.NewDialerResolver(server)
find = true
continue
}
util.Log("等待网络连接: %s", err)
util.Log("%s 后重试...", timeout)
// 等待 5 秒后重试
time.Sleep(timeout)
continue
}
// 网络已连接
resp.Body.Close()
return
}
}
}

56
dns/internet/wait.go Normal file
View File

@ -0,0 +1,56 @@
// Package internet implements utilities for checking the Internet connection.
package internet
import (
"strings"
"time"
"github.com/jeessy2/ddns-go/v6/util"
)
const (
// fallbackDNS used when a fallback occurs.
fallbackDNS = "1.1.1.1"
// delay is the delay time for each DNS lookup.
delay = time.Second * 5
)
// Wait blocks until the Internet is connected.
//
// See also:
//
// - https://stackoverflow.com/a/50058255
// - https://github.com/ddev/ddev/blob/v1.22.7/pkg/globalconfig/global_config.go#L776
func Wait(addresses []string) {
// fallbase in case loopback DNS is unavailable and only once.
fallback := false
for {
for _, addr := range addresses {
err := util.LookupHost(addr)
// Internet is connected.
if err == nil {
return
}
if !fallback && isLoopback(err) {
util.Log("本机DNS异常! 将默认使用 %s, 可参考文档通过 -dns 自定义 DNS 服务器", fallbackDNS)
util.SetDNS(fallbackDNS)
fallback = true
continue
}
util.Log("等待网络连接: %s", err)
util.Log("%s 后重试...", delay)
time.Sleep(delay)
}
}
}
// isLoopback checks if the error is a loopback error.
func isLoopback(e error) bool {
return strings.Contains(e.Error(), "[::1]:53")
}