版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://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权限