Nacos源码—8.Nacos升级gRPC分析六

大纲

7.服务端对服务实例进行健康检查

8.服务下线如何注销注册表和客户端等信息

9.事件驱动架构源码分析

一.处理ClientChangedEvent事件

也就是同步数据到集群节点:

public class DistroClientDataProcessor extends SmartSubscriber implements DistroDataStorage, DistroDataProcessor {
    ...
    @Override
    public void onEvent(Event event) {
        ...
        if (event instanceof ClientEvent.ClientVerifyFailedEvent) {
            syncToVerifyFailedServer((ClientEvent.ClientVerifyFailedEvent) event);
        } else {
            syncToAllServer((ClientEvent) event);
        }
    }

    private void syncToAllServer(ClientEvent event) {
        Client client = event.getClient();
        //Only ephemeral data sync by Distro, persist client should sync by raft.
        //临时实例使用Distro协议,持久化实例使用Raft协议
        //ClientManager.isResponsibleClient()方法,判断只有该client的责任节点才能进行集群数据同步
        if (null == client || !client.isEphemeral() || !clientManager.isResponsibleClient(client)) {
            return;
        }
        if (event instanceof ClientEvent.ClientDisconnectEvent) {
            //如果event是客户端注销实例时需要进行集群节点同步的事件
            DistroKey distroKey = new DistroKey(client.getClientId(), TYPE);
            distroProtocol.sync(distroKey, DataOperation.DELETE);
        } else if (event instanceof ClientEvent.ClientChangedEvent) {
            //如果event是客户端注册实例时需要进行集群节点同步的事件
            DistroKey distroKey = new DistroKey(client.getClientId(), TYPE);
            distroProtocol.sync(distroKey, DataOperation.CHANGE);
        }
    }
    ...
}

@Component
public class DistroProtocol {
    private final ServerMemberManager memberManager;
    private final DistroTaskEngineHolder distroTaskEngineHolder;
    ...

    //Start to sync by configured delay.
    public void sync(DistroKey distroKey, DataOperation action) {
        sync(distroKey, action, DistroConfig.getInstance().getSyncDelayMillis());
    }

    //Start to sync data to all remote server.
    public void sync(DistroKey distroKey, DataOperation action, long delay) {
        //遍历集群中除自身节点外的其他节点
        for (Member each : memberManager.allMembersWithoutSelf()) {
            syncToTarget(distroKey, action, each.getAddress(), delay);
        }
    }

    //Start to sync to target server.
    public void syncToTarget(DistroKey distroKey, DataOperation action, String targetServer, long delay) {
        //先把要同步的集群节点targetServer包装成DistroKey对象
        DistroKey distroKeyWithTarget = new DistroKey(distroKey.getResourceKey(), distroKey.getResourceType(), targetServer);
        //然后根据DistroKey对象创建DistroDelayTask任务
        DistroDelayTask distroDelayTask = new DistroDelayTask(distroKeyWithTarget, action, delay);
        //接着调用NacosDelayTaskExecuteEngine.addTask()方法
        //往延迟任务执行引擎DistroDelayTaskExecuteEngine中添加延迟任务DistroDelayTask
        distroTaskEngineHolder.getDelayTaskExecuteEngine().addTask(distroKeyWithTarget, distroDelayTask);
        if (Loggers.DISTRO.isDebugEnabled()) {
            Loggers.DISTRO.debug("[DISTRO-SCHEDULE] {} to {}", distroKey, targetServer);
        }
    }
    ...
}

二.处理ClientDeregisterServiceEvent事件

也就是移除注册表 + 订阅表的服务实例:

@Component
public class ClientServiceIndexesManager extends SmartSubscriber {
    //注册表(服务提供者),一个Service服务对象,对应多个服务实例的clientId
    private final ConcurrentMap<Service, Set<String>> publisherIndexes = new ConcurrentHashMap<>();

    //订阅者列表(服务消费者),一个Service服务对象,对应多个订阅者的cl
<think>我们正在处理一个关于Nacos客户端日志配置的问题。用户报告的错误是: "Unable to locate appender ASYNC-REMOTE for logger config com.alibaba.nacos.shaded.io.grpc" 这个错误通常发生在Nacos客户端尝试使用名为"ASYNC-REMOTE"的appender记录日志时,但在当前的日志配置中找不到该appender。 ### 问题分析 1. **日志框架配置问题**:Nacos客户端内部使用了SLF4J作为日志门面,实际日志实现可能是Logback、Log4j等。错误信息表明,在日志配置中,没有为名为"com.alibaba.nacos.shaded.io.grpc"的logger配置一个叫做"ASYNC-REMOTE"的appender。 2. **Nacos客户端的日志配置**:Nacos客户端在启动时会尝试加载默认的日志配置,但用户可能自定义了日志配置,覆盖了Nacos的默认配置。 3. **依赖冲突**:如果项目中存在多个日志框架的依赖,可能会导致配置混乱。 ### 解决方案 #### 1. 检查日志配置文件 确保日志配置文件(如logback.xml、log4j2.xml等)中定义了名为"ASYNC-REMOTE"的appender,并且该appender被关联到logger"com.alibaba.nacos.shaded.io.grpc"。 例如,在Logback中,配置可能如下: ```xml <appender name="ASYNC-REMOTE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 配置略 --> </appender> <logger name="com.alibaba.nacos.shaded.io.grpc" level="INFO"> <appender-ref ref="ASYNC-REMOTE"/> </logger> ``` #### 2. 检查默认日志配置 如果用户没有提供自定义日志配置,Nacos客户端会使用默认配置。但某些情况下,默认配置可能被覆盖。可以尝试在项目中添加一个简单的日志配置文件(如logback.xml)并配置所需的appender。 #### 3. 排除日志依赖冲突 检查项目的依赖树,确保没有引入多个日志框架的冲突版本。可以使用Maven的依赖分析工具: ```bash mvn dependency:tree ``` 或Gradle的依赖分析: ```bash gradle dependencies ``` 然后排除不必要的日志依赖。 例如,在Maven中排除冲突的日志依赖: ```xml <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> ``` #### 4. 使用Nacos默认日志配置 如果问题仍然存在,可以尝试使用Nacos自带的默认日志配置。在classpath下添加Nacos的默认日志配置文件(例如,从Nacos客户端jar包中提取logback.xml文件并放入项目的resources目录下)。但请注意,这可能会覆盖你的自定义配置。 ### 补充说明 - 如果问题仅在特定环境(如生产环境)出现,请检查该环境下的日志配置是否正确部署。 - 确保日志配置文件的名称和位置正确,并且被正确加载。 ### 示例配置(Logback) 以下是一个简单的Logback配置示例,定义了一个控制台输出和一个文件输出的appender,并将文件输出appender命名为"ASYNC-REMOTE"(注意:实际中"ASYNC-REMOTE"可能是一个异步appender,这里仅作示例): ```xml <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <appender name="ASYNC-REMOTE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>nacos.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>nacos.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>1GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <logger name="com.alibaba.nacos.shaded.io.grpc" level="INFO"> <appender-ref ref="ASYNC-REMOTE"/> </logger> <root level="INFO"> <appender-ref ref="CONSOLE"/> </root> </configuration> ``` 请根据实际需求调整。 ### 相关问题 1. 如何为Nacos客户端配置日志级别? 2. 如何解决SLF4J绑定多个日志框架的问题? 3. Nacos客户端在Spring Cloud项目中日志配置的优先级是怎样的?</think>### Nacos客户端日志配置问题分析 您遇到的错误信息 `Nacos client ERROR Unable to locate appender ASYNC-REMOTE for logger config com.alibaba.nacos.shaded.io.grpc` 表明Nacos客户端在尝试使用名为"ASYNC-REMOTE"的日志追加器(appender)时失败。以下是系统性的解决方案: --- ### 问题原因分析 1. **日志配置缺失** Nacos客户端内部使用`com.alibaba.nacos.shaded.io.grpc`包下的GRPC组件,该组件默认配置了名为`ASYNC-REMOTE`的appender。当您的项目日志配置中缺少此appender定义时,会触发此错误[^1]。 2. **日志框架冲突** 项目可能存在多个日志框架(如Logback、Log4j2、SLF4J)的依赖冲突,导致配置加载异常。 3. **配置覆盖问题** 自定义日志配置文件(如`logback.xml`)未正确继承Nacos默认配置,或错误覆盖了关键配置项。 --- ### 解决方案 #### 方案1:添加缺失的appender配置(推荐) 在您的日志配置文件(如`logback.xml`)中明确定义`ASYNC-REMOTE` appender: ```xml <!-- logback.xml 示例 --> <configuration> <!-- 1. 定义ASYNC-REMOTE appender --> <appender name="ASYNC-REMOTE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logs/nacos-remote.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>logs/nacos-remote.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 2. 关联到Nacos GRPC日志器 --> <logger name="com.alibaba.nacos.shaded.io.grpc" level="INFO"> <appender-ref ref="ASYNC-REMOTE"/> <!-- 关键配置 --> </logger> </configuration> ``` #### 方案2:排除冲突日志依赖 检查并排除重复的日志框架依赖(Maven示例): ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <exclusions> <!-- 排除冲突的日志绑定 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> ``` #### 方案3:启用Nacos默认配置 在`application.properties`中强制使用Nacos内置日志配置: ```properties # 强制加载Nacos默认日志配置 nacos.logging.config=classpath:nacos-logback.xml ``` --- ### 验证步骤 1. **检查配置生效** 启动时添加JVM参数验证配置加载: ```bash -Dlogging.config=classpath:logback.xml -Dnacos.logging.default.config.enabled=true ``` 2. **查看日志输出** 检查`logs/nacos-remote.log`是否生成,并包含GRPC相关日志。 3. **依赖树分析** 使用命令检查冲突: ```bash mvn dependency:tree | grep -E 'log4j|logback|slf4j' ``` --- ### 技术原理 Nacos客户端通过`nacos-client-logging`模块初始化日志系统,其默认配置要求存在`ASYNC-REMOTE` appender用于GRPC通信日志[^2]。当自定义配置覆盖默认配置但未保留此appender时,会导致组件级日志记录失败。 --- ### 相关问题 1. 如何为Nacos客户端配置不同的日志级别? 2. Spring Boot项目中如何统一管理Nacos与其他组件的日志配置? 3. Nacos客户端日志配置不生效的常见排查方法有哪些? [^1]: Nacos官方文档 - 日志配置说明 [^2]: Nacos GitHub源码 - nacos-client-logging模块
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值