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

3.0 fix reExporter bug when config-center {applicationName}.configurator data change #1144

Merged
merged 2 commits into from
Apr 11, 2021
Merged

3.0 fix reExporter bug when config-center {applicationName}.configurator data change #1144

merged 2 commits into from
Apr 11, 2021

Conversation

ztelur
Copy link
Contributor

@ztelur ztelur commented Apr 11, 2021

What this PR does:

修改 protocol.go 文件中 getCacheKey 函数实现;
在 registryProtocol 的 reExport 函数中增加 ServiceMap.Register 操作。

Fixes

Special notes for your reviewer:

  • 旧的 getCacheKey 函数根据url中所有参数生成key,精度太高,url稍微有变化就生成不同的key,导致配置下发时根据providerUrl生成的key和Export存储时用的key不同,无法进行配置更新。
  • Export 时使用 OverrideUrl 修改后的 providerUrl 生成key,应该使用 invoker 中最原始的 providerUrl 生成 key
// 初始化时
func (proto *registryProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
        .....
	providerUrl := getProviderUrl(invoker) // 1 clone了一份url,所以修改不会影响原url
        .....
	proto.providerConfigurationListener.OverrideUrl(providerUrl)
        .....
	serviceConfigurationListener.OverrideUrl(providerUrl)
        // 2 上述两个OverrideUrl修改了providerUrl的值
        .....
	key := getCacheKey(providerUrl)
	cachedExporter, loaded := proto.bounds.Load(key)
       if loaded {
		logger.Infof("The exporter has been cached, and will return cached exporter!")
	} else {
                 // 3 将key和cachedExproter的映射关系存入bounds .....
		proto.bounds.Store(key, cachedExporter)
	}
        ....
}

// 配置变更时,该函数会进行处理
func (nl *overrideSubscribeListener) doOverrideIfNecessary() {
	providerUrl := getProviderUrl(nl.originInvoker)
	key := getCacheKey(providerUrl)
        // 4 再次getProviderUrl获取的是旧的url,导致getCachedKey获得key和Export时的不同
	if exporter, ok := nl.protocol.bounds.Load(key); ok {
           ....
        }
}
  • 配置实时生效时会调用reExport方法,reExport会调用 protocol.Exporter 的 unexport 和 export 方法,该方法进行了ServiceMap.UnRegister操作,但是 export 时却没有进行 ServiceMap.Register 操作,导致再次配置实时生效时报错;
  • 为了减少修改影响范围,所以在 reExport 函数中添加重新进行 ServiceMap.Register 的操作
func (proto *registryProtocol) reExport(invoker protocol.Invoker, newUrl *common.URL) {
	url := getProviderUrl(invoker)
	key := getCacheKey(url)
	if oldExporter, loaded := proto.bounds.Load(key); loaded {
		wrappedNewInvoker := newWrappedInvoker(invoker, newUrl)
                 // unexport
		oldExporter.(protocol.Exporter).Unexport()
		proto.bounds.Delete(key)
                // export
		proto.Export(wrappedNewInvoker)
		// TODO:  unregister & unsubscribe
	}
}
func (de *DubboExporter) Unexport() {
	interfaceName := de.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "")
	de.BaseExporter.Unexport()

	err := common.ServiceMap.UnRegister(interfaceName, DUBBO, de.GetInvoker().GetUrl().ServiceKey())
	if err != nil {
		logger.Errorf("[DubboExporter.Unexport] error: %v", err)
	}
}

@ztelur ztelur changed the title fix reExporter bug when config-center {applicationName}.configurator data change 3.0 fix reExporter bug when config-center {applicationName}.configurator data change Apr 11, 2021
Copy link
Contributor

@zhaoyunxing92 zhaoyunxing92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved these changes

@AlexStocks AlexStocks merged commit 2ec80b8 into apache:3.0 Apr 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants