| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- 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
- }
|