
毫秒级实现状态监测.
参考了aiobfd ,看了协议文档,
协议帧,包编码解码,用了gopacket的bfd.go ,
然后就是实现 状态 init, up, down的监控.
主要的问题是,时间上,需要快速 的检查发送失败,以判断对端为down掉
// 发送超时失败
func (s *Session) DetectFailure() {
for {
select {
case <-s.clientDone:
return
default:
if !(s.DemandMode || s.asyncDetectTime == 0) {
if (s.State == layers.BFDStateInit || s.State == layers.BFDStateUp) &&
((time.Now().UnixNano()/1e6 - s.LastRxPacketTime) > (int64(s.asyncDetectTime) / 1000)) {
// 状态变化,执行回调函数
go s.callFunc(s.Remote, int(s.State), int(layers.BFDStateDown))
s.State = layers.BFDStateDown
s.LocalDiag = layers.BFDDiagnosticTimeExpired
s.setDesiredMinTxInterval(DesiredMinTXInterval)
slogger.Errorf("Detected BFD remote %s going DOWN ", s.Remote)
slogger.Infof("Time since last packet: %d ms; Detect Time: %d ms ", (time.Now().UnixNano()/1e6 - s.LastRxPacketTime), int64(s.asyncDetectTime)/1000)
//fmt.Printf("Detected BFD remote %s going DOWN \n", s.Remote)
fmt.Printf("Time since last packet: %d ms; Detect Time: %d ms \n", (time.Now().UnixNano()/1e6 - s.LastRxPacketTime), int64(s.asyncDetectTime) / 1000)
}
}
time.Sleep(time.Millisecond / 10) // 这里等待时间, 如果太短,cpu占用就大,等待时长,最后的结果不是很准
}
}
}
时间上要对应得上来.
最后,实现了协议,当然是要用上来。
package gobfd
import (
"fmt"
"syscall"
"testing"
"time"
)
const (
family = syscall.AF_INET // 默认ipv4
local = "0.0.0.0"
passive = false // 是否是被动模式
rxInterval = 400 // 400 毫秒
txInterval = 400 // 400 毫秒
detectMult = 1 // 报文最大失效的个数
)
// 回调函数
func PrintIpBFDState1(ipAddr string, preState, curState int) error {
fmt.Println("ipAddr:", ipAddr, ",preState:", preState, ",curState:", curState)
return nil
}
// 回调函数
func PrintIpBFDState2(ipAddr string, preState, curState int) error {
fmt.Println("ipAddr:", ipAddr, ",preState:", preState, ",curState:", curState)
return nil
}
//
func TestNewControl(t *testing.T) {
fmt.Println("start ..")
// 启动
control := NewControl(local, family)
// 添加监测
remote1 := "192.168.1.244" // 远程ip
control.AddSession(remote1, passive, rxInterval, txInterval, detectMult, PrintIpBFDState1)
// 添加监测2
remote2 := "192.168.1.185" // 远程ip2
control.AddSession(remote2, passive, rxInterval, txInterval, detectMult, PrintIpBFDState2)
fmt.Println("sleep 30 second...")
time.Sleep(time.Second * 30)
// 删除监测
fmt.Println("del session ...")
control.DelSession(remote1)
control.DelSession(remote2)
time.Sleep(time.Second * 3)
}
原文:https://www.cnblogs.com/LoveDan/p/12056372.html