3819 words
19 minutes
Nacos Native Image

Language: English | 简体中文 | 繁體中文 | 日本語

Why Nacos needs GraalVM?#

Nacos (official site: nacos.io) is an easy-to-use platform designed for dynamic service discovery and configuration and service management. It helps you to build cloud native applications and microservices platform easily.

GraalVM Native Image is a new feature introduced with JDK 17 in Java, enabling Java code to be pre-compiled into a binary file—a native executable. A native executable only includes the code required at runtime, that is, application classes, standard library classes, the language runtime, and statically-linked native code from the JDK, to improve Java application startup and runtime efficiency.

With the maturity and promotion of Spring Boot 3, which supports Java native-image running, an increasing number of applications have begun to launch in the native-image form. The Nacos community has seen a surge in demands for Nacos to support Native Image execution, e.g., #9997, #11402, etc.

Therefore, the Nacos community hopes to enable both Nacos’s Java client and server to support native-image, to increase Nacos’s startup speed and run more efficiently while meeting the community’s needs.

Microservices Overview#

Technical Solution Evaluation#

Nacos has multiple modules and complex dependencies, so utilizing mvn dependency:tree for dependency analysis is essential. By excluding test modules and test-scope dependencies from the results, we can quickly identify the modules that require code upgrades for Spring and GraalVM.

Starting from Spring Boot 3.0, Spring Boot provides official support for GraalVM Native Image, which means the spring-native dependency is no longer required. Spring Boot 3.x includes built-in support for GraalVM Native Image, offering automatic configuration and optimizations, allowing Spring Boot applications to compile more easily into native binary files.

Upgrading the Spring Boot dependency in Nacos modules from version 2.7.18 to 3.3.1 is intended not only to enhance support for packaging and compiling the project as a GraalVM Native Image application but also to ensure that Nacos can continuously follow and support the next major version of Spring.

Spring Boot 3 Upgrade Process Details#

Upgrading the Spring Boot dependency version across Nacos modules is a complex process involving multiple aspects, including dependency management, code migration, testing, and validation. In our preliminary version update research, we have identified the following final versions of dependencies that need to be upgraded together:

ArchivePrev VerNext VerDescription
java1.817Minimum compatible Java version
spring-boot-dependencies2.7.183.3.1Dependencies related to SpringBoot
servlet-api3.06.1.0Dependencies related to Servlet
spring5.3.346.1.10Dependencies related to Spring
spring-security5.7.126.3.1Dependencies related to Spring Security
apache-http-components4.1.55.3.1Dependencies related to Apache HTTP Components
micrometer1.9.171.13.1Dependencies related to Micrometer
maven-pmd-plugin3.83.15.0Dependencies related to PMD
p3c-pmd1.3.02.1.1Dependencies related to P3C
maven-shade-plugin3.2.43.6.0Dependencies related to Maven Shade
grpc-java1.57.21.65.1Dependencies related to grpc
grpc-util-1.65.1Detach from grpc
grpc-inprocess-1.65.1Detach from grpc
findbugs-maven-plugin3.0.4-No longer support for jdk 17
soptbugs-maven-plugin-4.8.6.2Support JDK 17

Based on the completed dependency graph, we can further clarify the Spring-related dependencies, determine their hierarchical relationships, and establish the order for future updates.

SpringBoot Upgrade Order

GraalVM Adaptation Details#

Compared to the Java Virtual Machine, Native Image can provide efficient and sustainable hosting for various workloads, including microservices, cloud functions, containers, and Kubernetes. Using GraalVM Native Image allows Nacos to be packaged as a binary executable, promising significant improvements in startup and runtime performance.

Native Image has multiple implementation technologies, each with its own advantages and limitations. After comparison and evaluation, GraalVM was selected as the optimal choice for upgrading Nacos to support the Native Image startup mode.

  • GraalVM: A high-performance runtime that offers multi-language support and can compile Java applications into native executables. It provides efficient native compilation, good compatibility with existing Java tools and frameworks, and has strong community and documentation support.
  • Excelsior JET: A commercial Java SE runtime environment and optimizing compiler that compiles Java applications to native code. It offers AOT compilation to reduce startup time, enhanced security and code protection, and supports multiple platforms and operating systems.
  • Avian: A lightweight Java virtual machine designed for embedded devices and small systems, supporting the compilation of Java applications to native code. It’s lightweight, suitable for resource-constrained devices, supports AOT compilation, and, as an open-source project, offers flexible customization.
  • LLVM/Clang: Primarily used for C/C++ compilation, it also supports other languages. By compiling Java bytecode into LLVM IR, it can generate native code. It has powerful optimization and code generation capabilities, supports multiple languages, and boasts a rich ecosystem and toolchain support.

Our goal is to enable both nacos-client and nacos-console to support the Native Image startup mode, ultimately allowing upstream dependencies (such as nacos-spring-context, nacos-spring-context-aop, nacos-spring-samples, spring-cloud-starter-alibaba-nacos-config, etc.) to be packaged and run smoothly with Native Image. The current GraalVM Native Image-related issues in the Nacos repository are as follows:

  1. ISSUE#9997 Nacos client support for Spring Native: https://github.com/alibaba/nacos/issues/9997
  2. ISSUE#11402 Support a native Docker image: https://github.com/alibaba/nacos/issues/11402
  3. ISSUE#11790 No serializer found for class com.alibaba.nacos.common.remote.client.RpcClientTlsConfig (native-image run failed): https://github.com/alibaba/nacos/issues/11790
  4. ISSUE#11853 GraalVM support for nacos-client: https://github.com/alibaba/nacos/issues/11853
  5. ISSUE#11860 Update reflect-config.json: https://github.com/alibaba/nacos/pull/11860
  6. ISSUE#11861 [GraalVM] Use Spring Boot Maven Plugin generation hints files appeared warning info: https://github.com/alibaba/nacos/issues/11861
  7. ISSUE#11902 GraalVM Reachability Metadata Loss: https://github.com/alibaba/nacos/issues/11902
  8. ISSUE#12028 [Summer 2024] Nacos support for Java native-image runtime mode: https://github.com/alibaba/nacos/issues/12028

To date, part of the reflection metadata sampling work for Native Image startup in the Nacos Client has been completed (such as the merge of ISSUE#11860). Although these actions have shown some progress, they have yet to extend support to nacos-console or address new Native technology issues introduced by Spring Boot 3. These issues will be resolved in this ongoing work.

GraalVM Upgrade Order

Performance Report#

NOTE

In this performance report, the memory usage differences for all functions on the Native and Java platforms are comparable to the memory and thread count differences observed during startup. Therefore, memory usage and thread count during runtime are not tracked.

Standalone Mode#

Load Testing Environment:

  • OS: 10 cores, 6GB RAM, macOS aarch64, Apple Silicon.
  • Database: MySQL 8.0 on localhost.
  • Nacos Versions: 2.5.0-SNAPSHOT with Spring Boot 3, 2.5.0-SNAPSHOT Native.
ModuleFunction2.5.0-SNAPSHOT with Spring Boot 32.5.0-SNAPSHOT NativePerformance Comparison
StartupTime: 3800ms
CPU: 33.5%
Mem: 470MB
Threads: 300
Time: 48ms
CPU: 33.1%
Mem: 190MB
Threads: 298
Time: ↓98.73%
CPU: -
Mem: ↓59.57%
Threads: -
configQuery ConfigurationCPU: 35.62%
QPS: 12050
CPU: 29.94%
QPS: 12035
CPU: ↓15.95%
Publish ConfigurationCPU: 52.41%
QPS: 6733
CPU: 54.69%
QPS: 6784
CPU: ↑4.35%
namingRegister ServiceCPU: 25.64%
QPS: 7328
CPU: 29.43%
QPS: 7584
CPU: ↑14.78%
Query Service InstanceCPU: 33.59%
QPS: 7370
CPU: 27.8%
QPS: 7380
CPU: ↓17.24%

Cluster Mode#

Load Testing Environment:

  • Cluster Environment: 2 cores, 4GB RAM, ECS instance type ecs.e-c1m2.large, 3-node cluster.
  • SLB: slb.s2.small.
  • Database: MySQL.x2.xlarge.2c mysql5.7.
  • Nacos Versions: 2.5.0-SNAPSHOT with Spring Boot 3, 2.5.0-SNAPSHOT Native.
ModuleFunction2.5.0-SNAPSHOT with Spring Boot 32.5.0-SNAPSHOT NativePerformance Comparison
StartupTime: 12800ms
CPU: 33.52%
Time: 45ms
CPU: 46%
Time: ↓99.65%
CPU: ↑37.23%
configQuery ConfigurationCPU: 82%
QPS: 9981.96
CPU: 93.3%
QPS: 9980.2
CPU: ↑13.78%
Publish ConfigurationCPU: 73%
QPS: 802.18
CPU: 81.6%
QPS: 796.37
CPU: ↑11.78%
namingRegister ServiceCPU: 84.6%
TPS: 6986.14
CPU: 83.3%
TPS: 6982.12
CPU: ↓1.53%
Query Service InstanceCPU: 70.6%
QPS: 8991
CPU: 83%
QPS: 8982
CPU: ↑17.56%
Change PushCPU: 78.3%
TPS: 1197.67
CPU: 95.31%
TPS: 1192
CPU: ↑21.72%

Summary#

Compared to Java Nacos, Nacos Native generally consumes about 15% more CPU, reduces memory usage by approximately 50%, and shows little difference in thread count, TPS, and QPS. Its startup time is significantly shorter than Java Nacos.

How to compile Nacos Native?#

Manually with Maven#

If you prefer not to configure a complex GraalVM environment or address missing glibc-related libraries and simply want to quickly build a Nacos Native, then you should choose Docker for automated building. Before starting the build with Maven, you need to ensure that your local operating system meets the basic requirements for GraalVM compilation:

  1. Your operating system must have Oracle GraalVM JDK 17.0.12+8.1 installed, and the environment variables GRAALVM_HOME and JAVA_HOME must point to your GraalVM directory.
  2. Ensure your operating system is fully GNU-based rather than MUSL or any other variant.
  3. Ensure your Unix-based OS has the essential libraries installed, including: bzip2-devel, ed, gcc, gcc-c++, gcc-gfortran, gzip, file, fontconfig, less, libcurl-devel, make, openssl, openssl-devel, readline-devel, tar, glibc-langpack-en, vi, which, xz-devel, zlib-devel, findutils, glibc-static, libstdc++, libstdc++-devel, libstdc++-static, zlib-static.
  4. Verify that Maven version 9.0 or higher is installed on your machine.
  5. If you want to reduce build time, it is recommended to perform this task on a multi-core CPU with a high clock speed.

Here, we’ll use macOS(Apple Silicon) operating system that meets the above requirements as the demonstration environment. Clone the repository git@github.com:alibaba/nacos.git to your local machine and follow these steps to build Nacos Native with Maven:

  1. Navigate to your Nacos directory and switch to the branch summer-ospp#12028: git checkout summer-ospp#12028.

  2. Run the Maven install command: mvn clean install -DskipTests=true -Pnative -Pnative-osx-arm64 -Prelease-native.

    • If you are using another version of the OS or environment, please refer to the table below to select the appropriate profile and replace -Pnative-osx-arm64 in the command.

      OS FamilyArchProfile
      Linuxaarch64native-linux-aarch64
      ppc64lenative-linux-ppc64le
      s390xnative-linux-s390x
      x86native-linux32
      x64native-linux64
      OSXarm64native-osx-arm64
      x86_64native-osx-x86_64
      Windowsx64native-win64
  3. Wait for Maven to complete the Nacos Native Image build. This usually takes around 10 minutes, depending on your CPU performance. If you encounter any issues during the build process, feel free to submit an issue to the Nacos repository.

  4. Upon completion, the relevant files will be located in the distribution/target folder. If you want to package this executable yourself, copy the final build files from the console/target folder according to the corresponding operating system in the table below:

    OSRelated Files
    windowsnacos-server, libinstrument.dll
    unixnacos-server, libinstrument.so
    macosnacos-server

If Maven outputs logs similar to the following at the end, it indicates that your Nacos Native has been successfully built.

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Alibaba NACOS 2.5.0-SNAPSHOT 2.5.0-SNAPSHOT:
[INFO] 
[INFO] Alibaba NACOS 2.5.0-SNAPSHOT ....................... SUCCESS [02:08 min]
...
[INFO] nacos-console 2.5.0-SNAPSHOT ....................... SUCCESS [06:34 min]
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  11:12 min
[INFO] Finished at: 2024-10-30T09:08:11Z
[INFO] ------------------------------------------------------------------------
Build successful.
Copying build artifacts to /opt/output

Automatically with Docker#

Using Docker to build your Nacos Native Image is a more convenient choice, though it will still consume most of your CPU. We’ve set up a complete Docker container according to Oracle’s GraalVM Native Image build environment standards. With this container, you no longer need to configure a bulky and complex GraalVM Unix environment separately.

You can also customize this Dockerfile to select other modified Nacos Native Git repositories for compilation, and the container will automatically package and map the completed build to your specified directory where you want to retrieve the results. Everything is fully within your control.

You can directly pull the official image from Docker Hub or use the standard code from the Nacos Docker repository. Additionally, the source code for the Dockerfile is provided here for any developer to reference:

# usage of this Dockerfile:
# build image: docker build -f Dockerfile.builder -t nacos-native-builder:latest .
# run container: docker run -v /local/output:/opt/output --name nacos-native-builder nacos-native-builder:latest

# based on oracle linux 8 slim
ARG BASE_IMAGE=container-registry.oracle.com/os/oraclelinux:8-slim

FROM ${BASE_IMAGE}

LABEL maintainer="Moritz Clifford <me@biu.kim>"

# setup
ENV PS1="nacos-native-builder>" \
    GRAALVM_HOME="/opt/graalvm-jdk-17.0.12+8.1" \
    JAVA_HOME="/opt/graalvm-jdk-17.0.12+8.1" \
    PATH="/opt/graalvm-jdk-17.0.12+8.1/bin:$PATH"

RUN microdnf update -y oraclelinux-release-el8 \
    && microdnf --enablerepo ol8_codeready_builder install bzip2-devel ed gcc gcc-c++ gcc-gfortran gzip file fontconfig less libcurl-devel make openssl openssl-devel readline-devel tar glibc-langpack-en \
    vi which xz-devel zlib-devel findutils glibc-static libstdc++ libstdc++-devel libstdc++-static zlib-static wget git \
    && microdnf clean all

WORKDIR /opt

# setup GraalVM
RUN wget https://download.oracle.com/graalvm/17/latest/graalvm-jdk-17_linux-x64_bin.tar.gz -O graalvm.tar.gz && \
    mkdir -p /opt && \
    tar -xzf graalvm.tar.gz -C /opt && \
    rm graalvm.tar.gz && \
    ln -s /opt/graalvm-jdk-${GRAALVM_VERSION}/bin/java /usr/bin/java && \
    gu install native-image

# setup Maven 3.9
RUN wget https://downloads.apache.org/maven/maven-3/3.9.5/binaries/apache-maven-3.9.5-bin.tar.gz -O maven.tar.gz && \
    tar -xzf maven.tar.gz -C /opt && \
    rm maven.tar.gz && \
    ln -s /opt/apache-maven-3.9.5/bin/mvn /usr/bin/mvn

# clone nacos native git repo
RUN git clone https://github.com/alibaba/nacos.git && \
    cd nacos && \
    git checkout summer-ospp#12028

# generate build shell script
ADD bin/build.sh /opt/build.sh
ADD etc/settings.xml /root/.m2/settings.xml
RUN chmod +x /opt/build.sh

ENTRYPOINT ["sh","/opt/build.sh"]

In this Dockerfile, you can specify any configuration files, including the target repository, Maven settings, build scripts, Docker volumes, etc. In theory, this container will have the capability to build any GraalVM Native Image. However, as an example, here is a sample code for a build script (build.sh) using Nacos:

#!/bin/bash
set -x

# Ensure working directory is /opt/nacos
if [ "$(pwd)" != "/opt/nacos" ]; then
  echo "Not in /opt/nacos, switching to /opt/nacos"
  cd /opt/nacos || exit 1
fi

# Applying Maven
echo "Refreshing Maven and applying settings.xml..."
mvn clean --settings /root/.m2/settings.xml

# Set the output directory
OUTPUT_DIR="/opt/output"
mkdir -p "$OUTPUT_DIR"
echo "Output directory: $OUTPUT_DIR"

# Check for updates in the remote repository
REMOTE_REPO="summer-ospp#12028"
git fetch origin "$REMOTE_REPO"
LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse origin/"$REMOTE_REPO")

if [ "$LOCAL" != "$REMOTE" ]; then
  echo "Local branch is behind the remote branch. Pulling latest changes..."
  git pull origin "$REMOTE_REPO"
else
  echo "Local branch is up to date with the remote branch."
fi

# Execute Maven install
echo "Building nacos native..."
mvn clean install -DskipTests=true -Paliyun-maven -Pnative -Pnative-linux64

# Check build result and copy to output directory
if [ $? -eq 0 ]; then
  echo "Build successful."
  if [ -f "/opt/nacos/console/target/nacos-server" ] && [ -f "/opt/nacos/console/target/libinstrument.so" ]; then
    echo "Copying build artifacts to $OUTPUT_DIR"
    cp /opt/nacos/console/target/nacos-server "$OUTPUT_DIR"
    cp /opt/nacos/console/target/nacos-server.debug "$OUTPUT_DIR"
    cp /opt/nacos/console/target/libinstrument.so "$OUTPUT_DIR"
  else
    echo "Build artifacts not found."
  fi
else
  echo "Build failed."
fi

# Enter interactive bash shell after build process
exec /bin/bash

Run and test your Nacos Native#

Running and testing the built Nacos Native program is a crucial step for its subsequent usage. Below, the latest version of the Debian operating system (2C2G 50G) will be used as the demonstration environment to illustrate how to start Nacos Native in standalone and cluster modes.

As of now, Nacos Native cannot fully support the embedded Derby database mode. Therefore, during testing, you must ensure that a complete PostgreSQL or other database setup is available for Nacos to use.

Standalone Mode#

The startup method for Nacos Native Standalone is almost identical to the Java version, except that certain JVM optimization parameters are not available (as GraalVM operates differently from the JVM). Parameters specific to Nacos itself, however, still work effectively.

On Windows, you can start it by simply double-clicking the nacos-server.exe file. Additionally, here is a sample bash startup script for Debian as a reference.

#!/bin/bash
set -x

# Ensure working directory is /opt/nacos
if [ "$(pwd)" != "/opt/nacos" ]; then
  echo "Not in /opt/nacos, switching to /opt/nacos"
  cd /opt/nacos || exit 1
fi

# Define options
export SERVER="nacos-server"
export BASE_DIR="/opt/nacos"
export NACOS_HOME="${BASE_DIR}/home/"
export APP_DIR="${BASE_DIR}/application"
export LOGS_DIR="${APP_DIR}/logs"
export CUSTOM_DIR="file:${APP_DIR}/custom/"

# Create folders
mkdir -p "${NACOS_HOME}"
mkdir -p "${APP_DIR}/logs"
mkdir -p "${APP_DIR}/custom"

chmod -R +x "${BASE_DIR}"

# Define application options
APP_OPT="${APP_OPT} -Dnacos.standalone=true -Dnacos.home=${NACOS_HOME}"

if [ -f "${APP_DIR}/custom/application.properties" ]; then
  echo "Using custom application.properties."
  APP_OPT="${APP_OPT} --spring.config.additional-location=${CUSTOM_DIR}"
fi

# Start the application with nohup
echo "nacos native is starting. check the ${LOGS_DIR}/start.out"

nohup ./${SERVER} ${APP_OPT} nacos.nacos >> ${LOGS_DIR}/start.out 2>&1 &
NACOS_PID=$!

# Wait for the Nacos process to finish
wait $NACOS_PID
EXIT_CODE=$?

# If the Nacos process exits with an error code, terminate the container
if [ $EXIT_CODE -ne 0 ]; then
  echo "Nacos process exited with code $EXIT_CODE, stopping container..."
  exit $EXIT_CODE
fi

You can directly refer to the parameter explanations on the Nacos official website for Nacos parameters used in the startup script. After running this script (or mounting it as a daemon for continuous operation), if your console outputs logs similar to the ones below, it indicates that your Nacos Native has started successfully.

         ,--.
       ,--.'|
   ,--,:  : |                                           Nacos 
,`--.'`|  ' :                       ,---.               Running in stand alone mode, All function modules
|   :  :  | |                      '   ,'\   .--.--.    Port: 8848
:   |   \ | :  ,--.--.     ,---.  /   /   | /  /    '   Pid: 12
|   : '  '; | /       \   /     \.   ; ,. :|  :  /`./   Console: http://172.17.0.2:8848/nacos/index.html
'   ' ;.    ;.--.  .-. | /    / ''   | |: :|  :  ;_
|   | | \   | \__\/: . ..    ' / '   | .; : \  \    `.      https://nacos.io
'   : |  ; .' ," .--.; |'   ; :__|   :    |  `----.   \
|   | '`--'  /  /  ,.  |'   | '.'|\   \  /  /  /`--'  /
'   : |     ;  :   .'   \   :    : `----'  '--'.     /
;   |.'     |  ,     .-./\   \  /            `--'---'
'---'        `--`---'     `----'

2024-09-19T03:25:54.202Z  INFO 12 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8848 (http)
2024-09-19T03:25:54.205Z  INFO 12 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 37 ms
2024-09-19T03:25:55.504Z  WARN 12 --- [           main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with an AuthenticationProvider bean. UserDetailsService beans will not be used for username/password login. Consider removing the AuthenticationProvider bean. Alternatively, consider using the UserDetailsService in a manually instantiated DaoAuthenticationProvider.
2024-09-19T03:25:55.535Z  INFO 12 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
2024-09-19T03:25:55.643Z  INFO 12 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint beneath base path '/actuator'
2024-09-19T03:25:55.651Z  WARN 12 --- [           main] o.s.s.c.a.web.builders.WebSecurity       : You are asking Spring Security to ignore Deferred [Mvc [pattern='/**'], Ant [pattern='/**']]. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.
2024-09-19T03:25:55.651Z  WARN 12 --- [           main] o.s.s.c.a.web.builders.WebSecurity       : You are asking Spring Security to ignore Deferred [Mvc [pattern='/prometheus'], Ant [pattern='/prometheus']]. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.
2024-09-19T03:25:55.652Z  WARN 12 --- [           main] o.s.s.c.a.web.builders.WebSecurity       : You are asking Spring Security to ignore Deferred [Mvc [pattern='/prometheus/namespaceId/{namespaceId}'], Ant [pattern='/prometheus/namespaceId/{namespaceId}']]. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.
2024-09-19T03:25:55.652Z  WARN 12 --- [           main] o.s.s.c.a.web.builders.WebSecurity       : You are asking Spring Security to ignore Deferred [Mvc [pattern='/prometheus/namespaceId/{namespaceId}/service/{service}'], Ant [pattern='/prometheus/namespaceId/{namespaceId}/service/{service}']]. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.
2024-09-19T03:25:55.665Z  INFO 12 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8848 (http) with context path '/nacos'
2024-09-19T03:25:55.667Z  INFO 12 --- [           main] c.a.n.c.l.StartingApplicationListener    : Nacos started successfully in stand alone mode. use external storage
2024-09-19T03:26:21.080Z  INFO 12 --- [nio-8848-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2024-09-19T03:26:21.082Z  INFO 12 --- [nio-8848-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms

Nacos Native Standalone typically requires less than 100 milliseconds to start, which is a significant improvement compared to the 15-second startup time of Nacos on Spring Boot 2.

Cluster Mode#

Starting a Nacos Native Cluster is equally straightforward, requiring only slight modifications to the Standalone startup method. Let’s take an example of a three-node Nacos Native setup (each host configured with 2 CPU cores, 2GB RAM, and 50GB storage) and set to Hostname mode to start a cluster. Configure each node’s IP address in cluster.conf.

nacos1:8848
nacos2:8848
nacos3:8848

Here is a simple example of a bash script for each machine in a Nacos Native Cluster to start Nacos:

#!/bin/bash
set -x
export MEMBER_LIST=""
export SERVER="${BASE_DIR}/nacos-server"
export CUSTOM_SEARCH_LOCATIONS="file:${BASE_DIR}/conf/"
function print_servers() {
  echo "" >"$CLUSTER_CONF"
  for server in ${NACOS_SERVERS}; do
    echo "$server" >>"$CLUSTER_CONF"
  done
}

# Create folders
chmod -R +x "${BASE_DIR}"

# Define application options
print_servers
APP_OPT="${APP_OPT} -Dnacos.home=${BASE_DIR}"
APP_OPT="${APP_OPT} -Dnacos.member.list=${MEMBER_LIST}"
APP_OPT="${APP_OPT} --spring.config.additional-location=${CUSTOM_SEARCH_LOCATIONS}"

if [[ "${NACOS_START_MODE}" == "standalone" ]]; then
  APP_OPT="${APP_OPT} -Dnacos.standalone=true"
fi

if [[ ! -z "${NACOS_AUTH_ENABLE}" ]]; then
  APP_OPT="${APP_OPT} -Dnacos.core.auth.enabled=${NACOS_AUTH_ENABLE}"
fi

if [[ "${PREFER_HOST_MODE}" == "hostname" ]]; then
  APP_OPT="${APP_OPT} -Dnacos.preferHostnameOverIp=true"
fi

# Start the application
echo "Nacos native is now starting with ${NACOS_START_MODE} mode"
exec ${SERVER} ${APP_OPT}

You can use platforms like Docker Compose or Oracle VirtualBox to build this cluster service. Now, let’s start Nacos Native on these three servers. When each server’s terminal outputs logs similar to the following, it indicates that your Nacos cluster has started successfully.

         ,--.
       ,--.'|
   ,--,:  : |                                           Nacos 
,`--.'`|  ' :                       ,---.               Running in cluster mode, All function modules
|   :  :  | |                      '   ,'\   .--.--.    Port: 8848
:   |   \ | :  ,--.--.     ,---.  /   /   | /  /    '   Pid: 1
|   : '  '; | /       \   /     \.   ; ,. :|  :  /`./   Console: http://nacos1:8848/nacos/index.html
'   ' ;.    ;.--.  .-. | /    / ''   | |: :|  :  ;_
|   | | \   | \__\/: . ..    ' / '   | .; : \  \    `.      https://nacos.io
'   : |  ; .' ," .--.; |'   ; :__|   :    |  `----.   \
|   | '`--'  /  /  ,.  |'   | '.'|\   \  /  /  /`--'  /
'   : |     ;  :   .'   \   :    : `----'  '--'.     /
;   |.'     |  ,     .-./\   \  /            `--'---'
'---'        `--`---'     `----'

2024-09-20T13:35:03.946+08:00  INFO 1 --- [            main] c.a.n.c.l.StartingApplicationListener    : The server IP list of Nacos is [nacos1:8848, nacos2:8848, nacos3:8848]
2024-09-20T13:35:04.982+08:00  INFO 1 --- [nacos-starting.0] c.a.n.c.l.StartingApplicationListener    : Nacos is starting...
2024-09-20T13:35:05.846+08:00  INFO 1 --- [            main] c.a.n.c.l.StartingApplicationListener    : Nacos started successfully in cluster mode. use external storage

Even when the number of Nacos Native Cluster nodes reaches 15 or more, their startup time can still stay within 100 milliseconds, which is an astounding improvement compared to Nacos on Spring Boot 2.

Quick start for Nacos Native#

TIP

The quick start guide is intended to assist you in quickly setting up, deploying, and getting started with Nacos. The Nacos service set up via this guide operates in standalone mode without authentication enabled, and is recommended for testing purposes only. For production environments, it’s advised to deploy Nacos in cluster mode with authentication enabled to avoid risks to stability and security. Nacos is intended to be used as an internal data center (IDC) application component, not a publicly facing product. It is highly recommended to deploy Nacos within an isolated internal network. It is strongly discouraged to deploy Nacos in public network environments.

This quick start guide is designed to help you quickly download, install, and use Nacos Native Image on your computer.

System Requirements#

WARNING

If you intend to build Nacos Native on a Unix-based operating system, you must ensure that your OS is fully developed based on GNU rather than Musl or other frameworks.

Nacos Native is a version of Nacos built using the GraalVM, and it no longer depends on a separate JDK installation. Nacos Native currently provides executable files for Linux (GNU) and macOS. The current version of Nacos Native corresponds to Java Nacos version 2.5.0. Executable binaries can be downloaded from the corresponding release page. It is recommended to run Nacos Native on a complete 64-bit operating system that includes the libstdc++ library.

Download and Extract the Package#

After downloading the program package from the appropriate page, extract it and verify the files:

  1. On Linux operating systems, the extracted files should include the nacos-server binary, the libinstrument.so symlink, and other related configurations.
  2. On macOS, the extracted files should include the nacos-server binary and other related configurations.

If a Nacos Native version for other operating systems is not available, you can manually compile the source code on that operating system to obtain the Nacos Native binary package.

Starting the Server#

It is recommended to run Nacos Native on a machine with at least 1 CPU core, 2 GB of RAM, and 50 GB of storage. On Linux/Unix/macOS, you can start Nacos Native using the following command:

# standalone means running in single-node mode, not cluster mode
sh startup.sh -m standalone

If you want to start Nacos Native in cluster mode, make sure to have a cluster.conf file in the conf directory. This process is the same as with Java Nacos. After starting Nacos Native in cluster mode, it will automatically scan and retrieve the cluster IP addresses.

Stopping the Server#

To stop the Nacos Native server on Linux/Unix/macOS, use the following command:

sh shutdown.sh

Viewing logs#

For Linux/Unix operating systems, Nacos Native’s runtime logs are recorded in the /root/nacos/logs directory. The log structure is consistent with that of Java Nacos.

Contribute code to Nacos Native#

Contributors are welcomed to join Nacos project. Please check CONTRIBUTING about how to contribute to nacos main project.

For contributions to Nacos Native, you need to clarify the following points:

  1. Classes related to GraalVM’s initialize-at-build-time must be added under the buildArgs section of the native-maven-plugin in console/pom.xml, ensuring the structure of the parameters remains intact.
  2. Metadata not related to Spring Boot AOT should be configured as GraalVM’s initialize-at-run-time parameters. These should be added under buildArgs in the native-maven-plugin in console/pom.xml and in the corresponding metadata files under src/main/resources/META-INF/native-image/com.alibaba.nacos/nacos-console, ensuring the parameter structure remains intact.
  3. Metadata directly related to Spring Boot AOT should be placed in an appropriate location within the com.alibaba.nacos.console.aot.NacosRuntimeHints class, ensuring the parameter structure remains intact.
  4. If the metadata you are adding requires separate handling for GraalVM and Java environments, add the implementation logic to the com.alibaba.nacos.console.aot.AotConfiguration class.
alibaba
/
nacos
Waiting for api.github.com...
0K
0K
No License
Waiting...

Translation Contributions#

Nacos Native Image
https://biu.kim/posts/nacos/
Author
Moritz Arena
Published at
2024-10-31