Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当前server实例不在哈希环上时,依旧遍历实例列表 #1203

Closed
qnnn opened this issue Aug 13, 2023 · 5 comments · Fixed by qnnn/polaris#2 · May be fixed by #1241
Closed

当前server实例不在哈希环上时,依旧遍历实例列表 #1203

qnnn opened this issue Aug 13, 2023 · 5 comments · Fixed by qnnn/polaris#2 · May be fixed by #1241

Comments

@qnnn
Copy link
Contributor

qnnn commented Aug 13, 2023

部分服务端节点被隔离或不健康时,即当前server实例不在哈希环上,依旧会去遍历实例列表。

if d.continuum != nil {
	d.svr.cacheProvider.RangeHealthCheckInstances(func(itemChecker ItemWithChecker, instance *model.Instance) {
		instanceId := instance.ID()
		host := d.continuum.Hash(itemChecker.GetHashValue())
		if host == d.svr.localHost {
			nextInstances[instanceId] = itemChecker.(*InstanceWithChecker)
		}
	})
}

在心跳分派处理上,可能只希望部分server实例参与心跳健康处理,未参与心跳分派的server实例不需要遍历实例列表。

@qnnn
Copy link
Contributor Author

qnnn commented Aug 14, 2023

大佬,顺便问下心跳健康检测时间轮添加任务前,delayMilli为什么需要加一个随机数getRandDelayMilli()。是有什么作用吗。

func (c *CheckScheduler) addUnHealthyCallback(instance *itemValue) {
	delaySec := instance.expireDurationSec
	if c.maxCheckIntervalSec > 0 && int64(delaySec) > c.maxCheckIntervalSec {
		delaySec = uint32(c.maxCheckIntervalSec)
	}
	host := instance.host
	port := instance.port
	instanceId := instance.id
	delayMilli := delaySec*1000 + getRandDelayMilli()
	log.Debugf("[Health Check][Check]add unhealthy callback, %s is %s:%d, id is %s, delay is %d(ms)",
		instance.ItemType.String(), host, port, instanceId, delayMilli)
	if instance.ItemType == itemTypeClient {
		c.timeWheel.AddTask(delayMilli, instanceId, c.checkCallbackClient)
	} else {
		c.timeWheel.AddTask(delayMilli, instanceId, c.checkCallbackInstance)
	}
}

@xiaolaji422
Copy link
Contributor

getRandDelayMilli 这个方法可以让时间轮上的单位时间执行的任务更分散。

@qnnn
Copy link
Contributor Author

qnnn commented Aug 25, 2023

getRandDelayMilli 这个方法可以让时间轮上的单位时间执行的任务更分散。

实测的时候没发现有能达到散列的作用呀。毫秒级的随机数。时间轮又是每秒一slot,实例的ttl也是int类型。代码里加完之后还是整数。

func (tw *TimeWheel) getSlots(d time.Duration) (pos int, circle int) {
	delayTime := int(d.Seconds())
	interval := int(tw.interval.Seconds())
	circle = int(delayTime / interval / tw.slotNum)
	pos = int(tw.currentPos+delayTime/interval) % tw.slotNum
	return
}

@xiaolaji422
Copy link
Contributor

还有一个可能是,当delaySec = 0时,避免AddTask的任务被跳过执行

@xiaolaji422
Copy link
Contributor

具体要看他们官方给出的结论-_-

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment