entorno de desarrollo
cuadro | Versión |
---|---|
Nube primaveral | 2020.0.2 |
Nacos | 2.2.1.LIBERAR |
Metas
Dado que loadbalancer
el caché de equilibrio de carga predeterminado es de 30 s , si se produce un servicio 上下线
, el consumidor del servicio no puede saber la adquisición en el primer momento y la llamada 远程服务
fallará. Por lo tanto, queremos darnos cuenta de que cuando el servicio se desconecta, puede notificar al consumidor del servicio la primera vez y luego puede realizar una serie de operaciones.
Idea principal
Mi idea es usar Nacos
la interfaz de transformación del servicio de monitoreo para modificar la lista de caché del equilibrio de carga para realizar la modificación en tiempo real de la lista de caché del servicio.
Leer el código fuente
org.springframework.cloud.loadbalancer.config
Se encontraron dos clases al observar las clases de configuración en el paquete
@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);
}
}
Se puede ver que, por defecto, Spring LoadBalancer utilizará la DefaultLoadBalancerCacheManager
clase de implementación como gestión de caché, así que echemos un vistazo a su código fuente.
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());
}
}
Se puede ver que la lista de caché de almacenamiento se implementa a través de cacheMap
este objeto, por lo que si borramos el mapa de caché, podemos lograr el efecto de modificar la lista de servicios de caché en tiempo real.Podemos obtener su mapa de caché a través de la reflexión para una operación clara.
Implementación del código principal
@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();
}
}
}
Al implementar la interfaz de transformación del servicio de monitoreo de Nacos, se borra la lista de servicios de caché para realizar la transformación del monitoreo del servicio en tiempo real en línea y fuera de línea.
Optimización de extracción
para ser escrito