聊聊nacos-coredns-plugin的UDPServer

codecraft · · 322 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

本文主要研究一下nacos-coredns-plugin的UDPServer

UDPServer

nacos-coredns-plugin/nacos/udp_server.go

type UDPServer struct {
    port int
    host string
    vipClient *NacosClient
}
UDPServer定义了port、host、vipClient属性

StartServer

nacos-coredns-plugin/nacos/udp_server.go

func (us *UDPServer) StartServer(){
    var conn *net.UDPConn

    for i := 0; i < 3; i++ {
        r := rand.New(rand.NewSource(time.Now().UnixNano()))
        port := r.Intn(1000) + 54951
        us.port = port
        conn1, ok := us.tryListen()

        if ok {
            conn = conn1
            NacosClientLogger.Info("udp server start, port: " + strconv.Itoa(port))
            break
        }

        if !ok && i == 2 {
            NacosClientLogger.Critical("failed to start udp server after trying 3 times.")
            os.Exit(1)
        }
    }

    UDP_Port = us.port

    defer conn.Close()
    for {
        us.handleClient(conn)
    }
}
StartServer方法循环3次执行tryListen(),若都没有成功则exit;若成功则for循环执行handleClient

tryListen

nacos-coredns-plugin/nacos/udp_server.go

func (us *UDPServer) tryListen() (*net.UDPConn, bool) {
    addr, err := net.ResolveUDPAddr("udp", us.host+":"+ strconv.Itoa(us.port))
    if err != nil {
        NacosClientLogger.Error("Can't resolve address: ", err)
        return nil , false
    }

    conn, err := net.ListenUDP("udp", addr)
    if err != nil {
        NacosClientLogger.Error("Error listening:", err)
        return nil, false
    }

    return conn, true
}
tryListen方法先执行net.ResolveUDPAddr,在执行net.ListenUDP

handleClient

nacos-coredns-plugin/nacos/udp_server.go

type PushData struct {
    PushType string `json:"type"`
    Data string `json:"data"`
    LastRefTime int64 `json:"lastRefTime"`
    
}

func (us *UDPServer) handleClient(conn *net.UDPConn) {
    data := make([]byte, 4024)
    n, remoteAddr, err := conn.ReadFromUDP(data)
    if err != nil {
        NacosClientLogger.Error("failed to read UDP msg because of ", err)
        return
    }

    s := TryDecompressData(data[:n])

    NacosClientLogger.Info("receive push: " + s + " from: ", remoteAddr)

    var pushData PushData
    err1 := json.Unmarshal([]byte(s), &pushData)
    if err1 != nil {
        NacosClientLogger.Warn("failed to process push data, ", err1)
        return
    }

    domain, err1 := ProcessDomainString(pushData.Data)
    NacosClientLogger.Info("receive domain: " , domain)

    if err1 != nil {
        NacosClientLogger.Warn("failed to process push data: " + s, err1)
    }

    key := GetCacheKey(domain.Name, LocalIP())

    us.vipClient.domainMap.Set(key, domain)

    ack := make(map[string]string)
    ack["type"] = "push-ack"
    ack["lastRefTime"] = strconv.FormatInt(pushData.LastRefTime, 10)
    ack["data"] = ""

    bs,_ := json.Marshal(ack)

    conn.WriteToUDP(bs, remoteAddr)
}
handleClient方法执行conn.ReadFromUDP,然后通过TryDecompressData解压数据,然后Unmarshal为PushData类型,执行ProcessDomainString获取domain,执行us.vipClient.domainMap.Set(key, domain),最后构造返回数据ack回去

小结

nacos-coredns-plugin的UDPServer定义了port、host、vipClient属性;它提供了StartServer方法;StartServer方法循环3次执行tryListen(),若都没有成功则exit;若成功则for循环执行handleClient。

doc


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:codecraft

查看原文:聊聊nacos-coredns-plugin的UDPServer

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

322 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传