-
Notifications
You must be signed in to change notification settings - Fork 8.7k
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
optimize: increase the cache of configuration values #2611
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #2611 +/- ##
=============================================
- Coverage 50.82% 50.81% -0.01%
- Complexity 2815 2822 +7
=============================================
Files 558 559 +1
Lines 17931 17971 +40
Branches 2126 2132 +6
=============================================
+ Hits 9113 9132 +19
- Misses 7952 7968 +16
- Partials 866 871 +5
|
config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I said my own understanding:
- The previous dynamic downgrade is to monitor the subscription through the configuration center and read the updated cache value as needed.
- you use caffeine as a cache locally, and then it expires regularly. There is no need to invalidate the cache regularly. The local cache uses monitoring subscriptions to update the cache in real time, and getConfig reads only the local cache.
The getConfig method will always only interact with the local cache. As for when the cache is updated, it will be handed over to the listen and subscribe logic instead of timing failure. If the local cache fails, it will still request the configuration center.
fcfe3ad
to
33d8f16
Compare
ok |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
about code style
|
||
private static final Set<String> LISTENER_KEYS = new HashSet<>(); | ||
|
||
private ConcurrentMap<String, HashSet<ConfigurationChangeListener>> configListenersMap = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just hashMap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
if (CollectionUtils.isEmpty(listenerHashSet)) { | ||
listenerHashSet = new HashSet<>(); | ||
} | ||
for (int i = 0; i < listeners.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For code elegance may use foreach would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
} | ||
if (null != listeners && listeners.length > 0) { | ||
HashSet<ConfigurationChangeListener> listenerHashSet = null; | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (null != listeners && listeners.length > 0) {
HashSet<ConfigurationChangeListener> listenerHashSet =
getInstance().configListenersMap.computeIfAbsent(dataId, k -> new HashSet<>());
if (CollectionUtils.isEmpty(listenerHashSet)) {
listenerHashSet = new HashSet<>();
}
for (ConfigurationChangeListener listener : listeners) {
ConfigurationChangeListener listener = listeners[i];
if (!listenerHashSet.contains(listener)) {
listenerHashSet.add(listener);
ConfigurationFactory.getInstance().addConfigListener(dataId, listener);
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@slievrly PTAL |
if (null != extConfiguration) { | ||
configurationCache = ConfigurationCache.getInstance().proxy(configuration); | ||
} else { | ||
configurationCache = ConfigurationCache.getInstance().proxy(configuration); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check the code logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
degradeCheck = Boolean.parseBoolean(event.getNewValue()); | ||
if (!degradeCheck) { | ||
if (ConfigurationKeys.CLIENT_DEGRADE_CHECK.equals(event.getDataId())) { | ||
if (!Boolean.parseBoolean(event.getNewValue())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why delete disable process logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the code has been restored
@@ -107,6 +136,10 @@ public Object invoke(final MethodInvocation methodInvocation) throws Throwable { | |||
final GlobalTransactional globalTransactionalAnnotation = | |||
getAnnotation(method, targetClass, GlobalTransactional.class); | |||
final GlobalLock globalLockAnnotation = getAnnotation(method, targetClass, GlobalLock.class); | |||
final boolean disable = ConfigurationFactory.getInstance() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why local variables?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the disable configuration item does not exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the disable configuration item does not exist?
when not present, the default value will be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
期待1.3发布 |
Ⅰ. Describe what this PR did
optimize: increase the cache of configuration values
大并发下性能相对1.2提升可达90%+
SEATA 1.3(#2611) 性能测试报告
方式说明
nacos做配置&注册中心.
对40条数据随机forupdate读取后,update.设置最高并发200,请求数400,每种方式4次测试
Dubbo下测试: 暂无.
SpringCloud下测试: 678ms 431ms 500ms 427ms (全部正常响应)
File配置中心下测试: 358ms 553ms 421ms 387ms (全部正常响应)
本地事务下测试: 191ms 214ms 109ms 154ms (全部正常响应)
SEATA 1.2下测试: 10289ms 13931ms 11118ms 12792ms (70%+的请求接口响应全部超时)
测试环境
硬件环境: CPU: i5-8300
内存: 8G
硬盘:1TB SSD
软件环境:
系统:win10 64
JAVA: 1.8.0_181
Mysql: 5.7.23
Nacos: 1.2.1
测试模块
测试用例
测试工具
Ⅱ. Does this pull request fix one issue?
Ⅲ. Why don't you add test cases (unit test/integration test)?
Ⅳ. Describe how to verify it
Ⅴ. Special notes for reviews