一. 问题背景

【java进阶课程】玩转spring cloud alibaba易如反掌,从入门到精通nacos中跟着视频使用源码启动nacos的时候,遇到db.num = 0报错。网上查了很多都说直接在nacos安装目录的某某文件里面设置set mode = standalone。然而我是用idea打开nacos源码启动。

参考自:Nacos使用(1):源码单机运行

二. 解决方案

其实静下心来想想非常容易解决。idea运行程序的时候,可以加入虚拟机参数的,在运行之前加上-Dnacos.standalone=true就好了。具体操作如下:

找到nacos源码中的console模块的Nacos类,如下:

在这里插入图片描述

在这里插入图片描述

至此启动成功。

在这里插入图片描述

三. 源码分析

为什么要这样来启动才不会报错呢?以下从源码级别来讲解。

概要思路: 从main函数开始debug,main里面调用了run方法,一直debug,会来到一个非常关键的environmentPrepared()方法,它所在的类是StartingSpringApplicationRunListener

environmentPrepared()方法如下(这里只给出最核心的代码,其余无关的逻辑代码省略):

@Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        ApplicationUtils.injectEnvironment(environment);
        if (ApplicationUtils.getStandaloneMode()) {
            System.setProperty(MODE_PROPERTY_KEY_STAND_MODE, "stand alone");
        } else {
            System.setProperty(MODE_PROPERTY_KEY_STAND_MODE, "cluster");
        }
        // 。。。其余逻辑代码
    }

解释:从上面可以看到,如果getStandaloneMode()为真则以单机模式启动,否则默认以集群模式启动nacos

为什么启动时要配置nacos.standalone=true与上面代码块中的getStandaloneMode()有关。

getStandaloneMode()方法如下:

 /**
     * Standalone mode or not
     */
    public static boolean getStandaloneMode() {
        if (Objects.isNull(isStandalone)) {
            isStandalone = Boolean.getBoolean(Constants.STANDALONE_MODE_PROPERTY_NAME);
        }
        return isStandalone;
    }

解释:getBoolean(name)方法,其底层调用的是System.getProperty(name),即获取指定name的系统输入

STANDALONE_MODE_PROPERTY_NAME的值如下:

/**
     * The System property name of  Standalone mode.
     */
    String STANDALONE_MODE_PROPERTY_NAME = "nacos.standalone";

解释:从上面的两个代码块,可以知道 只有配置了nacos.standalone=truegetStandaloneMode()方法才返回true,才能以单机模式启动。

四. 延申知识

  1. ApplicationUtils有许多关于nacos系统配置的方法,在里面都可以大概了解如何用源码配置nacos
  2. StartingSpringApplicationRunLinstener做了很多在启动nacos前要做的预处理工作
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐