package netmgrd import ( "fmt" "os/exec" "sync" "time" "github.com/beevik/ntp" ) var servers = []string{ "210.72.145.44", "ntp.aliyun.com", "ntp.ntsc.ac.cn", } type ntpResult struct { t time.Time stratum uint8 err error } func SyncNTPTime() error { t, err := getAccurateTime(servers, 5*time.Second) if err != nil { return err } if err := setSystemTime(t); err != nil { return err } return nil } func getAccurateTime(servers []string, timeout time.Duration) (time.Time, error) { ch := make(chan ntpResult, len(servers)) var wg sync.WaitGroup wg.Add(len(servers)) for _, s := range servers { go func(s string) { defer wg.Done() resp, err := ntp.QueryWithOptions(s, ntp.QueryOptions{Timeout: timeout}) if err != nil || resp.Stratum == 0 || resp.Stratum > 5 || resp.Time.IsZero() { ch <- ntpResult{err: err} // "resp.Stratum"为0(无效服务器)或大于5(精度较低) return } ch <- ntpResult{t: resp.Time, stratum: resp.Stratum} }(s) } go func() { wg.Wait() close(ch) }() var results []ntpResult for r := range ch { if r.err == nil { results = append(results, r) } } if len(results) == 0 { return time.Time{}, fmt.Errorf("所有NTP服务器请求失败或无有效时间") } // 找最低 Stratum minStratum := uint8(255) for _, r := range results { if r.stratum < minStratum { minStratum = r.stratum } } // 最低 Stratum 的时间 var bestTimes []time.Time for _, r := range results { if r.stratum == minStratum { bestTimes = append(bestTimes, r.t) } } return bestTimes[0], nil } func setSystemTime(t time.Time) error { cmd := exec.Command("date", "-s", t.Local().Format("2006-01-02 15:04:05")) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("%v, output: %s", err, string(output)) } return nil }