higress icon indicating copy to clipboard operation
higress copied to clipboard

Issue: About Higress syncing Nacos service list delay problems

Open hansedong opened this issue 1 year ago • 3 comments

[✓ ] I have searched the issues of this repository and believe that this is not a duplicate.

Ⅰ. Issue Description

问题是这样的:

目前,Higress 支持 Nacos,而 Nacos 原生就不支持直接订阅所有 service name 下的 Instance。能想到的办法就是:要 Watch 所有的 Nacos 实例,就只能先 List Services,然后循环 Services 分别对其做 Watch 操作。实际上,Higress 也是这样做的。

我看了下 Higress 的处理逻辑,它会先获取 service list,然后依次订阅 service name 对应的 instance 变化。

这就带来新的问题:

  1. Service list 可能并不是及时变更的,Higress 的处理逻辑是:没个 30s 重新 Relist Service Names 并根据差异,来决定是创建新的 Service 的订阅,或取消已经不存在的 Service 的订阅。
  2. 然而,而 List Services 是有时间差的,靠一个 ticker 重复循环触发,不是实时的。
  3. 如果刚 Relist Services 结束的时刻(或者延后几秒),正好有一个 Service 被创建出来,按我理解,Higress 会在之后的 30s 内,不会 Watch 这个 Service 的任何变化。

下面是具体的 Higress 代码逻辑:

func (w *watcher) Run() {
	ticker := time.NewTicker(time.Duration(w.NacosRefreshInterval))
	defer ticker.Stop()
	w.Status = provider.ProbeWatcherStatus(w.Domain, strconv.FormatUint(uint64(w.Port), 10))
	err := w.fetchAllServices()
	if err != nil {
		log.Errorf("first fetch services failed, err:%v", err)
	} else {
		w.Ready(true)
	}
	for {
		select {
                // 这里,就是 Relist Service 并重新依次 Watch Service Instance 的逻辑了。核心还是这个 ticker。
		case <-ticker.C:
			err := w.fetchAllServices()
			if err != nil {
				log.Errorf("fetch services failed, err:%v", err)
			} else {
				w.Ready(true)
			}
		case <-w.stop:
			return
		}
	}
}

简单来说:用户在 Higress 中配置了 Ingress、MCP,并且 Nacos 有实例,而此时,如果 Higress Watch 还没感知到 Nacos Service 变化,导致极端情况下,在一个 30s 周期内,流量全部无效(用户流量打到 Higress 会找不到相关的 Pod)。

Ⅱ. Describe what happened

之所以有这个问题,是因为我最近在做发现中心的时候,希望将 K8s 多集群的实例,同步到 Nacos,然后借由 Nacos 来对接 Higress。

然而,我将 K8s 实例同步到 Nacos 的时候,在想,既然 nacos 官方 SDK 在设计的时候就无法 Watch Nacos Service 变化,Higress 又是如何处理的呢。看到 Higress 目前的设计感觉是有问题的。但是,我也没有想到特别好的办法。

我有想过不同步到 Nacos,同步到 Consul,但是考虑到公司内的 Java 生态,Nacos 还是首选。所以,还是想看看,有没有更优雅的办法来处理这个问题。

hansedong avatar Jan 17 '24 12:01 hansedong

这样处理并没有问题,因为新注册到nacos上的服务,不会立即就去创建路由,即使做了一些自动化机制,一注册就立即创建路由,影响面也是在路由刚创建的时候要多等一会儿生效。

路由转发给哪个服务是个静态配置,只要Nacos上这个服务没有完全摘除,服务上下线都不会造成流量影响。

如果服务完全摘除后再重新上线,目前这个轮询list的机制确实会在这种极端case下影响重新上线后的速度,但在完全摘除时已经造成了流量影响,一般业务上也不会这样去操作。

johnlanni avatar Jan 18 '24 06:01 johnlanni

nacos3.0会支持模糊订阅机制(订阅一个分组下的服务新增),如果你们业务确实要考虑这种极端用例,higress未来可以考虑基于这个机制扩展一下

johnlanni avatar Jan 18 '24 06:01 johnlanni

如果服务完全摘除后再重新上线,目前这个轮询list的机制确实会在这种极端case下影响重新上线后的速度,但在完全摘除时已经造成了流量影响,一般业务上也不会这样去操作。

这个情况的确是有些极端,因为我们做的是微服务平台,通常来说,业务研发主要关心业务代码开发,不关心底层基础架构,业务研发是完全信赖基础平台的。这个场景中,极端场景下,业务会遇到上线(尤其是新上线)服务后,回归测试出现问题。实际上,关于网关规则生效速度慢的问题,还可能会导致前端微服务场景中 CDN 静态资源回源 404 的问题。

nacos3.0会支持模糊订阅机制(订阅一个分组下的服务新增),如果你们业务确实要考虑这种极端用例,higress未来可以考虑基于这个机制扩展一下

感谢提醒,我关注一下

非常感谢回复,期待后续在 Higress 上有更多交流~

hansedong avatar Jan 18 '24 07:01 hansedong