序
本文次要钻研一下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
- nacos-coredns-plugin