Skywalking hablar de RemoteClientManager

secuencia

En este trabajo, nos fijamos skywalking de RemoteClientManager

RemoteClientManager

skywalking-6.6.0 / OAP-servidor / servidor-core / src / main / java / org / apache / skywalking / oap / servidor / núcleo / remote / cliente / RemoteClientManager.java

public class RemoteClientManager implements Service {

    private static final Logger logger = LoggerFactory.getLogger(RemoteClientManager.class);

    private final ModuleDefineHolder moduleDefineHolder;
    private ClusterNodesQuery clusterNodesQuery;
    private volatile List<RemoteClient> usingClients;
    private GaugeMetrics gauge;
    private int remoteTimeout;

    /**
     * Initial the manager for all remote communication clients.
     *
     * @param moduleDefineHolder for looking up other modules
     * @param remoteTimeout      for cluster internal communication, in second unit.
     */
    public RemoteClientManager(ModuleDefineHolder moduleDefineHolder, int remoteTimeout) {
        this.moduleDefineHolder = moduleDefineHolder;
        this.usingClients = ImmutableList.of();
        this.remoteTimeout = remoteTimeout;
    }

    public void start() {
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this::refresh, 1, 5, TimeUnit.SECONDS);
    }

    /**
     * Query OAP server list from the cluster module and create a new connection for the new node. Make the OAP server
     * orderly because of each of the server will send stream data to each other by hash code.
     */
    void refresh() {
        if (gauge == null) {
            gauge = moduleDefineHolder.find(TelemetryModule.NAME).provider().getService(MetricsCreator.class)
                .createGauge("cluster_size", "Cluster size of current oap node",
                    MetricsTag.EMPTY_KEY, MetricsTag.EMPTY_VALUE);
        }
        try {
            if (Objects.isNull(clusterNodesQuery)) {
                synchronized (RemoteClientManager.class) {
                    if (Objects.isNull(clusterNodesQuery)) {
                        this.clusterNodesQuery = moduleDefineHolder.find(ClusterModule.NAME).provider().getService(ClusterNodesQuery.class);
                    }
                }
            }

            if (logger.isDebugEnabled()) {
                logger.debug("Refresh remote nodes collection.");
            }

            List<RemoteInstance> instanceList = clusterNodesQuery.queryRemoteNodes();
            instanceList = distinct(instanceList);
            Collections.sort(instanceList);

            gauge.setValue(instanceList.size());

            if (logger.isDebugEnabled()) {
                instanceList.forEach(instance -> logger.debug("Cluster instance: {}", instance.toString()));
            }

            if (!compare(instanceList)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("ReBuilding remote clients.");
                }
                reBuildRemoteClients(instanceList);
            }

            printRemoteClientList();
        } catch (Throwable t) {
            logger.error(t.getMessage(), t);
        }
    }

    //......
}
复制代码
  • RemoteClientManager proporciona un método para obtener getRemoteClient usingClients, se proporciona un método de inicio de una tarea programada se registra cada 5 segundos para realizar una renovación; lista de refresco por un método de adquisición de clusterNodesQuery.queryRemoteNodes instanceList (), entonces de acuerdo con la dirección de bit reordenación de peso, a continuación, en comparación con la lista RemoteClient local, si no se encuentra para cambiar el funcionamiento reBuildRemoteClients gatillo, y finalmente ejecutar printRemoteClientList

reBuildRemoteClients

skywalking-6.6.0 / OAP-servidor / servidor-core / src / main / java / org / apache / skywalking / oap / servidor / núcleo / remote / cliente / RemoteClientManager.java

public class RemoteClientManager implements Service {

	//......

    private void reBuildRemoteClients(List<RemoteInstance> remoteInstances) {
        final Map<Address, RemoteClientAction> remoteClientCollection = this.usingClients.stream()
            .collect(Collectors.toMap(RemoteClient::getAddress, client -> new RemoteClientAction(client, Action.Close)));

        final Map<Address, RemoteClientAction> latestRemoteClients = remoteInstances.stream()
            .collect(Collectors.toMap(RemoteInstance::getAddress, remote -> new RemoteClientAction(null, Action.Create)));

        final Set<Address> unChangeAddresses = Sets.intersection(remoteClientCollection.keySet(), latestRemoteClients.keySet());

        unChangeAddresses.stream()
            .filter(remoteClientCollection::containsKey)
            .forEach(unChangeAddress -> remoteClientCollection.get(unChangeAddress).setAction(Action.Unchanged));

        // make the latestRemoteClients including the new clients only
        unChangeAddresses.forEach(latestRemoteClients::remove);
        remoteClientCollection.putAll(latestRemoteClients);

        final List<RemoteClient> newRemoteClients = new LinkedList<>();
        remoteClientCollection.forEach((address, clientAction) -> {
            switch (clientAction.getAction()) {
                case Unchanged:
                    newRemoteClients.add(clientAction.getRemoteClient());
                    break;
                case Create:
                    if (address.isSelf()) {
                        RemoteClient client = new SelfRemoteClient(moduleDefineHolder, address);
                        newRemoteClients.add(client);
                    } else {
                        RemoteClient client = new GRPCRemoteClient(moduleDefineHolder, address, 1, 3000, remoteTimeout);
                        client.connect();
                        newRemoteClients.add(client);
                    }
                    break;
            }
        });

        //for stable ordering for rolling selector
        Collections.sort(newRemoteClients);
        this.usingClients = ImmutableList.copyOf(newRemoteClients);

        remoteClientCollection.values()
            .stream()
            .filter(remoteClientAction -> remoteClientAction.getAction().equals(Action.Close))
            .forEach(remoteClientAction -> remoteClientAction.getRemoteClient().close());
    }

	//......
}
复制代码
  • Un método para construir y remoteClientCollection reBuildRemoteClients latestRemoteClients, a continuación, en los unChangeAddresses de intersección obtenido, después se retiró del unChangeAddresses latestRemoteClients, y finalmente añadió a latestRemoteClients remoteClientCollection; después de atravesar remoteClientCollection, para la acción a la Crear y dividido en SelfRemoteClient GRPCRemoteClient, para su posterior ejecución en GRPCRemoteClient operación de conexión; newRemoteClients última ordenar, y luego re-asignados a usingClients; para la última acción que se realiza cerca de la operación de cierre RemoteClient

RemoteSenderService

skywalking-6.6.0 / OAP-servidor / servidor-core / src / main / java / org / apache / skywalking / oap / servidor / núcleo / remote / RemoteSenderService.java

public class RemoteSenderService implements Service {
    private static final Logger logger = LoggerFactory.getLogger(RemoteSenderService.class);

    private final ModuleManager moduleManager;
    private final HashCodeSelector hashCodeSelector;
    private final ForeverFirstSelector foreverFirstSelector;
    private final RollingSelector rollingSelector;

    public RemoteSenderService(ModuleManager moduleManager) {
        this.moduleManager = moduleManager;
        this.hashCodeSelector = new HashCodeSelector();
        this.foreverFirstSelector = new ForeverFirstSelector();
        this.rollingSelector = new RollingSelector();
    }

    public void send(String nextWorkName, StreamData streamData, Selector selector) {
        RemoteClientManager clientManager = moduleManager.find(CoreModule.NAME).provider().getService(RemoteClientManager.class);
        RemoteClient remoteClient = null;

        List<RemoteClient> clientList = clientManager.getRemoteClient();
        if (clientList.size() == 0) {
            logger.warn("There is no available remote server for now, ignore the streaming data until the cluster metadata initialized.");
            return;
        }
        switch (selector) {
            case HashCode:
                remoteClient = hashCodeSelector.select(clientList, streamData);
                break;
            case Rolling:
                remoteClient = rollingSelector.select(clientList, streamData);
                break;
            case ForeverFirst:
                remoteClient = foreverFirstSelector.select(clientList, streamData);
                break;
        }
        remoteClient.push(nextWorkName, streamData);
    }
}
复制代码
  • RemoteSenderService proporciona un método de envío desde la obtención de clientList clientManager.getRemoteClient (), a continuación, elegir uno remoteClient.push ejecución remoteClient (nextWorkName, streamData) de acuerdo con el tipo de selector

RemoteClientSelector

skywalking-6.6.0 / OAP-servidor / servidor-core / src / main / java / org / apache / skywalking / oap / servidor / núcleo / remote / selector / RemoteClientSelector.java

public interface RemoteClientSelector {
    RemoteClient select(List<RemoteClient> clients, StreamData streamData);
}
复制代码
  • RemoteClientSelector define el método de selección

HashCodeSelector

skywalking-6.6.0 / OAP-servidor / servidor-core / src / main / java / org / apache / skywalking / oap / servidor / núcleo / remote / selector / HashCodeSelector.java

public class HashCodeSelector implements RemoteClientSelector {

    @Override public RemoteClient select(List<RemoteClient> clients, StreamData streamData) {
        int size = clients.size();
        int selectIndex = Math.abs(streamData.remoteHashCode()) % size;
        return clients.get(selectIndex);
    }
}
复制代码
  • HashCodeSelector dio cuenta de interfaz RemoteClientSelector, por Math.abs(streamData.remoteHashCode()) % sizela selección de selectIndex a

RollingSelector

skywalking-6.6.0 / OAP-servidor / servidor-core / src / main / java / org / apache / skywalking / oap / servidor / núcleo / remote / selector / RollingSelector.java

public class RollingSelector implements RemoteClientSelector {

    private int index = 0;

    @Override public RemoteClient select(List<RemoteClient> clients, StreamData streamData) {
        int size = clients.size();
        index++;
        int selectIndex = Math.abs(index) % size;

        if (index == Integer.MAX_VALUE) {
            index = 0;
        }
        return clients.get(selectIndex);
    }
}
复制代码
  • RollingSelector dio cuenta de interfaz RemoteClientSelector, que según el índice y luego incrementa cada vez que por Math.abs(index) % sizela selección de selectIndex

ForeverFirstSelector

skywalking-6.6.0 / OAP-servidor / servidor-core / src / main / java / org / apache / skywalking / oap / servidor / núcleo / remote / selector / ForeverFirstSelector.java

public class ForeverFirstSelector implements RemoteClientSelector {

    private static final Logger logger = LoggerFactory.getLogger(ForeverFirstSelector.class);

    @Override public RemoteClient select(List<RemoteClient> clients, StreamData streamData) {
        if (logger.isDebugEnabled()) {
            logger.debug("clients size: {}", clients.size());
        }
        return clients.get(0);
    }
}
复制代码
  • ForeverFirstSelector interfaz RemoteClientSelector dado cuenta, que siempre devuelve el primer cliente

resumen

RemoteClientManager proporciona un método para obtener getRemoteClient usingClients, se proporciona un método de inicio de una tarea programada se registra cada 5 segundos para realizar una renovación; lista de refresco por un método de adquisición de clusterNodesQuery.queryRemoteNodes instanceList (), entonces de acuerdo con la dirección de bit reordenación de peso, a continuación, en comparación con la lista RemoteClient local, si no se encuentra para cambiar el funcionamiento reBuildRemoteClients gatillo, y finalmente ejecutar printRemoteClientList

Doc

Supongo que te gusta

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