Language: English | 简体中文 | 繁體中文 | 日本語
為什麼Nacos需要GraalVM?
Nacos(官方網站:nacos.io)是一個易於使用的平台,專為動態服務發現、配置管理和服務管理而設計。它可以幫助您輕鬆構建雲原生應用程式和微服務平台。
GraalVM Native Image 是隨著 Java 的 JDK 17 推出的新功能,允許 Java 程式碼預先編譯為二進位檔案(即本機執行檔)。本機執行檔僅包含運行時所需的程式碼,即應用程式類別、標準庫類別、語言運行時和來自 JDK 的靜態鏈接原生程式碼,以提升 Java 應用程式的啟動和運行效率。
隨著支援 Java Native Image 運行的 Spring Boot 3 的成熟和推廣,越來越多的應用程式以本機執行檔形式推出。在 Nacos 社群中,也出現了對 Nacos 支援 Native Image 運行的需求激增的情況,例如 #9997、#11402 等。
因此,Nacos 社群希望實現 Nacos 的 Java 客戶端和服務端同時支援 Native Image,以提高 Nacos 的啟動速度,並在滿足社群需求的同時更高效地運行。
微服務概述
技術解決方案評估
Nacos 包含多個模組和複雜的依賴關係,因此使用 mvn dependency:tree
進行依賴分析是必要的。通過從結果中排除測試模組和測試範疇的依賴,可以快速識別需要進行 Spring 和 GraalVM 代碼升級的模組。
自 Spring Boot 3.0 起,Spring Boot 正式支援 GraalVM Native Image,這意味著不再需要 spring-native
依賴。Spring Boot 3.x 包含對 GraalVM Native Image 的內建支援,提供自動配置和優化,使 Spring Boot 應用程式更易於編譯為本機二進位檔案。
將 Nacos 模組中的 Spring Boot 依賴從 2.7.18 升級到 3.3.1 的目的是不僅增強將專案打包並編譯為 GraalVM Native Image 應用程式的支援,還確保 Nacos 能夠持續跟隨並支援 Spring 的下一個主要版本。
Spring Boot 3 升級流程詳細說明
在 Nacos 模組中整體升級 Spring Boot 依賴版本是一個包含多個方面的複雜過程,包括依賴管理、代碼遷移、測試和驗證。在我們的初步版本更新研究中,已確認需要共同升級以下依賴的最終版本。
檔案 | 先前版本 | 下一版本 | 說明 |
---|---|---|---|
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 |
根據完成的依賴圖,我們可以進一步明確 Spring 相關依賴關係,確定它們的階層關係,並確立未來更新的順序。
GraalVM 適應細節
與 Java 虛擬機相比,Native Image 可以為各種工作負載(包括微服務、雲函數、容器和 Kubernetes)提供高效且可持續的託管。使用 GraalVM Native Image 允許 Nacos 打包為二進位可執行文件,顯著提升啟動和運行性能。
Native Image 具有多種實現技術,每種技術各有優缺點。經過比較和評估,GraalVM 被選為升級 Nacos 以支援 Native Image 啟動模式的最佳選擇。
- GraalVM:一個高性能的運行時,提供多語言支持並可將 Java 應用程式編譯為本機可執行文件。它提供高效的本機編譯,與現有的 Java 工具和框架良好兼容,並擁有強大的社群和文件支援。
- Excelsior JET:商業化的 Java SE 運行時環境和優化編譯器,可將 Java 應用程式編譯為本機代碼。它提供 AOT 編譯以減少啟動時間,增強安全性和代碼保護,並支持多種平台和操作系統。
- Avian:專為嵌入式設備和小型系統設計的輕量級 Java 虛擬機,支持將 Java 應用程式編譯為本機代碼。它輕量且適用於資源受限設備,支持 AOT 編譯,作為開源專案可靈活定制。
- LLVM/Clang:主要用於 C/C++ 編譯,也支持其他語言。通過將 Java 位元組碼編譯為 LLVM IR,它可以生成本機代碼。具有強大的優化和代碼生成能力,支持多種語言,擁有豐富的生態系統和工具鏈支持。
我們的目標是讓 nacos-client
和 nacos-console
都能支援 Native Image 啟動模式,最終使上游依賴(例如 nacos-spring-context
、nacos-spring-context-aop
、nacos-spring-samples
、spring-cloud-starter-alibaba-nacos-config
等)可以順利地以 Native Image 形式打包和運行。Nacos 儲存庫中當前的 GraalVM Native Image 相關問題如下:
- ISSUE#9997 Nacos 客戶端支援 Spring Native: https://github.com/alibaba/nacos/issues/9997
- ISSUE#11402 支援本機 Docker 映像: https://github.com/alibaba/nacos/issues/11402
- ISSUE#11790 找不到 com.alibaba.nacos.common.remote.client.RpcClientTlsConfig 類的序列化器(native-image 運行失敗): https://github.com/alibaba/nacos/issues/11790
- ISSUE#11853 GraalVM 支援 nacos-client: https://github.com/alibaba/nacos/issues/11853
- ISSUE#11860 更新 reflect-config.json: https://github.com/alibaba/nacos/pull/11860
- ISSUE#11861 [GraalVM] 使用 Spring Boot Maven Plugin 生成的提示文件出現警告訊息: https://github.com/alibaba/nacos/issues/11861
- ISSUE#11902 GraalVM 可達性元數據遺失: https://github.com/alibaba/nacos/issues/11902
- ISSUE#12028 [2024年夏季] Nacos 支援 Java native-image 運行時模式: https://github.com/alibaba/nacos/issues/12028
迄今為止,Nacos 客戶端的部分 Native Image 啟動反射元數據採樣工作已完成(如 ISSUE#11860 的合併)。儘管這些行動已顯示出一些進展,但尚未擴展至 nacos-console
或解決 Spring Boot 3 引入的新 Native 技術問題。這些問題將在持續的工作中得到解決。
性能報告
在此性能報告中,所有功能在 Native 和 Java 平台上的內存使用差異可與啟動過程中觀察到的內存和線程數差異進行比較。因此,不會跟蹤運行時的內存使用和線程數。
單機模式
負載測試環境:
- 作業系統:10 核心,6GB RAM,macOS aarch64,Apple Silicon。
- 資料庫:本地 MySQL 8.0。
- Nacos 版本:2.5.0-SNAPSHOT 使用 Spring Boot 3、2.5.0-SNAPSHOT Native。
模組 | 功能 | 2.5.0-SNAPSHOT with Spring Boot 3 | 2.5.0-SNAPSHOT Native | 性能比較 |
---|---|---|---|---|
啟動 | 時間: 3800ms CPU: 33.5% 記憶體: 470MB Threads: 300 | 時間: 48ms CPU: 33.1% 記憶體: 190MB Threads: 298 | 時間: ↓98.73% CPU: - 記憶體: ↓59.57% Threads: - | |
config | 查詢配置 | CPU: 35.62% QPS: 12050 | CPU: 29.94% QPS: 12035 | CPU: ↓15.95% |
發佈配置 | CPU: 52.41% QPS: 6733 | CPU: 54.69% QPS: 6784 | CPU: ↑4.35% | |
naming | 註冊服務 | CPU: 25.64% QPS: 7328 | CPU: 29.43% QPS: 7584 | CPU: ↑14.78% |
查詢服務實例 | CPU: 33.59% QPS: 7370 | CPU: 27.8% QPS: 7380 | CPU: ↓17.24% |
集群模式
負載測試環境:
- 集群環境:2 核心,4GB RAM,ECS 實例類型 ecs.e-c1m2.large,3 節點集群。
- SLB:slb.s2.small。
- 資料庫:MySQL.x2.xlarge.2c mysql5.7。
- Nacos 版本:2.5.0-SNAPSHOT 使用 Spring Boot 3、2.5.0-SNAPSHOT Native。
模組 | 功能 | 2.5.0-SNAPSHOT with Spring Boot 3 | 2.5.0-SNAPSHOT Native | 性能比較 |
---|---|---|---|---|
啟動 | 時間: 12800ms CPU: 33.52% | 時間: 45ms CPU: 46% | 時間: ↓99.65% CPU: ↑37.23% | |
config | 查詢配置 | CPU: 82% QPS: 9981.96 | CPU: 93.3% QPS: 9980.2 | CPU: ↑13.78% |
發佈配置 | CPU: 73% QPS: 802.18 | CPU: 81.6% QPS: 796.37 | CPU: ↑11.78% | |
naming | 註冊服務 | CPU: 84.6% TPS: 6986.14 | CPU: 83.3% TPS: 6982.12 | CPU: ↓1.53% |
查詢服務實例 | CPU: 70.6% QPS: 8991 | CPU: 83% QPS: 8982 | CPU: ↑17.56% | |
變更推送 | CPU: 78.3% TPS: 1197.67 | CPU: 95.31% TPS: 1192 | CPU: ↑21.72% |
總結
與 Java Nacos 相比,Nacos Native 通常多消耗約 15% 的 CPU,內存使用量約減少 50%,線程數、TPS 和 QPS 幾乎無差異。其啟動時間顯著短於 Java Nacos。
如何編譯Nacos Native?
透過Maven手動構建
如果你不希望配置複雜的 GraalVM 環境、補齊缺少的 glic
相關的函式庫,只希望快速建置一個 Nacos Native 那麼你應該選擇使用 Docker 來自動建置。在使用 Maven 建置開始之前,你需要確保你的本機作業系統必須滿足 GraalVM 能編譯的基本環境:
- 你的作業系統必須安裝 Oracle GraalVM JDK 17.0.12+8.1,且必須讓環境變數
GRAALVM_HOME
和JAVA_HOME
指向 GraalVM 的目錄。 - 確保你的作業系統是完全基於 GNU 的,而不是 MUSL 或其他。
- 確保你的 Unix 類型的作業系統中裝有如下的基本函式庫: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-staticic。
- 確保你的電腦中安裝有 9.0 以上版本的 Maven。
- 如果你不希望編譯建置時間太長,推薦你在多核心且頻率較高的 CPU 上進行改工作。
這裡以符合上述條件的 macOS(Apple Silicon) 作業系統作為示範環境。將倉庫 git@github.com:alibaba/nacos.git
複製至本地,並按照以下的步驟來透過 Maven 建立 Nacos Native:
進入到你的 Nacos 目錄並切換至分支
summer-ospp#12028
:git checkout summer-ospp#12028
。使用 Maven 指令進行
install
:mvn clean install -DskipTests=true -Pnative -Pnative-osx-arm64 -Prelease-native
。如果你正在使用其他版本的作業系統或環境請參考如下的表格選擇你需要的 Profile 並取代參數中的
-Pnative-osx-arm64
進行建置。OS Family Arch Profile Linux aarch64 native-linux-aarch64 Linux ppc64le native-linux-ppc64le Linux s390x native-linux-s390x Linux x86 native-linux32 Linux x64 native-linux64 OSX arm64 native-osx-arm64 OSX x86_64 native-osx-x86_64 Windows x64 native-win64
等待你的 Maven 完成 Nacos Native Image 的建置工作,通常這需要 10 分鐘左右(具體時間需要依據你的 CPU 效能)。若建置過程中出現了異常歡迎提供 Issue 至 Nacos 倉庫。
建置完成後相關文件會被存放在
distribution/target
資料夾下,如果你希望自己封裝這個執行包那麼請按照以下作業系統對應的最終建立文件表格從console/target
資料夾中拷貝出來:OS Related Files windows nacos-server, libinstrument.dll unix nacos-server, libinstrument.so macos nacos-server
如果 Maven 在最後輸出類似以下的日誌,則表示您的 Nacos Native 已成功構建。
[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
透過Docker自動構建
使用 Docker 來建立你的 Nacos Native Image 是一個更方便的選擇,即便這還是會佔用你絕大部分的 CPU。我們按照 Oracle GraalVM Native Image 建構環境標準搭建了一套完備的 Docker 容器,借助於容器你不再需要單獨配置臃腫而複雜的 GraalVM Unix 環境,你還可以自訂這個 Dockerfile 來選擇其他經過修改的 Nacos Native 的 Git 倉庫進行編譯,同時這個容器也會自動將建置完成的程式全部打包映射到你指定的希望取得建置結果的目錄中,一切都由你自己決定。
你可以直接拉取Docker Hub (預計於 2025 年晚些時候推出) 中的官方映像或 Nacos Docker 倉庫中的標準代碼進行使用,同時這裡會直接給出 Dockerfile 與構建腳本的源代碼,以供任何開發者進行參考:
# 建構鏡像: docker build -f Dockerfile.builder -t nacos-native-builder:latest .
# 運行鏡像: docker run -v /local/output:/opt/output --name nacos-native-builder nacos-native-builder:latest
ARG BASE_IMAGE=container-registry.oracle.com/os/oraclelinux:8-slim
FROM ${BASE_IMAGE}
LABEL maintainer="Moritz Clifford <me@biu.kim>"
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
# 設定 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
# 設定 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
RUN git clone https://github.com/alibaba/nacos.git && \
cd nacos && \
git checkout summer-ospp#12028
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"]
在這個 Dockerfile 中你可以指定任何配置文件,包括:目標倉庫、Maven 配置、構建腳本、Docker Volume 等,理論上這個容器將具備構建任何 GraalVM Native Image 的能力,但這裡仍然以 Nacos 為例給出一個建置腳本(build.sh)的範例程式碼:
#!/bin/bash
set -x
if [ "$(pwd)" != "/opt/nacos" ]; then
echo "Not in /opt/nacos, switching to /opt/nacos"
cd /opt/nacos || exit 1
fi
echo "Refreshing Maven and applying settings.xml..."
mvn clean --settings /root/.m2/settings.xml
OUTPUT_DIR="/opt/output"
mkdir -p "$OUTPUT_DIR"
echo "Output directory: $OUTPUT_DIR"
# 自動拉取git分支進行更新
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
# 使用Maven進行install
echo "Building nacos native..."
mvn clean install -DskipTests=true -Paliyun-maven -Pnative -Pnative-linux64
# 將建置完成的文件拷貝到映射卷
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
exec /bin/bash
運行並測試Nacos Native
運行並測試構建完成的 Nacos Native 程式是其後續使用的重要步驟。以下將使用最新版本的 Debian 操作系統(2C2G 50G)作為演示環境,說明如何以單機模式和集群模式啟動 Nacos Native。
目前,Nacos Native 尚無法完全支援內嵌的 Derby 資料庫模式。因此,在測試期間,必須確保有完整的 PostgreSQL 或其他資料庫設置可供 Nacos 使用。
單機模式
Nacos Native 單機模式的啟動方式與 Java 版本幾乎相同,不同之處在於某些 JVM 優化參數無法使用(因為 GraalVM 的運作方式與 JVM 不同)。然而,Nacos 自身的特定參數仍能有效運作。
在 Windows 上,您可以通過雙擊 nacos-server.exe
文件來啟動。此外,以下提供一個用於 Debian 的範例 bash 啟動腳本以供參考。
#!/bin/bash
set -x
# 確保工作目錄為 /opt/nacos
if [ "$(pwd)" != "/opt/nacos" ]; then
echo "Not in /opt/nacos, switching to /opt/nacos"
cd /opt/nacos || exit 1
fi
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/"
# 建立資料夾
mkdir -p "${NACOS_HOME}"
mkdir -p "${APP_DIR}/logs"
mkdir -p "${APP_DIR}/custom"
chmod -R +x "${BASE_DIR}"
# 定義應用程式選項
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
# 使用 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=$!
# 等待 Nacos 進程完成
wait $NACOS_PID
EXIT_CODE=$?
# 如果 Nacos 進程退出並出現錯誤代碼,則終止容器
if [ $EXIT_CODE -ne 0 ]; then
echo "Nacos process exited with code $EXIT_CODE, stopping container..."
exit $EXIT_CODE
fi
您可以直接參考 Nacos 官方網站的參數說明 來了解在啟動腳本中使用的 Nacos 參數。在執行此腳本(或將其掛載為守護程式以持續運行)後,如果您的控制台輸出類似於以下的日誌,則表示您的 Nacos Native 已成功啟動。
,--.
,--.'|
,--,: : | 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 單機模式通常只需不到 100 毫秒即可啟動,這相比於基於 Spring Boot 2 的 Nacos 需要 15 秒的啟動時間有了顯著的提升。
集群模式
啟動 Nacos Native 集群同樣簡單,只需對單機模式的啟動方法進行少許修改。以下以三節點的 Nacos Native 設置為例(每個主機配置 2 個 CPU 核心、2GB RAM 和 50GB 存儲),並設置為主機名模式來啟動集群。在 cluster.conf
中配置每個節點的 IP 地址。
nacos1:8848
nacos2:8848
nacos3:8848
以下是用於 Nacos Native 集群中每臺機器啟動 Nacos 的簡單 bash 腳本範例。
#!/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
}
chmod -R +x "${BASE_DIR}"
# 定義應用程式選項
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
# 啟動應用程式
echo "Nacos native is now starting with ${NACOS_START_MODE} mode"
exec ${SERVER} ${APP_OPT}
您可以使用 Docker Compose 或 Oracle VirtualBox 等平台來構建此集群服務。現在,讓我們在這三個服務器上啟動 Nacos Native。當每個服務器的終端輸出類似以下的日誌時,則表示您的 Nacos 集群已成功啟動。
,--.
,--.'|
,--,: : | 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
即使 Nacos Native 集群節點數達到 15 個或更多,其啟動時間仍然能保持在 100 毫秒以內,這相比基於 Spring Boot 2 的 Nacos 來說是一個驚人的提升。
Nacos Native快速開始
NOTE此快速開始指南旨在協助您快速設置、部署並開始使用 Nacos。通過此指南設置的 Nacos 服務運行在單機模式下,未啟用身份驗證,僅建議用於測試目的。在生產環境中,建議將 Nacos 部署在集群模式並啟用身份驗證,以提高穩定性和安全性。 Nacos 是為內部數據中心(IDC)作為應用組件使用,並非面向公眾的產品。強烈建議在隔離的內部網路中部署 Nacos。強烈不建議將 Nacos 部署在公網環境。
此快速開始指南旨在幫助您快速在計算機上下載、安裝和使用 Nacos Native Image。
系統要求
如果您打算在基於 Unix 的操作系統上構建 Nacos Native,則必須確保您的操作系統是基於 GNU 完全開發的,而非 Musl 或其他框架。
Nacos Native 是使用 GraalVM 構建的 Nacos 版本,不再依賴於單獨的 JDK 安裝。Nacos Native 目前提供 Linux(GNU)和 macOS 的可執行文件。當前的 Nacos Native 版本對應 Java Nacos 版本 2.5.0。可執行的二進位文件可從相應的發行頁面下載。建議在包含 libstdc++
庫的完整 64 位操作系統上運行 Nacos Native。
下載並解壓縮程序包
從合適的頁面下載程序包後,解壓並驗證文件:
- 在 Linux 操作系統上,解壓後的文件應包括
nacos-server
二進位文件、libinstrument.so
符號鏈接和其他相關配置。 - 在 macOS 上,解壓後的文件應包括 nacos-server 二進位文件和其他相關配置。
如果沒有針對其他操作系統的 Nacos Native 版本,您可以在該操作系統上手動編譯源代碼以獲取 Nacos Native 二進位包。
啟動服務器
建議在至少具有 1 個 CPU 核心、2GB RAM 和 50GB 存儲的機器上運行 Nacos Native。在 Linux/Unix/macOS 上,可以使用以下命令來啟動 Nacos Native:
# standalone 表示以單節點模式運行,而非集群模式
sh startup.sh -m standalone
如果您想在集群模式下啟動 Nacos Native,請確保在 conf 目錄中有一個 cluster.conf
文件。此過程與 Java Nacos 相同。在集群模式下啟動 Nacos Native 後,它會自動掃描並檢索集群 IP 地址。
停止服務器
在 Linux/Unix/macOS 上停止 Nacos Native 服務器,可以使用以下命令:
sh shutdown.sh
查看日誌
對於 Linux/Unix 操作系統,Nacos Native 的運行時日誌記錄在 /root/nacos/logs
目錄中。日誌結構與 Java Nacos 一致。
如何參與Nacos Native貢獻?
非常歡迎每位開發者的貢獻和加入,無論是微不足道的清理或大的新功能。 Nacos 社群非常重視文件、與其他項目的集成,並欣然接受這些方面的改進。如果你希望為 Nacos Native Image 貢獻程式碼,請先參考《貢獻規約》後再參考本文的 Native Image 方面的規約進行貢獻。
在對 Nacos Native 進行貢獻時,您需要明確以下幾點:
- 與 GraalVM 的
initialize-at-build-time
相關的類必須添加到console/pom.xml
中native-maven-plugin
的buildArgs
區段,並確保參數結構保持完整。 - 與 Spring Boot AOT 無關的元數據應配置為 GraalVM 的
initialize-at-run-time
參數。這些參數應添加到console/pom.xml
中native-maven-plugin
的buildArgs
區段以及src/main/resources/META-INF/native-image/com.alibaba.nacos/nacos-console
下對應的元數據文件中,確保參數結構保持完整。 - 與 Spring Boot AOT 直接相關的元數據應放置在
com.alibaba.nacos.console.aot.NacosRuntimeHints
類中的適當位置,並確保參數結構保持完整。 - 如果您添加的元數據需要在 GraalVM 和 Java 環境中分別處理,請將實現邏輯添加到
com.alibaba.nacos.console.aot.AotConfiguration
類中。
相關程式碼倉庫
譯文貢獻者
- DerFrZocker:From Discord
- ultrakox:From Discord
- Sunny 陳:From X