Code Monkey home page Code Monkey logo

Comments (9)

yanhom1314 avatar yanhom1314 commented on August 29, 2024

这也看不出来什么,能说的更详细点吗,或者定位下bug在哪儿,可以提pr修复

from dynamic-tp.

kuguobing avatar kuguobing commented on August 29, 2024

反复修改上面的properties配置:executors[0].corePoolSize或executors[0].maximumPoolSize、executors[0].queueCapacity等的值。
现象:第一次修改报,第二次不报,第三次修改报第二次的,第四次修改报第三次的。

运行dynamic-tp-example-apollo 中的例子代码,仅改了下apollo对应的配置而已:
apollo:
bootstrap:
enabled: true
namespaces: 2B.dynamic-tp

com.dtp.starter.apollo.refresh.ApolloRefresher::

public void onChange(ConfigChangeEvent changeEvent) {
    ConfigFile configFile = ConfigService.getConfigFile(namespace,
            ConfigFileFormat.fromString(configFileType.getValue()));
    String content = configFile.getContent();
    refresh(content, configFileType);
}

这个方法取的content 内容,貌似是上次缓存的内容:也即properties类型的线程池配置,每次报警的是上次的修改。

from dynamic-tp.

kuguobing avatar kuguobing commented on August 29, 2024

上面的代码我修改些打印下日志:

public void onChange(ConfigChangeEvent changeEvent) {
ConfigFile configFile = ConfigService.getConfigFile(namespace,
ConfigFileFormat.fromString(configFileType.getValue()));

	for(String key : changeEvent.changedKeys()) {
		System.out.println("Changed Key:" + key + " - value:[" + 
	            changeEvent.getChange(key).getOldValue() + " => {" + 
				changeEvent.getChange(key).getNewValue() + "}]");
	}
	
    String content = configFile.getContent();
    refresh(content, configFileType);
}

重新启动Example-Apollo例子,然后经过几次线程池属性配置的修改,打印日志如下:

【第一次修改】 : OK,准确变更并发送通知
Changed Key:spring.dynamic.tp.executors[0].corePoolSize - value:[20 => {25}]
2022-08-31 10:39:12.688 INFO 21112 --- [Apollo-Config-2] com.dtp.core.DtpRegistry : DynamicTp refresh, name: [dtpExecutor1], changed keys: [corePoolSize], corePoolSize: [20 => 25], maxPoolSize: [80 => 80], queueType: [VariableLinkedBlockingQueue => VariableLinkedBlockingQueue], queueCapacity: [1000 => 1000], keepAliveTime: [50s => 50s], rejectedType: [CallerRunsPolicy => CallerRunsPolicy], allowsCoreThreadTimeOut: [false => false]
2022-08-31 10:39:12.694 WARN 21112 --- [Apollo-Config-2] com.dtp.core.DtpRegistry : DynamicTp refresh, main properties of [defaultThreadExcutor] have not changed.
2022-08-31 10:39:13.173 INFO 21112 --- [ dtp-notify-1] com.dtp.core.notify.base.DingNotifier : DynamicTp notify, ding send success, response: *****

【第二次修改】:fail,更新后,但提示没有更新
Changed Key:spring.dynamic.tp.executors[0].maximumPoolSize - value:[80 => {85}]
2022-08-31 10:39:48.711 WARN 21112 --- [Apollo-Config-1] com.dtp.core.DtpRegistry : DynamicTp refresh, main properties of [dtpExecutor1] have not changed.
2022-08-31 10:39:48.712 WARN 21112 --- [Apollo-Config-1] com.dtp.core.DtpRegistry : DynamicTp refresh, main properties of [defaultThreadExcutor] have not changed.

【第三次修改】: fail,更新后,但提示的是第二次的修改更新
Changed Key:spring.dynamic.tp.executors[0].corePoolSize - value:[25 => {20}]
2022-08-31 10:40:04.717 INFO 21112 --- [Apollo-Config-2] com.dtp.core.DtpRegistry : DynamicTp refresh, name: [dtpExecutor1], changed keys: [maxPoolSize], corePoolSize: [25 => 25], maxPoolSize: [80 => 85], queueType: [VariableLinkedBlockingQueue => VariableLinkedBlockingQueue], queueCapacity: [1000 => 1000], keepAliveTime: [50s => 50s], rejectedType: [CallerRunsPolicy => CallerRunsPolicy], allowsCoreThreadTimeOut: [false => false]
2022-08-31 10:40:04.717 WARN 21112 --- [Apollo-Config-2] com.dtp.core.DtpRegistry : DynamicTp refresh, main properties of [defaultThreadExcutor] have not changed.
2022-08-31 10:40:04.937 INFO 21112 --- [ dtp-notify-1] com.dtp.core.notify.base.DingNotifier : DynamicTp notify, ding send success, response: ****

【第四次修改】: fail,更新后,但提示的是第三次的修改更新
Changed Key:spring.dynamic.tp.executors[0].maximumPoolSize - value:[85 => {80}]
2022-08-31 10:40:29.745 INFO 21112 --- [Apollo-Config-1] com.dtp.core.DtpRegistry : DynamicTp refresh, name: [dtpExecutor1], changed keys: [corePoolSize], corePoolSize: [25 => 20], maxPoolSize: [85 => 85], queueType: [VariableLinkedBlockingQueue => VariableLinkedBlockingQueue], queueCapacity: [1000 => 1000], keepAliveTime: [50s => 50s], rejectedType: [CallerRunsPolicy => CallerRunsPolicy], allowsCoreThreadTimeOut: [false => false]
2022-08-31 10:40:29.745 WARN 21112 --- [Apollo-Config-1] com.dtp.core.DtpRegistry : DynamicTp refresh, main properties of [defaultThreadExcutor] have not changed.
2022-08-31 10:40:29.950 INFO 21112 --- [ dtp-notify-1] com.dtp.core.notify.base.DingNotifier : DynamicTp notify, ding send success, response: ****

from dynamic-tp.

kuguobing avatar kuguobing commented on August 29, 2024

DEBUG跟了一下代码,跟了一下类的,应该跟Apollo类PropertiesConfigFile 的 getContent方法再线程异步并发的多个ConfigChangeListener,修改不同步导致。也即:
String content = configFile.getContent();
refresh(content, configFileType);
上面代码中content取值非同步安全,导致取到的非最新修改后的值,但是方法入参(ConfigChangeEvent changeEvent) 是没问题的。

com.ctrip.framework.apollo.internals.PropertiesConfigFile ::

@OverRide
protected void update(Properties newProperties) {
m_configProperties.set(newProperties);
m_contentCache.set(null);
}

@OverRide
public String getContent() {
if (m_contentCache.get() == null) {
m_contentCache.set(doGetContent());
}
return m_contentCache.get();
}

from dynamic-tp.

kuguobing avatar kuguobing commented on August 29, 2024

修复了下代码:

@Override
public void onChange(ConfigChangeEvent changeEvent) {
	ConfigFile configFile = ConfigService.getConfigFile(namespace,
             ConfigFileFormat.fromString(configFileType.getValue()));
    String content = configFile.getContent();
    
    if(!ConfigFileTypeEnum.PROPERTIES.equals(configFileType)) {
    	super.refresh(content, configFileType);
    	return;
    }

    if (StringUtils.isBlank(content) || Objects.isNull(configFileType)) {
        log.warn("DynamicTp refresh, empty content or null fileType.");
        return;
    }
    
    try {
    	ConfigHandler configHandler = ConfigHandler.getInstance();
    	Map<Object, Object> properties = configHandler.parseConfig(content, configFileType);
		
    	// fix concurrent onchange event not synchronized
    	for(String key : changeEvent.changedKeys()) {
    		properties.put(key, changeEvent.getChange(key).getNewValue());
    	}
    	
    	super.doRefresh(properties);
	} catch (IOException e) {
		 log.error("DynamicTp refresh error, content: {}, fileType: {}", content, configFile, e);
	}
}

from dynamic-tp.

yanhom1314 avatar yanhom1314 commented on August 29, 2024

我试了下,雀氏有这个问题,老哥方便提个pr么,修复下

from dynamic-tp.

kuguobing avatar kuguobing commented on August 29, 2024

dynamic-tp修改properties文件更新BUG

from dynamic-tp.

yanhom1314 avatar yanhom1314 commented on August 29, 2024

他这个顺序是先调用ConfigChangeListener#onChange的实现,然后在调用AbstractConfigFile#onRepositoryChange来实现newProperties的赋值,所以会有这个问题,如果顺序调转下就没问题了,不清楚apollo就是这样设计的还是bug

from dynamic-tp.

yanhom1314 avatar yanhom1314 commented on August 29, 2024

见此issue #67

from dynamic-tp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.