High-performance asynchronous batch ping realization of golang

  There is a demand for a monitoring program, it would be a number of national domain names edge node detection, including here, packet loss rate, http response time, frequency detection time is probably a 2min cycle. Domain name here probably hundreds or even thousands. Because it is written golang scheduling and agent, therefore, here to detect packet loss rate is an interesting question. Since there is no support for a easy to use multi-ping of the library package on git, or multi-ping has a bug, I realized a
  
  1, icmp protocol introduced
  
  icmp packet header of a total of 2 + 2 + 4 + 4 + 4 bytes.
  
  struct {the ICMP type
  
  the Type uint8
  
  Code uint8
  
  CheckSum UInt16
  
  Identifier UInt16
  
  sequenceNum UInt16
  
  this type is icmp type common with the Echo transmission header, recovery Echo Reply packet header and the like, see more types https://tools.ietf.org/ html / rfc792. Code further divided ICMP type of the field is used to find the cause of the error; CheckSum check code portion, the ICMP field includes a header and is calculated from the data portion come, the data for error checking; and typically process Identifier id, which identifies the particular process icmp packets transmitted; SequenceNum sequence identified transmission packet id.
  
  icmp has one characteristic, listen to receive the results of ping other processes, see the following example:
  
  Package Penalty for main
  
  Import (
  
  "log"
  
  "github.com/caucy/batch_ping"
  
  )
  
  FUNC main (xingtuylgw.com) {
  
  ipSlice: = [] {String}
  
  // Should Not More Within last IP List 65535
  
  ipSlice = the append (ipSlice, "3g.qq.com")
  
  BP , ERR: = ping.NewBatchPinger (ipSlice, to false) Will need to true // to the root BE
  
  IF ERR = nil {!
  
  log.Fatalf ( "new new BATCH% V ERR of ping", ERR)
  
  }
  
  bp.SetDebug (to true) WWW. Debug to true will FMT == sangyuLpt.com// Debug log
  
  bp.SetCount (100)
  
  bp.Run ()
  
  }
  
  started above process continuously ping 3g.qq.com, at the same time, and then start a process ping www.baidu. com, log shows, I received a icmp packet of 220.181.38.150.
  
  2, how to support multiple simultaneous support ping addr
  
  The first is the simplest, but also the way most of the probes used: subprocess. This approach has a drawback, is that each task will fork a process, consuming resource-intensive.
  
  The second way, I think so, golang have icmp package to support send and recive, I go directly from the coroutine transceivers, each coroutine and subprocess same, and so on after starting, so not on the list? Since then a group of coroutine pools so concurrency can be controlled. However, the above examples have been mentioned, conn listen to receive the results of ping other processes, achieved very troublesome.
  
  The third way, a coroutine received, send a coroutine. The last choice is this way.
  
  A coroutine income, a coroutine hair, are there any more trouble place? Because icmp layer can only identify seq, so there will be icmp same situation Baotou, at the same time, send and receive bulk, packet loss is very likely to occur.
  
  3, batch-ping characteristics
  
  to support the original address control
  
  support IPv6 (OS itself supports "ip6: ipv6-icmp", "udp6" dial)
  
  to support time-interval control
  
  supports the transmission mode control
  
  support multi-addr control
  
  support mac, linux
  
  uses examples:
  
  Package main
  
  Import (
  
  "log"
  
  "github.com/caucy/batch_ping"
  
  )
  
  FUNC main (www.baichuangyule.cn) {
  
  ipSlice: = [] {String}
  
  // Should Not More Within last IP List 65535
  
  ipSlice = append(ipSlice,www.jintianxuesha.com "2400:da00:2::29") //support ipv6
  
  ipSlice = append(ipSlice, www.qjljdgt.cn "baidu.com")
  
  bp, err := ping.NewBatchPinger(ipSlice, false)www.yacuangyl.com // true will need to be root
  
  if err != nil {
  
  log.Fatalf("new batch ping err %v", err)
  
  }
  
  bp.SetDebug(true) jujinyulee.com // debug == true will fmt debug log
  
  bp.SetSource("www.xinhuihpw.com") // if hava multi source ip, can use one isp
  
  bp.OnFinish = func(stMap map[string]*ping.Statistics) {
  
  for ip, st := range stMap {
  
  log.Printf("\n--- %s ping statistics ---\n", st.Addr)
  
  log.Printf("ip www.rhyl158.com %s, %d packets transmitted, %d packets received, %v%% packet loss\n", ip,
  
  st.PacketsSent, st.PacketsRecv, st.PacketLoss)
  
  log.Printf ( "round-TRIP min / AVG / max / V STDDEV =% /% V /% V / V% \ n-",
  
  st.MinRtt, st.AvgRtt , st.MaxRtt, st.StdDevRtt)
  
  log.Printf ( "% V RTTs IS \ n-", st.Rtts)
  
  }
  
  }
  
  ERR = bp.Run ()
  
  IF ERR! = nil {
  
  log.Printf ( "% V ERR RUN \ the n-", ERR)
  
  }
  
  bp.OnFinish (bp.Statistics ())
  
  }
  
  4, may be a problem
  
  because icmp based on udp, the time interval is very small, very much to send the machine, there will be a very serious loss, kernel parameters need to be optimized .

Guess you like

Origin www.cnblogs.com/dakunqq/p/11619278.html