Recuerde que un empleado del zoológico excepción que se lanza dubbo accidente proveedor de servicios de red perdida

fondo

Durante las empresas de calentamiento y gran favorecer la aparición de dubbo proveedor de servicios con la pérdida del accidente, la actuación principal es el pago a proveedores se pierden seis aplicaciones en los enlaces, pero otro proveedor de servicios de la compañía es normal, y el problema se puede aplicar adecuadamente ZK conectividad.

Algunas preguntas

Este problema se produce después, nuestro equipo tuvo un par de preguntas,

  1. Después de la recuperación cuidador del zoológico, podría decirse que dubbo servicio será re-registrado
  2. ¿Por qué pagar por sólo el enlace de esta línea es un problema, todos los demás enlace normal
  3. Los entornos de producción son el despliegue de múltiples nodos, ¿por qué todos los nodos de enlaces pagados ni debidamente registrados, y todos los demás nodos son las aplicaciones normales de enlace

Solución de problemas

La investigación preliminar

En el curso de la investigación inicial, encontramos los siguientes problemas:

  1. Conexión de proceso no es reelegido durante el cuidador del zoológico que había sucedido, probablemente duró alrededor de 3 a 4 minutos
  2. entorno de producción zookeeper tres nodos tienen un problema de configuración, suponiendo que los tres eran ZK1, ZK2, zk3, entonces ZK1 con el racimo se convirtió ZK1, ZK1, ZK2, los dos restantes fueron configuración normal
  3. Hay un problema porque se aplica el código, lo que resulta en aproximadamente 1.000 consumidor

Sin embargo, intuitivamente, nuestro equipo de acuerdo en que si bien 2,3 problema de dos horas, pero debe haber nada que ver con este accidente.

una pregunta

En primer lugar, estábamos muy confundido es una pregunta, así que no tengo la intención de considerar la cuestión de dos, tres preguntas, una razón para dudar de la investigación.

adivinar

Para una duda, debido al cuidador del zoológico y dubbo no particularmente familiarizados con, hacer mucho durante la prueba, finalmente encontrado, pero que tome la iniciativa de nodo de proveedor de eliminación zkCli, no se vuelve a registrar dubbo.

Así que para ver los asuntos de la operación de registro de los cuidadores del zoológico, no eliminar registros en el nodo proveedor de descubrimiento. Así que supongo que sólo puede ser borrado automáticamente el cuidador del zoológico.

Así que para hacer una conjetura, Dubbo realidad volver a registrarse, pero más tarde se retiraron al cuidador del zoológico .

problema recurrente

Solución de problemas de todo tomó un largo tiempo, no encuentra nada, hasta que encuentre la casa hay un documento wiki hace tres años, un accidente similar registrada en el entorno de prueba, más o menos similar a la sensación del accidente y la grabación de la wiki, wiki para que, de acuerdo con los pasos se reproducen.

  1. ZK1 inicio, ZK2, zk3, servicio dubbo despliegue. Servicio registrado correctamente
  2. Desconectar ZK1, ZK2 red entre, zk3, racimo zk no está disponible, servicio dubbo informó error de conexión de tiempo de espera zk
  3. Esperar 4 minutos
  4. Restaurar red entre ZK1, ZK2, zk3, reconexión del servicio de dubbo y servicios de registro
  5. Ver zookeeper nodo, proveedor linfáticos normales
  6. Espere un minuto
  7. proveedor de nodo de desaparecer

ZK registro abierto, de la siguiente manera:

registro de ZK

dubbo registro de servicio es el siguiente:

registro del servicio dubbo

Puede verse en dubbo tiene que volver a registrarse después de una recuperación cuidador del zoológico, pero se puede ver el final cuidador del zoológico, el resultado de reinscripción es NodeExists, y produce una excepción. dubbo final, pero ignorado esta excepción. Después de un tiempo los niños, se elimina empleado del zoológico final del gran número de sesión de tiempo extra, al mismo nodo proveedor de tiempo.

Aquí, tenemos básicamente una cuestión de interpretación:

1. Al principio, todo Dubbo normal y zk, y conectado por período de sesionesa
desconectar red de clúster zk 2. A continuación, la condición no puede exceder de la mitad de los nodos disponibles, el grupo está en el zk estado disponible, ZK Dubbo y desconectado
3. zk restaurados normal, dubbo pensar sesionesa servicio ha sido desconectado y vuelto a iniciar una nueva sessionB, y el nodo proveedor registrado. En un momento en ZK debido a la persistencia local utilizando los datos originales se restaura a la normalidad sesionesa piensa es normal, el nodo proveedor no borrada sesionesa registrado. Así sessionB registro falla, y dubbo ignorar esta anomalía, también se considera todo el bien
4. Después de un niño, debido al hecho de sesionesa se ha desconectado, incapaz de mantener un ritmo cardíaco normal, por lo que después de que el tiempo de espera, ZK desconectado sesionesa, y se aclaró período de sesionesa correspondiente nodo proveedor

A continuación, se simula todo el proceso de pérdida de nodo de proveedor.

A continuación podemos verificar algunos de los puntos del proceso por la fuente de la especulación:

A. Servicio dubbo NodeExists ignorados anormal

package com.helijia.dubbox.remoting.zookeeper.curator;

public class CuratorZookeeperClient extends AbstractZookeeperClient<CuratorWatcher> {
  
    ... ...
  
    public void createEphemeral(String path) {
        try {
            client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
        } catch (NodeExistsException ignored) {
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
}
复制代码

Podemos ver la NodeExistsException ignorados en el proceso de creación de un nodo temporal

tratamiento B. zk para período de sesionesa

package org.apache.zookeeper.server;

public class SessionTrackerImpl extends ZooKeeperCriticalThread implements SessionTracker {
  
    ... ...
  
    @Override
    synchronized public void run() {
        try {
            while (running) {
                currentTime = Time.currentElapsedTime();
                if (nextExpirationTime > currentTime) {
                    this.wait(nextExpirationTime - currentTime);
                    continue;
                }
                SessionSet set;
                set = sessionSets.remove(nextExpirationTime);
                if (set != null) {
                    for (SessionImpl s : set.sessions) {
                        setSessionClosing(s.sessionId);
                        expirer.expire(s);
                    }
                }
                nextExpirationTime += expirationInterval;
            }
        } catch (InterruptedException e) {
            handleException(this.getName(), e);
        }
        LOG.info("SessionTrackerImpl exited loop!");
    }
}
复制代码

Este código se utiliza para manejar la sesión ha finalizado, ver aquí, usted puede pedir, ¿no es igual que en esta sesión se ZK se mató durante la elección, de hecho, no una agrupación ZK no está disponible, runninglas variables cambiarán es falso, y sessionSetsse mantuvo a la base de datos de ZK (Este código no está fijado hacia fuera). El ciclo terminará, esperar hasta ZK vuelto a la normalidad, y luego restaurar la sesión anterior.

A continuación podemos ver, SessionTrackerImplsimplemente crear lo que nextExpirationTime,

package org.apache.zookeeper.server;

public class SessionTrackerImpl extends ZooKeeperCriticalThread implements SessionTracker {
    public SessionTrackerImpl(SessionExpirer expirer,
            ConcurrentHashMap<Long, Integer> sessionsWithTimeout, int tickTime,
            long sid, ZooKeeperServerListener listener)
    {
        super("SessionTracker", listener);
        this.expirer = expirer;
        this.expirationInterval = tickTime;
        this.sessionsWithTimeout = sessionsWithTimeout;
        nextExpirationTime = roundToInterval(Time.currentElapsedTime());
        this.nextSessionId = initializeNextSession(sid);
        for (Entry<Long, Integer> e : sessionsWithTimeout.entrySet()) {
            addSession(e.getKey(), e.getValue());
        }
    }
    
    private long roundToInterval(long time) {
        // We give a one interval grace period
        return (time / expirationInterval + 1) * expirationInterval;
    }
}
复制代码

En el código anterior se puede ver en la primera nextExpirationTimerelación de currentTimemás de un período de tiempo de espera después de que es un retorno a la normalidad ZK necesidad de esperar un período de tiempo de espera, se producirá un error de limpiar la sesión original.

Como se dijo anteriormente, la edad persistencia de sesión, que se puede confirmar desde la creación de la sesión, como se deduce de la segunda parámetro pasado puede saber cuando se obtienen los datos de sesión de base de datos de la ZK inicial. (Por supuesto, no hay pruebas suficientes, se puede tratar de crear un nodo temporal zkCli, ZK luego se detuvo rápidamente, a continuación, iniciar ZK, nodo temporal hasta después de que nos encontramos después de comenzar persistir durante algún tiempo)

package org.apache.zookeeper.server;

public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
    
    ... ...
    
    protected void createSessionTracker() {
        // 第二个参数可以看出session数据初始时会从zk的数据库中进行获取
        sessionTracker = new SessionTrackerImpl(this, zkDb.getSessionWithTimeOuts(),
                tickTime, 1, getZooKeeperServerListener());
    }
}
复制代码

Aquí, podemos explicar completamente la primera pregunta.

La pregunta dos, tres preguntas

Para preguntas dos y tres preguntas, es casi seguro que esto no es un accidente, sino un acontecimiento inevitable. Debido a que la misma zk se utilizan todas las aplicaciones, y por lo tanto este problema deben ZK nada que ver, debe ser dubbo lado del servicio de la cuestión. Por lo que es fácil adivinar, y dubbo versión, zkCli, dubbox, curador de estas bibliotecas vinculadas.

Pero incluso con esta especulación, todavía no hay manera de comprobar en adelante, porque no hay tiempo, ni tampoco el código de estas bibliotecas de investigación tripartitos de nuevo.

Según el registro de análisis

Bueno, esto se sigue haciendo por la forma reproducir la escena de la investigación, esta vez he elegido se observaron un servicio dubbo normal y un dubbo problema de servicio, respectivamente, cada uno de ellos para seleccionar un proveedor de seguimiento de sesión. El mismo funcionamiento de la red entre un zk abierto, a largo de unos 2 minutos OFF.

De registro de los servicios dubbo normales son los siguientes:

2020-03-11 10:23:56,975 [org.apache.zookeeper.ClientCnxn]-[localhost-startStop-1-SendThread(10.3.6.39:12181)]-[onConnected]-[1299]-[INFO] Session establishment complete on server 10.3.6.39/10.3.6.39:12181, sessionid = 0x170c26cf67a0011, negotiated timeout = 40000
2020-03-11 11:40:33,357 [org.apache.zookeeper.ClientCnxn]-[localhost-startStop-1-SendThread(10.3.6.39:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c26cf67a0011, likely server has closed socket, closing socket connection and attempting reconnect
2020-03-11 11:40:35,009 [org.apache.zookeeper.ClientCnxn]-[localhost-startStop-1-SendThread(10.3.6.39:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c26cf67a0011, likely server has closed socket, closing socket connection and attempting reconnect
... ...
2020-03-11 11:42:39,282 [org.apache.zookeeper.ClientCnxn]-[localhost-startStop-1-SendThread(10.3.6.39:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c26cf67a0011, likely server has closed socket, closing socket connection and attempting reconnect
2020-03-11 11:42:40,502 [org.apache.zookeeper.ClientCnxn]-[localhost-startStop-1-SendThread(10.3.6.39:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c26cf67a0011, likely server has closed socket, closing socket connection and attempting reconnect
2020-03-11 11:42:42,117 [org.apache.zookeeper.ClientCnxn]-[localhost-startStop-1-SendThread(10.3.6.39:12181)]-[onConnected]-[1299]-[INFO] Session establishment complete on server 10.3.6.39/10.3.6.39:12181, sessionid = 0x170c26cf67a0011, negotiated timeout = 40000
复制代码

servicios dubbo problema de registro son los siguientes:

2020-03-11 10:24:42,548 [org.apache.zookeeper.ClientCnxn]-[Curator-Framework-0-SendThread(10.3.6.39:12181)]-[onConnected]-[1299]-[INFO] Session establishment complete on server 10.3.6.39/10.3.6.39:12181, sessionid = 0x170c7688bbc0001, negotiated timeout = 40000
2020-03-11 11:41:24,733 [org.apache.zookeeper.ClientCnxn]-[Curator-Framework-0-SendThread(10.3.8.118:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c7688bbc0001, likely server has closed socket, closing socket connection and attempting reconnect
2020-03-11 11:41:25,400 [org.apache.zookeeper.ClientCnxn]-[Curator-Framework-0-SendThread(10.3.8.117:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c7688bbc0001, likely server has closed socket, closing socket connection and attempting reconnect
... ...
2020-03-11 11:42:23,802 [org.apache.zookeeper.ClientCnxn]-[Curator-Framework-0-SendThread(10.3.8.117:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c7688bbc0001, likely server has closed socket, closing socket connection and attempting reconnect
2020-03-11 11:42:23,972 [org.apache.zookeeper.ClientCnxn]-[Curator-Framework-0-SendThread(10.3.6.39:12181)]-[run]-[1158]-[INFO] Unable to read additional data from server sessionid 0x170c7688bbc0001, likely server has closed socket, closing socket connection and attempting reconnect
2020-03-11 11:42:24,841 [org.apache.curator.ConnectionState]-[DubboRegistryFailedRetryTimer-thread-1]-[checkTimeouts]-[191]-[WARN] Connection attempt unsuccessful after 60007 (greater than max timeout of 60000). Resetting connection and trying again with a new connection.
2020-03-11 11:42:25,277 [org.apache.zookeeper.ZooKeeper]-[DubboRegistryFailedRetryTimer-thread-1]-[close]-[684]-[INFO] Session: 0x170c7688bbc0001 closed
2020-03-11 11:42:25,277 [org.apache.zookeeper.ClientCnxn]-[Curator-Framework-0-EventThread]-[run]-[519]-[INFO] EventThread shut down for session: 0x170c7688bbc0001
复制代码

Después de que el registro se puede encontrar desde el reintento dubbo anteriormente, el servicio normal ha sido hasta la re-conexión de sesión se realiza correctamente, pero el servicio dubbo problema volverá a intentar un minuto, desconectar la sesión, vuelva a crear una nueva sesión.

Ver el registro de entorno de producción descubrió que más de los enlaces de pago 6 problemas de servicio dubbo, afectó a un total de más de 20 aplicaciones, pero sólo pagó enlaces proveedor de seis aplicaciones, otras aplicaciones son solamente consumidores.

Ya se puede explicar este fenómeno desde el registro, entonces el siguiente para encontrar la verdadera razón de la peor desde el código fuente.

Averiguar las razones del código fuente

En primer lugar, encontrar la Connection attempt unsuccessful after 60007 (greater than max timeout of 60000). Resetting connection and trying again with a new connection.ubicación del código de este registro se encuentra,

package org.apache.curator;

class ConnectionState implements Watcher, Closeable {
    
    ... ...
    
    private synchronized void checkTimeouts() throws Exception
    {
        int minTimeout = Math.min(sessionTimeoutMs, connectionTimeoutMs);
        long elapsed = System.currentTimeMillis() - connectionStartMs;
        if ( elapsed >= minTimeout )
        {
            if ( zooKeeper.hasNewConnectionString() )
            {
                handleNewConnectionString();
            }
            else
            {
                int maxTimeout = Math.max(sessionTimeoutMs, connectionTimeoutMs);
                if ( elapsed > maxTimeout )
                {
                    if ( !Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES) )
                    {
                        log.warn(String.format("Connection attempt unsuccessful after %d (greater than max timeout of %d). Resetting connection and trying again with a new connection.", elapsed, maxTimeout));
                    }
                    reset();
                }
                else
                {
                    KeeperException.ConnectionLossException connectionLossException = new CuratorConnectionLossException();
                    if ( !Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES) )
                    {
                        log.error(String.format("Connection timed out for connection string (%s) and timeout (%d) / elapsed (%d)", zooKeeper.getConnectionString(), connectionTimeoutMs, elapsed), connectionLossException);
                    }
                    new EventTrace("connections-timed-out", tracer.get(), getSessionId()).commit();
                    throw connectionLossException;
                }
            }
        }
    }
}
复制代码

Algunos de depuración, se encontró diferencias en la aplicación normal y problemas aplicados en esto. A continuación, la aplicación normal elapsed>connectionTimeoutMsobstruir la parte roja de la figura de abajo, y problemas en la aplicación se ejecutará hasta que elapsed > maxTimeoutdespués de reiniciar la sesión.

imagen-20200311163446869

¿Por qué un bloqueo de aplicaciones normales, y los problemas en la aplicación no bloquearla, al final encontramos por debajo de este punto de los dos va a llegar a una rama diferente,

imagen-20200311165058123

A continuación, la siguiente nota es condiciones más atractivas de la presente sentencia, el siguiente código, ambos códigos son los mismos,

imagen-20200311165600268

Depurar encontró que tanto client.getRetryPolicy()la estrategia de reintento de retorno es diferente de los rendimientos normales de aplicación n = 1, la solicitud problema vuelve n = Integer.MAX_VALUE. A continuación, el resto es comprobar la inicialización del proceso de retryPolicy de ambos.

Encuentra inyectado en el modo de depuración retryPolicy

problemas de las aplicaciones

Para el problema aplicaciones, como se muestra a continuación, ya que la aplicación antigua, se utiliza CuratorZookeeperClient dubbox-1.0.4, en el que el número de reintentos ha establecido como predeterminado ilimitada (Integer.MAX_VALUE)

imagen-20200311161008906

aplicación normal

Para uso normal, como se muestra abajo, CuratorZookeeperClient se carga el dubbo-2.6.7, en el que el valor predeterminado para el número de reintentos 1

imagen-20200311160525435

Investigación aquí, se puede llegar a una conclusión, que es la diferencia entre las diferentes versiones de los dos dubbo utilizado, que dubbo-2.6.7 no tendrá este problema, dubbox-1.0.4 (dubbo-2.5.3 ) se produce este problema .

Con la versión dubbo (2.5.3), una normal, no es un problema

Pero la historia no termina aquí. Es más complicado de lo esperado, de hecho, el problema de todas las aplicaciones utilizan el dubbo2.5.3, pero no todas las aplicaciones dubbo2.5.3 tener problemas, hay alguna aplicación dubbo2.5.3 realmente se está ejecutando con normalidad.

Buscando una aplicación normal, la depuración se encontró que no hay carga de cliente conservador y, por tanto, restablecer el problema anterior no aparece la sesión . Después de la comparación detallada encontró, dubbo problemas de configuración de la aplicación como sigue:

<dubbo:registry protocol="zookeeper" address="${user.dubbo.zk.servers}" client="curatorx" />
复制代码

Dubbo aplicación normal y dispuestas como sigue:

<dubbo:registry protocol="zookeeper" address="${dubbo.registry.address}" check="true" />
复制代码

Para la versión dubbo2.5.3, zkclient predeterminado, después de la fig. Por lo que una aplicación normal no está cargado cliente conservador, y la aplicación problemática especifica el uso del curador como cliente .

dubbo-2.5.3

Por supuesto, para dubbo2.6.7, como cliente predeterminado curador ZK

dubbo-2.6.7

conclusión

En mi caso, que implica sólo el dubbo2.5.3 y dubbo2.6.7, otra versión dubbo Es necesario comprobar usted mismo

Por lo tanto, ya están todas explicarán las tres preguntas anteriores.

En resumen, cuando la versión dubbo2.5.3 (versión dubbo otra baja pueden tener problemas similares) y el cliente se especifica como conservador, aparecerá después cuidador del zoológico estado inutilizable durante un cierto tiempo, el proveedor de desaparecer fenómeno.

Supongo que te gusta

Origin juejin.im/post/5e68cb2ff265da573402545c
Recomendado
Clasificación