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:
Archive | Prev Ver | Next Ver | Description |
---|---|---|---|
java | 1.8 | 17 | Minimum compatible Java version |
spring-boot-dependencies | 2.7.18 | 3.3.1 | Dependencies related to SpringBoot |
servlet-api | 3.0 | 6.1.0 | Dependencies related to Servlet |
spring | 5.3.34 | 6.1.10 | Dependencies related to Spring |
spring-security | 5.7.12 | 6.3.1 | Dependencies related to Spring Security |
apache-http-components | 4.1.5 | 5.3.1 | Dependencies related to Apache HTTP Components |
micrometer | 1.9.17 | 1.13.1 | Dependencies related to Micrometer |
maven-pmd-plugin | 3.8 | 3.15.0 | Dependencies related to PMD |
p3c-pmd | 1.3.0 | 2.1.1 | Dependencies related to P3C |
maven-shade-plugin | 3.2.4 | 3.6.0 | Dependencies related to Maven Shade |
grpc-java | 1.57.2 | 1.65.1 | Dependencies related to grpc |
grpc-util | - | 1.65.1 | Detach from grpc |
grpc-inprocess | - | 1.65.1 | Detach from grpc |
findbugs-maven-plugin | 3.0.4 | - | No longer support for jdk 17 |
soptbugs-maven-plugin | - | 4.8.6.2 | Support 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.
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:
- ISSUE#9997 Nacos client support for Spring Native: https://github.com/alibaba/nacos/issues/9997
- ISSUE#11402 Support a native Docker image: https://github.com/alibaba/nacos/issues/11402
- 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
- ISSUE#11853 GraalVM support for nacos-client: https://github.com/alibaba/nacos/issues/11853
- ISSUE#11860 Update reflect-config.json: https://github.com/alibaba/nacos/pull/11860
- ISSUE#11861 [GraalVM] Use Spring Boot Maven Plugin generation hints files appeared warning info: https://github.com/alibaba/nacos/issues/11861
- ISSUE#11902 GraalVM Reachability Metadata Loss: https://github.com/alibaba/nacos/issues/11902
- 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.
Performance Report
NOTEIn 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.
Module | Function | 2.5.0-SNAPSHOT with Spring Boot 3 | 2.5.0-SNAPSHOT Native | Performance Comparison |
---|---|---|---|---|
Startup | Time: 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: - | |
config | Query Configuration | CPU: 35.62% QPS: 12050 | CPU: 29.94% QPS: 12035 | CPU: ↓15.95% |
Publish Configuration | CPU: 52.41% QPS: 6733 | CPU: 54.69% QPS: 6784 | CPU: ↑4.35% | |
naming | Register Service | CPU: 25.64% QPS: 7328 | CPU: 29.43% QPS: 7584 | CPU: ↑14.78% |
Query Service Instance | CPU: 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.
Module | Function | 2.5.0-SNAPSHOT with Spring Boot 3 | 2.5.0-SNAPSHOT Native | Performance Comparison |
---|---|---|---|---|
Startup | Time: 12800ms CPU: 33.52% | Time: 45ms CPU: 46% | Time: ↓99.65% CPU: ↑37.23% | |
config | Query Configuration | CPU: 82% QPS: 9981.96 | CPU: 93.3% QPS: 9980.2 | CPU: ↑13.78% |
Publish Configuration | CPU: 73% QPS: 802.18 | CPU: 81.6% QPS: 796.37 | CPU: ↑11.78% | |
naming | Register Service | CPU: 84.6% TPS: 6986.14 | CPU: 83.3% TPS: 6982.12 | CPU: ↓1.53% |
Query Service Instance | CPU: 70.6% QPS: 8991 | CPU: 83% QPS: 8982 | CPU: ↑17.56% | |
Change Push | CPU: 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:
- Your operating system must have Oracle GraalVM JDK 17.0.12+8.1 installed, and the environment variables
GRAALVM_HOME
andJAVA_HOME
must point to your GraalVM directory. - Ensure your operating system is fully GNU-based rather than MUSL or any other variant.
- 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.
- Verify that Maven version 9.0 or higher is installed on your machine.
- 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:
Navigate to your Nacos directory and switch to the branch
summer-ospp#12028
:git checkout summer-ospp#12028
.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 Family Arch Profile Linux aarch64 native-linux-aarch64 ppc64le native-linux-ppc64le s390x native-linux-s390x x86 native-linux32 x64 native-linux64 OSX arm64 native-osx-arm64 x86_64 native-osx-x86_64 Windows x64 native-win64
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.
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 theconsole/target
folder according to the corresponding operating system in the table below:OS Related Files windows nacos-server, libinstrument.dll unix nacos-server, libinstrument.so macos nacos-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
TIPThe 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
WARNINGIf 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:
- On Linux operating systems, the extracted files should include the
nacos-server
binary, thelibinstrument.so
symlink, and other related configurations. - 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:
- Classes related to GraalVM’s
initialize-at-build-time
must be added under the buildArgs section of thenative-maven-plugin
inconsole/pom.xml
, ensuring the structure of the parameters remains intact. - Metadata not related to Spring Boot AOT should be configured as GraalVM’s
initialize-at-run-time
parameters. These should be added underbuildArgs
in thenative-maven-plugin
inconsole/pom.xml
and in the corresponding metadata files undersrc/main/resources/META-INF/native-image/com.alibaba.nacos/nacos-console
, ensuring the parameter structure remains intact. - 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. - 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.