美文网首页
OpenKruise用到的技术 网络监听句柄动态转移 切换网络监

OpenKruise用到的技术 网络监听句柄动态转移 切换网络监

作者: ShootHzj | 来源:发表于2021-08-29 07:49 被阅读0次

    今天看到了https://mp.weixin.qq.com/s/tTipcU8MKxTpFurWNEUIww 中热迁移网络句柄的功能,忍不住自己在机器上实验了一下,确实可以实现网络句柄的迁移。实验代码如下

    old_server

    package main
    
    import (
        "net"
        "syscall"
    )
    
    func main() {
        tcpAddr := net.TCPAddr{Port: 8001}
        tcpLn, err := net.ListenTCP("tcp4", &tcpAddr)
        if err != nil {
            panic(err)
        }
        f, _ := tcpLn.File()
        fdNum := f.Fd()
        data := syscall.UnixRights(int(fdNum))
        // 与新版本sidecar通过Unix Domain Socket建立链接
        raddr, _ := net.ResolveUnixAddr("unix", "/dev/shm/migrate.sock")
        uds, _ := net.DialUnix("unix", nil, raddr)
        // 通过UDS,发送ListenFD到新版本sidecar容器
        _, _, _ = uds.WriteMsgUnix(nil, data, nil)
        // 停止接收新的request,并且开始排水阶段
        tcpLn.Close()
    }
    

    new_server

    package main
    
    import (
        "fmt"
        "net"
        "net/http"
        "os"
        "syscall"
        "time"
    )
    
    func main() {
        // 新版本sidecar 接收ListenFD,并且开始对外服务
        // 监听UDS
        addr, _ := net.ResolveUnixAddr("unix", "/dev/shm/migrate.sock")
        unixLn, _ := net.ListenUnix("unix", addr)
        conn, _ := unixLn.AcceptUnix()
        buf := make([]byte, 32)
        oob := make([]byte, 32)
        time.Sleep(5 * time.Second)
        // 接收 ListenFD
        _, oobn, _, _, _ := conn.ReadMsgUnix(buf, oob)
        scms, _ := syscall.ParseSocketControlMessage(oob[:oobn])
        if len(scms) > 0 {
            // 解析FD,并转化为 *net.TCPListener
            fds, _ := syscall.ParseUnixRights(&scms[0])
            f := os.NewFile(uintptr(fds[0]), "")
            ln, _ := net.FileListener(f)
            tcpLn, _ := ln.(*net.TCPListener)
            http.Serve(tcpLn, &MyHttp{})
        }
    }
    
    type MyHttp struct {
    }
    
    func (*MyHttp) ServeHTTP(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(w, "hello world")
    }
    

    实验结果

    • 先启动new_server
    • 再启动old_server
    • 然后访问localhost:8001,返回hello world,这是new_server返回的结果

    代码地址

    https://github.com/Shoothzj/go_demo/tree/main/demo_base/fd_migrate

    相关文章

      网友评论

          本文标题:OpenKruise用到的技术 网络监听句柄动态转移 切换网络监

          本文链接:https://www.haomeiwen.com/subject/byciiltx.html