zoukankan      html  css  js  c++  java
  • golang实现BFD协议

    毫秒级实现状态监测.

    参考了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 
    ", s.Remote)
    					fmt.Printf("Time since last packet: %d ms; Detect Time: %d ms 
    ", (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)
    
    }
    

      

    github 链接:

    https://github.com/WLmutou/gobfd

  • 相关阅读:
    git 常用操作命令行
    Mysql 命令行...
    bootstrap
    10.11 android输入系统_补充知识_activity_window_decor_view关系
    10.10 android输入系统_APP获得并处理输入事件流程
    10.9 android输入系统_APP跟输入系统建立联系和Dispatcher线程_分发dispatch
    10.8 android输入系统_实战_使用GlobalKey一键启动程序
    10.7 android输入系统_Dispatcher线程情景分析_Reader线程传递事件和dispatch前处理
    10.6 android输入系统_Dispatcher线程_总体框架
    10.5 android输入系统_Reader线程_使用EventHub读取事件和核心类及配置文件_实验_分析
  • 原文地址:https://www.cnblogs.com/LoveDan/p/12056372.html
Copyright © 2011-2022 走看看