化:內(nèi)網(wǎng)制品倉庫實(shí)戰(zhàn)指南)
簡(jiǎn)介Nexus Repository Manager 3.50.0-01 是面向 Windows 64 位系統(tǒng)的倉庫管理軟件主要服務(wù)于需要搭建 Maven 私服的開發(fā)團(tuán)隊(duì)與運(yùn)維人員用于統(tǒng)一存儲(chǔ)、發(fā)布和管理 Maven、npm、Docker 等構(gòu)建工具產(chǎn)出的軟件包。該版本在安全性與性能上做了強(qiáng)化提供細(xì)粒度權(quán)限控制以保障倉庫內(nèi)容完整并優(yōu)化了存儲(chǔ)與檢索速度從而提升構(gòu)建和部署效率。壓縮包共 690 個(gè)文件約 240.15MB以 419 個(gè) jar 核心庫、82 個(gè) dll 動(dòng)態(tài)鏈接庫、22 個(gè) exe 可執(zhí)行程序?yàn)橹鬏o以 xml、properties、cfg 等配置文件和少量 png、gif 圖標(biāo)資源整體結(jié)構(gòu)完整開箱即可部署。目前已有 494 人學(xué)習(xí)下載。借助該安裝包讀者可快速搭建本地 Maven 私服掌握倉庫權(quán)限配置、構(gòu)件上傳與依賴代理等實(shí)用技能為團(tuán)隊(duì)協(xié)作與持續(xù)集成提供穩(wěn)定支撐。1. 從一次內(nèi)網(wǎng)構(gòu)建翻車說起nexus-3.50.0-01-win64.zip 到底是什么上周幫一個(gè)做跨平臺(tái)系統(tǒng)的團(tuán)隊(duì)排查構(gòu)建問題現(xiàn)象很典型開發(fā)機(jī)npm install秒過CI 流水線卻卡在拉包上轉(zhuǎn)圈日志里全是超時(shí)。一查他們的私服 Nexus 還是三年前的老版本倉庫格式對(duì)不上新版的元數(shù)據(jù)協(xié)議緩存里一堆半截包。換上新版 Nexus 之后同樣的流水線一次跑通。這件事讓我重新翻出nexus-3.50.0-01-win64.zip這個(gè)包——它是 Sonatype Nexus Repository 3 的 Windows 64 位發(fā)行版版本號(hào) 3.50.0-01解壓即用自帶 JVM 依賴不需要你單獨(dú)裝 Java 環(huán)境。它能解決的核心問題就一個(gè)在內(nèi)網(wǎng)里當(dāng) Maven、npm、Docker、PyPI 等格式的制品倉庫把外網(wǎng)依賴緩存到本地讓構(gòu)建不再看公網(wǎng)臉色。適合誰做私有化部署的后端、DevOps、需要離線構(gòu)建的嵌入式團(tuán)隊(duì)以及被依賴下載速度折磨過的任何人。下面我按「裝起來 → 配明白 → 避坑 → 進(jìn)階」的順序把這份資源拆開講透。2. 解壓與啟動(dòng)把 Nexus 跑成 Windows 服務(wù)2.1 目錄結(jié)構(gòu)與啟動(dòng)腳本怎么選把 zip 解壓到任意目錄比如D:\nexus你會(huì)看到兩個(gè)頂層文件夾nexus-3.50.0-01是程序本體sonatype-work是數(shù)據(jù)目錄首次啟動(dòng)后生成。程序目錄里bin下有兩個(gè)關(guān)鍵腳本nexus.exe和nexus.bat。很多人第一次直接雙擊nexus.exe窗口一閃而過以為裝失敗了——其實(shí)它默認(rèn)是前臺(tái)運(yùn)行模式關(guān)掉窗口服務(wù)就停。正確做法是用命令行帶參數(shù)跑。# 進(jìn)入 bin 目錄 cd D:\nexus\nexus-3.50.0-01\bin # 前臺(tái)啟動(dòng)用于首次驗(yàn)證配置是否正確 nexus.exe /run # 安裝為 Windows 服務(wù)開機(jī)自啟 nexus.exe /install nexus-repo # 啟動(dòng)服務(wù) nexus.exe /start nexus-repo/run是前臺(tái)調(diào)試模式日志直接打在控制臺(tái)適合第一次確認(rèn)端口和路徑?jīng)]問題。/install后面跟的是服務(wù)名可以自定義不寫默認(rèn)叫nexus。服務(wù)方式啟動(dòng)后日志會(huì)落到sonatype-work\nexus3\log\nexus.log排查問題看這個(gè)文件比看控制臺(tái)靠譜。提示W(wǎng)indows 服務(wù)方式啟動(dòng)時(shí)默認(rèn)以 LocalSystem 賬戶運(yùn)行如果sonatype-work放在網(wǎng)絡(luò)盤或權(quán)限受限目錄會(huì)啟動(dòng)失敗。建議數(shù)據(jù)目錄放在本地 NTFS 盤并確保服務(wù)賬戶有讀寫權(quán)限。2.2 端口、JVM 內(nèi)存與數(shù)據(jù)目錄的改法Nexus 3.50 默認(rèn)監(jiān)聽 8081 端口JVM 堆內(nèi)存默認(rèn)給得比較保守。生產(chǎn)環(huán)境如果倉庫里包多、并發(fā)拉取頻繁不改內(nèi)存很容易 OOM。配置文件在nexus-3.50.0-01\etc\nexus-default.properties改完重啟服務(wù)生效。# 應(yīng)用上下文默認(rèn)根路徑反代到子路徑時(shí)才改 nexus-context-path/ # 監(jiān)聽端口被占用時(shí)改成 8082 等 application-port8081 application-host0.0.0.0 # 數(shù)據(jù)目錄默認(rèn)相對(duì)路徑建議改成絕對(duì)路徑 nexus-data-blobstore-pathD:/nexus-data/blobsJVM 參數(shù)不在這個(gè)文件里而在bin\nexus.vmoptions。把-Xms和-Xmx調(diào)大比如 4G 內(nèi)存的機(jī)器給 2G 堆-Xms2048m -Xmx2048m -XX:MaxDirectMemorySize2048mMaxDirectMemorySize容易被忽略Nexus 處理大文件上傳下載時(shí)會(huì)用堆外內(nèi)存這個(gè)值太小會(huì)報(bào)OutOfMemoryError: Direct buffer memory。改完參數(shù)后用nexus.exe /stop再/start重啟別直接殺進(jìn)程否則可能損壞 Lucene 索引。2.3 首次登錄與初始密碼在哪服務(wù)起來后瀏覽器訪問http://localhost:8081會(huì)提示初始密碼在sonatype-work\nexus3\admin.password文件里。復(fù)制出來登錄用戶名admin。登錄后第一件事是改密碼并禁用匿名訪問如果倉庫只對(duì)內(nèi)網(wǎng)特定團(tuán)隊(duì)開放。匿名訪問在Security → Anonymous里關(guān)關(guān)之前確認(rèn)所有客戶端都配了認(rèn)證否則 CI 會(huì)突然 401。3. 倉庫類型與代理配置讓構(gòu)建真正提速3.1 三種倉庫類型的選型邏輯Nexus 的倉庫分三類理解它們才能配得對(duì)類型作用典型場(chǎng)景proxy代理遠(yuǎn)程倉庫緩存到本地代理 Maven Central、npm registryhosted存放自己發(fā)布的制品內(nèi)部 jar 包、私有 npm 包group把多個(gè)倉庫聚合成一個(gè)入口統(tǒng)一對(duì)外暴露一個(gè) URL選型上有個(gè)常見誤區(qū)很多人只建 proxy 倉庫然后讓開發(fā)直接指向 proxy 的 URL。正確做法是建一個(gè) group把 proxy 和 hosted 都加進(jìn)去開發(fā)只配 group 的地址。這樣內(nèi)部包和外部包走同一個(gè)入口將來加倉庫不用改客戶端配置。3.2 配一個(gè) Maven 代理倉庫的完整步驟以代理 Maven Central 為例。登錄后進(jìn)Settings → Repositories → Create repository選maven2 (proxy)。關(guān)鍵參數(shù)Namemaven-central-proxyRemote storagehttps://repo1.maven.org/maven2/Version policyRelease快照另建一個(gè)Storage → Blob store默認(rèn) default量大時(shí)單獨(dú)建 blob storeHTTP → Connection settings超時(shí)設(shè) 30 秒以上內(nèi)網(wǎng)出口慢的話設(shè) 60建完再建一個(gè)maven2 (group)把剛建的 proxy 和一個(gè) hosted 加進(jìn)去順序上 hosted 放前面這樣同名包優(yōu)先走內(nèi)部??蛻舳藄ettings.xml里配 mirrormirror idnexus-group/id mirrorOf*/mirrorOf urlhttp://內(nèi)網(wǎng)IP:8081/repository/maven-group//url /mirrormirrorOf寫*表示所有倉庫請(qǐng)求都走 Nexus包括插件倉庫。這一步配完mvn clean package第一次會(huì)慢走公網(wǎng)回源之后命中緩存就是內(nèi)網(wǎng)速度。3.3 npm 與 Docker 倉庫的差異化配置npm 代理倉庫選npm (proxy)Remote storage 填https://registry.npmjs.org/??蛻舳伺鋘pm config set registry http://內(nèi)網(wǎng)IP:8081/repository/npm-group/。注意 npm 的 group 倉庫要把 proxy 和 hosted 都加進(jìn)去否則npm publish私有包會(huì)失敗。Docker 倉庫稍微特殊需要建三種docker (hosted)存內(nèi)部鏡像docker (proxy)代理 Docker Hubdocker (group)聚合。hosted 倉庫要勾選 HTTP 連接器并指定一個(gè)端口比如 8082因?yàn)?Docker 客戶端不認(rèn) 8081 上的路徑前綴。配完daemon.json里加insecure-registries然后docker pull才會(huì)走 Nexus。注意Docker proxy 首次拉取大鏡像時(shí)Nexus 會(huì)先完整下載再轉(zhuǎn)發(fā)客戶端可能卡在Pulling很久。這是正?;卦葱袨椴皇强ㄋ揽?Nexus 日志能看到下載進(jìn)度。4. 避坑與排查那些讓我加班到凌晨的坑4.1 啟動(dòng)報(bào)端口占用但 netstat 查不到現(xiàn)象nexus.exe /run報(bào)Address already in use但netstat -ano | findstr 8081什么都沒有。原因通常是 Windows 的http.sys或某個(gè)服務(wù)預(yù)留了端口范圍Nexus 綁不上。解決換端口或者用netsh int ipv4 show excludedportrange protocoltcp查預(yù)留段避開它。我一般直接把端口改成 8082 以上省得糾纏。4.2 上傳大包時(shí) 413 或超時(shí)現(xiàn)象mvn deploy傳一個(gè) 200MB 的 fat jar報(bào) 413 或連接重置。原因是 Nexus 前面的反向代理如果有限制了 body 大小或者 Nexus 自身的nexus-default.properties里沒調(diào)上傳限制。解決反代層調(diào)client_max_body_sizeNexus 層確認(rèn)nexus-data-blobstore-path所在磁盤有足夠空間并且nexus.vmoptions里MaxDirectMemorySize夠大。內(nèi)網(wǎng)直連的話檢查是不是走了 group 倉庫的 hosted 子倉庫路徑別配錯(cuò)。4.3 清理策略誤刪了還在用的包現(xiàn)象配了 Cleanup Policy 定時(shí)清理未使用的快照結(jié)果某個(gè)老項(xiàng)目的構(gòu)建突然拉不到包。原因是清理策略按「最后下載時(shí)間」判斷老項(xiàng)目半年沒構(gòu)建包被判定為未使用刪掉了。解決清理策略只對(duì) snapshot 倉庫啟用release 倉庫別開自動(dòng)清理或者把保留天數(shù)設(shè)長(zhǎng)比如 180 天。血淚經(jīng)驗(yàn)是清理任務(wù)第一次跑之前先手動(dòng)跑一次 dry-runNexus 3.50 支持預(yù)覽確認(rèn)要?jiǎng)h的列表里沒有關(guān)鍵包。4.4 服務(wù)重啟后索引損壞現(xiàn)象直接taskkill殺 Nexus 進(jìn)程后重啟倉庫列表空白或搜索報(bào)錯(cuò)。原因是 Lucene 索引在寫入時(shí)被強(qiáng)殺文件損壞。解決永遠(yuǎn)用nexus.exe /stop停服務(wù)等進(jìn)程完全退出再操作。已經(jīng)損壞的話停服務(wù)后刪掉sonatype-work\nexus3\db\下的索引目錄重啟會(huì)重建但歷史搜索記錄會(huì)丟包本身還在 blob store 里不影響拉取。4.5 匿名訪問關(guān)閉后 CI 全線 401現(xiàn)象為了安全關(guān)了匿名訪問結(jié)果 Jenkins 流水線全掛。原因是 CI 的settings.xml或.npmrc里沒配認(rèn)證。解決在 Nexus 里建一個(gè)專用只讀賬號(hào)給 CI 用密碼寫進(jìn) CI 的憑據(jù)管理別硬編碼在腳本里。改配置前先在測(cè)試流水線驗(yàn)證別直接動(dòng)生產(chǎn)。5. 進(jìn)階用腳本批量初始化倉庫與驗(yàn)證緩存命中手動(dòng)點(diǎn)界面建倉庫建到第五個(gè)就想砸鍵盤。Nexus 3.50 提供了 REST API可以用腳本批量創(chuàng)建。下面這段 Python 用requests調(diào) API先建 blob store再建 proxy 和 group適合新環(huán)境初始化。import requests from requests.auth import HTTPBasicAuth BASE http://localhost:8081/service/rest/v1 AUTH HTTPBasicAuth(admin, 你的新密碼) # 建 blob store量大時(shí)單獨(dú)隔離 blob { name: maven-blob, path: D:/nexus-data/blobs/maven, softQuota: {type: spaceRemainingQuota, limit: 10737418240} } r requests.post(f{BASE}/blobstores/file, jsonblob, authAUTH) print(blobstore:, r.status_code) # 建 maven proxy proxy { name: maven-central-proxy, online: True, storage: {blobStoreName: maven-blob, strictContentTypeValidation: True}, proxy: { remoteUrl: https://repo1.maven.org/maven2/, contentMaxAge: 1440, metadataMaxAge: 1440 }, negativeCache: {enabled: True, timeToLive: 1440}, httpClient: {connection: {retries: 3, timeout: 60}} } r requests.post(f{BASE}/repositories/maven/proxy, jsonproxy, authAUTH) print(proxy:, r.status_code) # 建 group把 proxy 加進(jìn)去 group { name: maven-group, online: True, storage: {blobStoreName: maven-blob, strictContentTypeValidation: True}, group: {memberNames: [maven-central-proxy]} } r requests.post(f{BASE}/repositories/maven/group, jsongroup, authAUTH) print(group:, r.status_code)contentMaxAge是緩存元數(shù)據(jù)的有效期分鐘設(shè) 1440 表示一天內(nèi)不再回源檢查更新內(nèi)網(wǎng)穩(wěn)定后可以調(diào)大。negativeCache是拉不到的包也緩存一段時(shí)間防止反復(fù)回源拖慢構(gòu)建。retries和timeout按出口網(wǎng)絡(luò)質(zhì)量調(diào)出口差就加大。建完怎么驗(yàn)證緩存真的生效第一次mvn dependency:resolve后看 Nexus 的Browse里對(duì)應(yīng)路徑下有沒有文件或者直接看sonatype-work\nexus3\blobs\maven-blob\目錄大小在漲。更直接的辦法是斷掉外網(wǎng)再跑一次構(gòu)建能過就說明緩存命中。我習(xí)慣在初始化腳本最后加一個(gè)curl檢查 group 倉庫的maven-metadata.xml是否返回 200作為冒煙測(cè)試。從那以后我每次部署新 Nexus都強(qiáng)制走一遍「前臺(tái)啟動(dòng)驗(yàn)證 → 改 JVM 參數(shù) → 腳本建倉庫 → 斷網(wǎng)構(gòu)建驗(yàn)證」這四步再也沒在半夜被 CI 報(bào)警叫醒過。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取