首页 > 其他分享 >golang vrrp 包

golang vrrp 包

时间:2023-05-14 09:45:32浏览次数:54  
标签:netlink addr fmt vr golang vrrp eth

vrrp 是一个比较有用的功能,可以实现业务访问的的高可用,keepalived 就使用了此协议(当然还集成了lvs )
此包是基于了社区提供的VRRP-go 包调整的,解决了一些问题:比如不是go mod 的,部分依赖三方包不兼容

参考使用

  • go mod
 
go mod init github.com/rongfengliang/demoappvrrp
  • main.go
    集成了netlink 进行vip 的bind
 
package main
 
import (
    "flag"
    "fmt"
    "net"
    "os"
    "os/signal"
    "syscall"
    "time"
 
    "github.com/rongfengliang/vrrp/vrrp"
    "github.com/vishvananda/netlink"
)
 
var (
    VRID     int
    Priority int
)
 
func init() {
    flag.IntVar(&VRID, "vrid", 233, "virtual router ID")
    flag.IntVar(&Priority, "pri", 100, "router priority")
}
 
func main() {
    flag.Parse()
    sigs := make(chan os.Signal, 1)
    done := make(chan bool, 1)
 
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    var vr = vrrp.NewVirtualRouter(byte(VRID), "enp0s1", false, vrrp.IPv4)
    vr.SetPriorityAndMasterAdvInterval(byte(Priority), time.Millisecond*800)
    vr.AddIPvXAddr(net.IPv4(10, 10, 17, 29))
    vr.Enroll(vrrp.Backup2Master, func() {
        // vip bind
        eth, _ := netlink.LinkByName("enp0s1")
        addr, _ := netlink.ParseAddr("10.10.17.29/32")
        netlink.AddrAdd(eth, addr)
        fmt.Println("backup to master")
    })
    vr.Enroll(vrrp.Init2Master, func() {
        // vip bind
        eth, _ := netlink.LinkByName("enp0s1")
        addr, _ := netlink.ParseAddr("10.10.17.29/32")
        netlink.AddrAdd(eth, addr)
        fmt.Println("init to master")
    })
    vr.Enroll(vrrp.Master2Init, func() {
        // remove vip bind
        eth, _ := netlink.LinkByName("enp0s1")
        addr, _ := netlink.ParseAddr("10.10.17.29/32")
        netlink.AddrDel(eth, addr)
        fmt.Println("master to init")
    })
    vr.Enroll(vrrp.Master2Backup, func() {
        // remove vip bind
        eth, _ := netlink.LinkByName("enp0s1")
        addr, _ := netlink.ParseAddr("10.10.17.29/32")
        netlink.AddrDel(eth, addr)
        fmt.Println("master to backup")
    })
    vr.Enroll(vrrp.Init2Backup, func() {
        // remove vip bind
        eth, _ := netlink.LinkByName("enp0s1")
        addr, _ := netlink.ParseAddr("10.10.17.29/32")
        netlink.AddrDel(eth, addr)
        fmt.Println("init  to backup")
    })
    vr.Enroll(vrrp.Backup2Init, func() {
        // remove vip bind
        eth, _ := netlink.LinkByName("enp0s1")
        addr, _ := netlink.ParseAddr("10.10.17.29/32")
        netlink.AddrDel(eth, addr)
        fmt.Println("backup to init")
    })
    go func() {
        // starting vrrp server
        vr.StartWithEventLoop()
    }()
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        done <- true
        vr.Stop()
        // remove vip bind
        eth, _ := netlink.LinkByName("enp0s1")
        addr, _ := netlink.ParseAddr("10.10.17.29/32")
        netlink.AddrDel(eth, addr)
    }()
    fmt.Println("awaiting signal")
    <-done
    fmt.Println("exiting")
}
  • 效果

启动的时候

 


进行切换(可以看到backup 切换到了master 了)

 

说明

以上是一个简单的包装集成,ip bind 部分使用了netlink,对于开发使用可以直接使用go 包了,内置实现具体可以参考github,同时VRRP-go 也是值得看看的
当然单纯直接依赖vrrp 的一些机制并不是特别可靠,比如keepalived 同时也利用了bfd 协议进行状态检测,确保vip 的快速切换以及状态处理

参考资料

https://github.com/rongfengliang/vrrp
https://github.com/napw/VRRP-go
https://datatracker.ietf.org/doc/html/rfc5798
https://github.com/vishvananda/netlink
https://www.keepalived.org/
https://github.com/acassen/keepalived

标签:netlink,addr,fmt,vr,golang,vrrp,eth
From: https://www.cnblogs.com/rongfengliang/p/17398781.html

相关文章

  • golang多版本管理工具g
    一、golang多版本管理工具g 一)g简介g是一个Linux、macOS、Windows下的命令行工具,可以提供一个便捷的多版本go环境的管理和切换 二)g特性支持列出可供安装的go版本号支持列出已安装的go版本号支持在本地安装多个go版本支持卸载已安装的go版本支持在已安装的go版本......
  • golang 实现一个自动注入跟踪代码工具
    如下面代码所示:packagemainimport("bytes""fmt""runtime""strconv")/**实现一个自动注入跟踪代码,并输出有层次感的函数调用链跟踪命令行工具.*/funcTrace()func(){//通过runtime.Caller函数获得当前Goroutine的函数调用栈上的信息,......
  • golang netlink 方便的网络管理包
    netlink可以方便的处理golang对于系统网络相关测试,比如我们需要设置网桥,配置ip,设置路由。。。。参考使用packagemain import("github.com/vishvananda/netlink") funcmain(){eth,_:=netlink.LinkByName("enp0s2")addr,_:=netli......
  • [golang] logrus日志包如何自定义级别
    在Logrus中,可以使用logrus.Level类型定义自定义的日志级别,以便更精细地控制日志输出。以下是使用Logrus自定义级别的基本步骤:首先,在代码中使用 logrus.New() 方法创建一个新的logrus.Logger对象,并使用 AddHook() 方法注册所需的Hook对象(可选)。例如,以下代码创建了一个......
  • GoLang 使用 goroutine 停止的几种办法
    [toc]前言我们有很多情况下需要主动关闭goroutine,如需要实现一个系统自动熔断的功能就需要主动关闭goroutine为什么要中断GoRoutine?场景:俩个相互依赖的的操作,“依赖”是指如果其中一个失败,那么另一个就没有意义,而不是第二个操作依赖第一个操作的结果(那种情况下,两个操作不能并行)。......
  • golang web页面动态加载实现
            Go的web页面动态加载实现。  1.在MySQL中添加表项users,构造多条数据。CREATETABLEIFNOTEXISTSusers(idINTUNSIGNEDAUTO_INCREMENT,usernameVARCHAR(255)NOTNULL,passwordVA......
  • 使用golang编写支持C++调用的动态库,接口支持结构体和回调函数
    网上有很多例子介绍如何使用cgo实现C/C++与golang进行接口交互。我有个项目是使用Qt写的客户端程序,但Qt在需要使用redis、支持表单的web服务、mq或网络化日志库等需求时,往往需要加载一大堆第三方库,且编译复杂,跨平台(如Windows/linuxarm/linuxx86)编译时较为复杂。鉴于有使用go......
  • Golang调用Dll案例
    Golang调用Dll案例前言在家办公已经两个多星期了,目前最大的困难就是网络很差。独自一个人用golang开发调用dll的驱动程序。本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心。本想依葫芦画瓢把这个驱动做了。可网上找到的案例都是一些简单的调用dll。对于各种传参、获取......
  • golang调用dll,windows
    使用syscall.LoadLibrary(dllPath)函数加载dll,syscall.Syscall(...)函数调用具体的函数接口funcGoCallDll1(a,bint)uintptr{ dllFile:=syscall.NewLazyDLL(dllFileName) fmt.Println("dll:",dllFile.Name) add:=dllFile.NewProc("add") fmt.Println("......
  • Golang for循环遍历小坑
    一、for循环循环:让程序多次执行相同的代码块for循环是Go语言中唯一一个循环结构for循环经典语法先执行表达式1执行表达式2判断是否成立,如果成立执行循环体循环体执行完成后,执行表达式3再次执行表达式2,判断是否成立.for循环用的最多的地方就是遍历数组或切片等for表达式1......