¡Acostúmbrate a escribir juntos! Este es el quinto día de mi participación en el "Nuggets Daily New Plan·Desafío de actualización de abril", haz clic para ver los detalles del evento
Proceso de alta en el servicio de atención al cliente de Eureka
La determinación es el principio del éxito.
Artículos relacionados
Diagrama + explicación del código fuente Diagrama de análisis del proceso de inicio del servidor Eureka + explicación del código fuente Diagrama
de análisis del proceso de inicio del cliente Eureka + explicación del código fuente Diagrama
lógico de la memoria caché del registro del servidor Eureka
+ explicación del código fuente Proceso de extracción del registro del cliente Eureka
Diagrama de flujo del núcleo de registro
Dónde comenzar su análisis
Cuando se inicializa el cliente, clientConfig.shouldEnforceRegistrationAtInit() Si habilitar el registro obligatorio al inicializar, este valor es falso de forma predeterminada, por lo que no se registrará. Se registra en el método renew() en los 30 segundos posteriores que envían la tarea del mecanismo de latido .
if (clientConfig.shouldRegisterWithEureka() &&
// clientConfig.shouldEnforceRegistrationAtInit() 默认是false
clientConfig.shouldEnforceRegistrationAtInit()) {
if (!register()) {
throw new IllegalStateException("Registration error at startup. Invalid server response.");
}
}
复制代码
lógica central
Cuando el latido se envía a través de renew(), devuelve que no se puede encontrar la información de la instancia, por lo que la operación de registro se realiza nuevamente y la operación de solicitud de latido se realiza a través del cliente eurekaTransport.registrationClient.
1. Iniciar el registro a través de tareas de sincronización de latidos
boolean renew() {
EurekaHttpResponse<InstanceInfo> httpResponse;
httpResponse = eurekaTransport.registrationClient.
sendHeartBeat(instanceInfo.getAppName(),
instanceInfo.getId(), instanceInfo, null);
if (httpResponse.getStatusCode() == Status.NOT_FOUND.getStatusCode()) {
REREGISTER_COUNTER.increment();
long timestamp = instanceInfo.setIsDirtyWithTime();
boolean success = register(); // 注册实例
if (success) {
instanceInfo.unsetIsDirty(timestamp);
}
return success;
}
return httpResponse.getStatusCode() == Status.OK.getStatusCode();
}
复制代码
El registro de instancias se realiza a través del método register(), y el acceso al método de registro se realiza a través de eurekaTransport.registrationClient, que accede al método de registro de AbstractJersey2EurekaHttpClient
boolean register() throws Throwable {
EurekaHttpResponse<Void> httpResponse;
httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
....
}
复制代码
Se accede al método de registro de AbstractInstanceRegistry bajo el proyecto eureka-core a través del marco jersey2
public void register(InstanceInfo registrant, int leaseDuration,
boolean isReplication) {
/**
* 通过服务名字从本地的 gMap 中获取一个服务实例信息
*/
Map<String, Lease<InstanceInfo>> gMap = registry.get(registrant.getAppName());
if (gMap == null) {
// 如果本地gMap中没有当前要注册的实例的话创建一个 gNewMap
// 也就是 registry 中的一个服务实例
final ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap =
new ConcurrentHashMap<String, Lease<InstanceInfo>>();
// 将当前服务名字为key并且服务名字,value就是当前要注册的 gNewMap
gMap = registry.putIfAbsent(registrant.getAppName(), gNewMap);
if (gMap == null) {
gMap = gNewMap;
}
}
// 说白了上面就是创建了一个gMap中的一个实例
gMap.put(registrant.getId(), lease);
}
复制代码
2. Ponga la instancia actual en la cola
Esta cola de registro y cola de cambios se crean cuando se inicializa el servicio. El estado cambiado recientemente se puede monitorear a través de esta cola cambiada recientemente. La cola recién registrada y la cola fuera de línea son principalmente para mostrar en la página . La cola cambiada recientemente Se utiliza al obtener información de instancia de registro incremental .
/**
* 将当前实例放入到最近注册的队列
*/
recentRegisteredQueue.add(new Pair<Long, String>(System.currentTimeMillis(),
registrant.getAppName() + "(" + registrant.getId() + ")"));
// 设置类型为添加类型
registrant.setActionType(ActionType.ADDED);
/**
* 添加也属于改变所以创建一个最近的改变对象【RecentlyChangedItem】放入到最近的改变队列中,
* 时间戳是当前的系统时间
*/
recentlyChangedQueue.add(new RecentlyChangedItem(lease));
复制代码
3. Invalidar caché local
/**
* 当有新实例过来的时候无效当前读写缓存
*/
invalidateCache(registrant.getAppName(), registrant.getVIPAddress(),
registrant.getSecureVipAddress());
复制代码
La invalidación de la operación de la memoria caché local consiste en eliminar algunas claves de la memoria caché a través del método de invalidación de ResponseCacheImpl y eliminar el valor de la clave en la memoria caché de lectura y escritura.
public void invalidate(Key... keys) {
for (Key key : keys) {
// 移除读写缓存中的key
readWriteCacheMap.invalidate(key);
Collection<Key> keysWithRegions = regionSpecificKeys.get(key);
if (null != keysWithRegions && !keysWithRegions.isEmpty()) {
for (Key keysWithRegion : keysWithRegions) {
readWriteCacheMap.invalidate(keysWithRegion);
}
}
}
}
复制代码
resumen
- Iniciar registro a través de heartbeat
- Coloque la instancia actual en la cola de registro y la cola de cambios recientes
- Invalidar caché del lado del servidor