聊聊nacos-coredns-plugin的UDPServer

本文主要研究一下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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章