2. nsqlookupd 源码阅读(2) RegistrationDB存储
nsqlookupd 使用 RegistrationDB 来存储生产者的信息
需要注意的函数
(1)
该函数给你 category key subkey 让你查找符合条件的 Registrations。
func (r *RegistrationDB) FindRegistrations(category string, key string, subkey string) Registrations {
r.RLock()
defer r.RUnlock()
if !r.needFilter(key, subkey) {
k := Registration{category, key, subkey}
if _, ok := r.registrationMap[k]; ok {
return Registrations{k}
}
return Registrations{}
}
results := Registrations{}
for k := range r.registrationMap {
if !k.IsMatch(category, key, subkey) {
continue
}
results = append(results, k)
}
return results
}
此时需要注意 key和subkey有可能是,这是一个特殊的标识,可以默认与任何字符匹配在比较的时候要对其特殊处理。
首先如果给定的key和subkey都不是*的话,就按照正常的逻辑构造Registration,然后查询RegistrationDB 即可。
其次如若key和subkey有一个或者全是*的话,需要调用IsMatch 函数进行校验是否匹配。
func (k Registration) IsMatch(category string, key string, subkey string) bool {
// category 不同直接返回 不匹配
if category != k.Category {
return false
}
// 如果 给定的key不是* ,并且与Registration 的key不相同直接返回不匹配
if key != "*" && k.Key != key {
return false
}
// 同理
if subkey != "*" && k.SubKey != subkey {
return false
}
return true
}
(2)
同(1) 需要注意的地方
func (r *RegistrationDB) FindProducers(category string, key string, subkey string) Producers {
r.RLock()
defer r.RUnlock()
if !r.needFilter(key, subkey) {
k := Registration{category, key, subkey}
return r.registrationMap[k]
}
results := Producers{}
for k, producers := range r.registrationMap {
if !k.IsMatch(category, key, subkey) {
continue
}
for _, producer := range producers {
found := false
for _, p := range results {
if producer.peerInfo.id == p.peerInfo.id {
found = true
}
}
if found == false {
results = append(results, producer)
}
}
}
return results
}
(3) 这是根据给定的生产者的存活时间和墓碑的存活时间来获取符合条件的生产者
func (pp Producers) FilterByActive(inactivityTimeout time.Duration, tombstoneLifetime time.Duration) Producers {
now := time.Now()
results := Producers{}
for _, p := range pp {
// 获得该生产者最后一ping的时间点
cur := time.Unix(0, atomic.LoadInt64(&p.peerInfo.lastUpdate))
// 如果这个生产者上一次ping的时间大于了inactivityTimeout 或者他的创建时间长度小于tombstoneLifetime 该生产者不符合条件
if now.Sub(cur) > inactivityTimeout || p.IsTombstoned(tombstoneLifetime) {
continue
}
results = append(results, p)
}
return results
}