開発環境
フレーム | バージョン |
---|---|
Springcloud | 2020.0.2 |
ナコス | 2.2.1。リリース |
目標
loadbalancer
デフォルトの負荷分散キャッシュは30秒であるため、サービスが発生した場合上下线
、サービスコンシューマーは最初に取得を知ることができず、呼び出しは远程服务
失敗します。したがって、サービスがオフラインになると、最初にサービスコンシューマーに通知し、その後一連の操作を実行できることを認識したいと思います。
本旨
私の考えはNacos
、監視サービス変換インターフェースを使用して負荷分散のキャッシュリストを変更し、サービスキャッシュリストのリアルタイム変更を実現することです。
ソースコードを読む
パッケージの下の構成クラスを調べると、 org.springframework.cloud.loadbalancer.config
2つのクラスが見つかりました
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Caffeine.class, CaffeineCacheManager.class })
protected static class CaffeineLoadBalancerCacheManagerConfiguration {
@Bean(autowireCandidate = false)
@ConditionalOnMissingBean
LoadBalancerCacheManager caffeineLoadBalancerCacheManager(LoadBalancerCacheProperties cacheProperties) {
return new CaffeineBasedLoadBalancerCacheManager(cacheProperties);
}
}
@Configuration(proxyBeanMethods = false)
@Conditional(OnCaffeineCacheMissingCondition.class)
@ConditionalOnClass(ConcurrentMapWithTimedEviction.class)
protected static class DefaultLoadBalancerCacheManagerConfiguration {
@Bean(autowireCandidate = false)
@ConditionalOnMissingBean
LoadBalancerCacheManager defaultLoadBalancerCacheManager(LoadBalancerCacheProperties cacheProperties) {
return new DefaultLoadBalancerCacheManager(cacheProperties);
}
}
デフォルトでは、Spring LoadBalancerはDefaultLoadBalancerCacheManager
実装クラスをキャッシュ管理として使用することがわかります。そのため、そのソースコードを見てみましょう。
public class DefaultLoadBalancerCacheManager implements LoadBalancerCacheManager {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>(16);
public DefaultLoadBalancerCacheManager(LoadBalancerCacheProperties loadBalancerCacheProperties,
String... cacheNames) {
cacheMap.putAll(createCaches(cacheNames, loadBalancerCacheProperties).stream()
.collect(Collectors.toMap(DefaultLoadBalancerCache::getName, cache -> cache)));
}
public DefaultLoadBalancerCacheManager(LoadBalancerCacheProperties loadBalancerCacheProperties) {
this(loadBalancerCacheProperties, SERVICE_INSTANCE_CACHE_NAME);
}
private Set<DefaultLoadBalancerCache> createCaches(String[] cacheNames,
LoadBalancerCacheProperties loadBalancerCacheProperties) {
return Arrays.stream(cacheNames).distinct()
.map(name -> new DefaultLoadBalancerCache(name,
new ConcurrentHashMapWithTimedEviction<>(loadBalancerCacheProperties.getCapacity(),
new DelayedTaskEvictionScheduler<>(aScheduledDaemonThreadExecutor())),
loadBalancerCacheProperties.getTtl().toMillis(), false))
.collect(Collectors.toSet());
}
private ScheduledExecutorService aScheduledDaemonThreadExecutor() {
return Executors.newSingleThreadScheduledExecutor(runnable -> {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
});
}
@Override
@Nullable
public Cache getCache(String name) {
return cacheMap.get(name);
}
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(cacheMap.keySet());
}
}
ストレージキャッシュリストはこのオブジェクトを介して実装されてcacheMap
いることがわかります。したがって、キャッシュマップをクリアすると、キャッシュサービスリストをリアルタイムで変更する効果が得られます。リフレクションを介してキャッシュマップを取得し、クリア操作を行うことができます。
メインコードの実装
@Override
public void onEvent(Event event) {
try {
if (event instanceof NamingEvent){
nacosWeightRandomLoadBanlancer = (NacosWeightRandomLoadBanlancer) applicationContext.getBean(ReactorLoadBalancer.class);
LoadBalancerCacheManager loadBalancerCacheManager = applicationContext.getBean(LoadBalancerCacheManager.class);
log.info("bean:{}",loadBalancerCacheManager);
ConcurrentMap<String, Cache> cacheMap = (ConcurrentMap<String, Cache>) ReflectUtil.getFieldValue(loadBalancerCacheManager, "cacheMap");
for (Map.Entry<String, Cache> stringCacheEntry : cacheMap.entrySet()) {
String key = stringCacheEntry.getKey();
Cache cache = stringCacheEntry.getValue();
log.info("key:{}\tvalue:{}",key,cache);
cache.clear();
}
}
} catch (Exception e) {
log.error("e:{}",e);
e.printStackTrace();
}
}
}
Nacos監視サービス変換インターフェースを実装することにより、キャッシュサービスリストがクリアされ、オンラインおよびオフラインでのリアルタイムサービスの監視変換が実現されます。
抽出の最適化
書かれる