Nacos + Springloadbalancerは、オンラインとオフラインの高速化を実現します

開発環境

フレーム バージョン
Springcloud 2020.0.2
ナコス 2.2.1。リリース

目標

loadbalancerデフォルトの負荷分散キャッシュは30秒であるため、サービスが発生した場合上下线、サービスコンシューマーは最初に取得を知ることができず、呼び出しは远程服务失敗します。したがって、サービスがオフラインになると、最初にサービスコンシューマーに通知し、その後一連の操作を実行できることを認識したいと思います。

本旨

私の考えはNacos、監視サービス変換インターフェースを使用して負荷分散のキャッシュリストを変更し、サービスキャッシュリストのリアルタイム変更を実現することです。

ソースコードを読む

パッケージの下の構成クラスを調べると、 org.springframework.cloud.loadbalancer.config2つのクラスが見つかりました

@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監視サービス変換インターフェースを実装することにより、キャッシュサービスリストがクリアされ、オンラインおよびオフラインでのリアルタイムサービスの監視変換が実現されます。

抽出の最適化

書かれる

おすすめ

転載: juejin.im/post/7116743190681485349