Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc

起因:公司有个项目需要批量检查多个IP的网络质量,其中一个指标是丢包率,当然用ping是最合适的方法,但是使用ping命令性能太差,Golang又没有批量ping的包

开发:

目前github只有sparrc写的ping库,不过他的库不支持批量探测多个IP
https://github.com/sparrc/go-ping
并且sparrc/go-ping在使用时,如果对多个IP同时探测会出现串包的问题,请谨慎使用。
再他的启发下,我做了扩展,支持批量请求

安装

go get github.com/vearne/go-ping

使用

    ipSlice := []string{}
    ipSlice = append(ipSlice, "123.126.157.222")
    ipSlice = append(ipSlice, "wwww.baidu.com")
    ipSlice = append(ipSlice, "github.com")


    // 对每个地址,共发出4个探测包,每隔1秒发一个, 总超时6秒
    bp, err := ping.NewBatchPinger(ipSlice, 4, time.Second*1, time.Second*6)

    if err != nil {
        fmt.Println(err)
    }

    // 收到ICMP answer时的回调函数
    bp.OnRecv = func(pkt *icmp.Echo) {
        //
        fmt.Printf("recv icmp_id=%d, icmp_seq=%d\n",
            pkt.ID, pkt.Seq)
    }

    // 所有Ping结束时的回调函数
    bp.OnFinish = func(stSlice []*ping.Statistics) {
        for _, st := range stSlice{
            fmt.Printf("\n--- %s ping statistics ---\n", st.Addr)
            fmt.Printf("%d packets transmitted, %d packets received, %v%% packet loss\n",
                st.PacketsSent, st.PacketsRecv, st.PacketLoss)
            fmt.Printf("round-trip min/avg/max/stddev = %v/%v/%v/%v\n",
                st.MinRtt, st.AvgRtt, st.MaxRtt, st.StdDevRtt)
        }

    }

    bp.Run()

完整的例子
https://github.com/vearne/go-ping/blob/master/cmd/ping/ping2.go

注意1 目前多协程并发使用,也是会有问题的。如果你要探测的地址非常多,比如有5000个,我建议可以分成若干批次,比如一批探测1000个地址,执行完上一批,再执行下一批。由于每个批次中,ping是并发的,因此性能也不会差。

注意2 库使用时,需要root权限

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注