全部笔记All notes

Nexus 3 企业级仓库管理完整实践指南

阅读 15m 49s15m 49s read

img

Nexus 3 企业级仓库管理完整实践指南

概述

Nexus 3 是一款由 Sonatype 公司开发的强大仓库管理平台,为企业提供统一的软件制品管理解决方案。

主要特性

  1. 多格式支持

    • Maven/Gradle (Java)
    • npm (JavaScript)
    • PyPI (Python)
    • Docker
    • NuGet (.NET)
    • RubyGems
    • Raw repositories
  2. 企业级功能

    • 高可用集群部署
    • 细粒度权限控制
    • 自动清理策略
    • 审计日志
    • REST API
  3. 性能优化

    • 智能代理缓存
    • 并发下载支持
    • 存储优化
    • 元数据索引

应用场景

  • 依赖管理:统一管理企业内部所有依赖包
  • 私有仓库:托管企业私有组件和制品
  • 代理加速:缓存公共仓库,提升下载速度
  • 安全控制:扫描和控制依赖包的安全性
  • 版本管理:管理软件制品的生命周期

Nexus 3 安装部署

Docker方式安装

1. 单机部署

x86-64架构:

# 创建数据目录
mkdir -p /data/nexus-data
chmod 777 /data/nexus-data

# 启动容器
docker run -d \
  --name nexus \
  --restart=always \
  -p 8081:8081 \
  -v /data/nexus-data:/nexus-data \
  sonatype/nexus3:latest

ARM架构(M1/M2 Mac):

docker run -d \
  --name nexus \
  --restart=always \
  -p 8081:8081 \
  -p 8082:8082 \
  -p 8083:8083 \
  -v /data/nexus-data:/nexus-data \
  klo2k/nexus3:latest
2. Docker Compose部署
version: '3.8'
services:
  nexus:
    image: sonatype/nexus3:latest
    container_name: nexus
    restart: always
    ports:
      - "8081:8081"      # Nexus UI
      - "8082:8082"      # Docker group
      - "8083:8083"      # Docker hosted
    volumes:
      - nexus-data:/nexus-data
    environment:
      - INSTALL4J_ADD_VM_PARAMS=-Xms2g -Xmx2g -XX:MaxDirectMemorySize=3g
    networks:
      - nexus-net

volumes:
  nexus-data:

networks:
  nexus-net:
    driver: bridge

传统方式安装

1. 下载安装包
# 下载最新版本
wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz

# 解压
tar -zxvf latest-unix.tar.gz
mv nexus-3.* /opt/nexus
mv sonatype-work /opt/
2. 配置系统服务
# 创建nexus用户
useradd nexus
chown -R nexus:nexus /opt/nexus /opt/sonatype-work

# 创建systemd服务
cat > /etc/systemd/system/nexus.service << EOF
[Unit]
Description=Nexus Repository Manager
After=network.target

[Service]
Type=forking
LimitNOFILE=65536
User=nexus
Group=nexus
ExecStart=/opt/nexus/bin/nexus start
ExecStop=/opt/nexus/bin/nexus stop
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

# 启动服务
systemctl daemon-reload
systemctl enable nexus
systemctl start nexus

高可用部署

1. 使用外部数据库
# config.properties
nexus.datastore.enabled=true
nexus.datastore.nexus.jdbcUrl=jdbc:postgresql://db-host:5432/nexus
nexus.datastore.nexus.username=nexus
nexus.datastore.nexus.password=secret
2. 配置负载均衡
upstream nexus_backend {
    server nexus1:8081;
    server nexus2:8081;
    server nexus3:8081;
}

server {
    listen 80;
    server_name nexus.example.com;
    
    client_max_body_size 1G;
    
    location / {
        proxy_pass http://nexus_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

初始化配置

1. 访问界面

通过浏览器访问 http://localhost:8081

image-20231227152301705

2. 获取初始密码

image-20231227154319306

点击页面右上角的”Sign in”,按弹窗提示找到默认密码

  • 默认账号:admin
  • 默认密码:容器内的 “/nexus-data/admin.password”
  • 会提示重置密码,改个记得住的密码(或者用默认密码),后面配置需要用到

在命令行中使用下面的命令进行获取密码

docker exec nexus cat /nexus-data/admin.password
3. 安全配置

image-20231227152749263

默认开启匿名访问

image-20231227152900691

这就基本安装完成

image-20231227154643340

界面功能详解

主界面布局

右侧分为四个一级菜单分别是 Welcome Search Browse Upload

  • Welcome

    • 欢迎界面,展示仓库的数据

    • Total components : 总组件数量

    • Unique logins : 登录数量(30天内)

    • Peak requests per minute : 每分钟峰值请求(24小时内)

    • Peak requests per day : 每天的峰值请求(30天内)

image-20231227172644727

  • Search

    • 用于在所有仓库中,搜索是否存在某个jar包(依赖)
    • Group(组织):如果我们想搜索 Spring Framework 的构件,可以使用 group:org.springframework 进行查询。
    • Artifact(构件):如果我们想搜索 Spring Framework 的 web 模块,可以使用 artifact:spring-web 进行查询。
    • Version(版本):如果我们想搜索 Spring Framework 版本为 5.3.10.RELEASE 的构件,可以使用 version:5.3.10.RELEASE 进行查询。另外,如果想模糊匹配多个版本,可以使用通配符 ,例如 version:5.3. 可以匹配到所有 5.3.x 版本。
    • Base Version(基本版本):如果我们想搜索 Spring Framework 的 SNAPSHOT 版本,可以使用 baseVersion:5.3.11-SNAPSHOT 进行查询。这样就可以忽略掉 SNAPSHOT 部分,只匹配基本版本号为 5.3.11 的构件。
    • Classifier(分类器):如果我们想搜索 Spring Framework 的 Windows 版本构件,可以使用 classifier:windows 进行查询。另外,有些 Maven 项目会为不同的环境打包不同的构件,例如 dev、test、prod 等,可以使用 classifier 进行搜索。
    • Extension(扩展名):如果我们只想搜索 jar 文件,可以使用 extension:jar 进行查询。另外,如果我们想搜索所有类型的构件,可以省略该查询条件,默认会搜索所有扩展名的文件。

  • Browse
    • 检查该nexus私服拥有多少私有的仓库
    • maven-central 是一个代理仓库,它代表了 Maven 中央仓库,它是默认的 Maven 仓库,包含了大量的开源 Java 类库和框架,可以改成国内代理,如阿里云(https://maven.aliyun.com/repository/public)
    • maven-public 是一个托管的仓库,它允许将自己的库发布到其中,并使其可供其他人使用。
    • maven-releases 是一个托管的仓库,用于发布稳定版本的库。
    • maven-snapshots 是一个托管的仓库,用于发布开发中或者测试版的库。

image-20231227172852084

  • Upload

    • 上传 jar 包到私有仓库
    • 点击仓库后可以进行上传 jar 包

image-20240102150816215

Maven仓库管理

仓库类型介绍

Nexus 3支持三种Maven仓库类型:

  1. Hosted Repository(宿主仓库)

    • 存储组织内部的私有构件
    • 分为releases和snapshots两种
    • 用于部署自己的jar包
  2. Proxy Repository(代理仓库)

    • 代理远程公共仓库
    • 缓存外部构件,加速下载
    • 可配置多个上游源
  3. Group Repository(仓库组)

    • 聚合多个仓库
    • 提供统一的访问入口
    • 简化客户端配置

配置Maven推送

1. 项目pom.xml配置
  • 直接改造Maven项目(或者新建一个Maven项目)
    • 执行”mvn package”能打包出jar的项目就行
    • 如下在pom.xml添加nexus3地址信息
      • 与dependencies/build同级
<dependencies>...略</dependencies>
<build>...略</build>

<distributionManagement>
    <repository>
        <id>maven-releases</id>
        <name>maven-releases</name>
        <url>${这里填写从nexus页面上复制的maven-releases的url}</url>
    </repository>
    <snapshotRepository>
        <id>maven-snapshots</id>
        <name>maven-snapshots</name>
        <url>${这里填写从nexus页面上复制的maven-snapshots的url}</url>
    </snapshotRepository>
</distributionManagement>

image-20240103151816700

  • 推送包
    • 执行 “mvn deoloy”
    • 此时报错 “…status: 401 Unauthorized”,说明项目配置正确
2. Maven settings.xml配置
  • 打开_${maven根目录}/conf/settings.xml_
    • 增加nexus账号密码
    • id要和在项目pom.xml中配置的一致
<servers>
    <server>
        <id>maven-releases</id>
        <username>admin</username>
        <password>${密码}</password>
    </server>
    <server>
        <id>maven-snapshots</id>
        <username>admin</username>
        <password>${密码}</password>
    </server>
</servers>

注意事项:

  • server的id必须与pom.xml中repository的id一致
  • 密码建议使用加密存储:mvn --encrypt-password
3. 执行部署命令
# 部署到仓库
mvn clean deploy

# 跳过测试部署
mvn clean deploy -DskipTests

# 部署指定文件
mvn deploy:deploy-file \
  -DgroupId=com.example \
  -DartifactId=my-app \
  -Dversion=1.0.0 \
  -Dpackaging=jar \
  -Dfile=target/my-app.jar \
  -DrepositoryId=maven-releases \
  -Durl=http://nexus-host:8081/repository/maven-releases/

版本规则:

  • 带-SNAPSHOT后缀的版本会上传到snapshots仓库
  • 不带后缀的版本会上传到releases仓库
  • releases仓库默认不允许重复上传相同版本

image-20240103152221677

image-20240103152112596

image-20240103152000386

配置Maven拉取

1. 配置镜像仓库

在settings.xml中配置Nexus作为中央仓库镜像:

<mirror>
    <id>nexus-public</id>
    <mirrorOf>*</mirrorOf>
    <name>私有仓库</name>
    <url>http://nexus-host:8081/repository/maven-public/</url>
</mirror>

高级配置(推荐):

<profiles>
  <profile>
    <id>nexus</id>
    <repositories>
      <repository>
        <id>nexus-public</id>
        <url>http://nexus-host:8081/repository/maven-public/</url>
        <releases><enabled>true</enabled></releases>
        <snapshots><enabled>true</enabled></snapshots>
      </repository>
    </repositories>
    <pluginRepositories>
      <pluginRepository>
        <id>nexus-public</id>
        <url>http://nexus-host:8081/repository/maven-public/</url>
        <releases><enabled>true</enabled></releases>
        <snapshots><enabled>true</enabled></snapshots>
      </pluginRepository>
    </pluginRepositories>
  </profile>
</profiles>

<activeProfiles>
  <activeProfile>nexus</activeProfile>
</activeProfiles>
2. 引入私有依赖

在项目pom.xml中正常引入依赖:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>mini-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

刷新依赖后的效果:

image-20240103152406703

刷新Maven后成功引入:

image-20240103152426226

私服最佳实践

1. 仓库组织结构
maven-public (仓库组)
├── maven-releases (hosted) # 正式版本
├── maven-snapshots (hosted) # 快照版本
├── maven-central (proxy) # 中央仓库代理
├── aliyun-public (proxy) # 阿里云代理
└── third-party (hosted) # 第三方jar包
2. 代理仓库优化

配置阿里云代理:

  1. 创建 proxy 仓库
  2. Remote Storage:https://maven.aliyun.com/repository/public
  3. 将其添加到 maven-public 组中
3. 清理策略配置
// 清理一年未使用的快照版本
repository.createCleanupPolicy(
    name: 'cleanup-maven-snapshots',
    format: 'maven2',
    mode: 'delete',
    criteria: [
        lastDownloaded: '365',
        isPrerelease: 'true'
    ]
)
4. 上传第三方jar包
# 上传Oracle JDBC驱动
mvn deploy:deploy-file \
  -DgroupId=com.oracle \
  -DartifactId=ojdbc8 \
  -Dversion=19.3.0.0 \
  -Dpackaging=jar \
  -Dfile=ojdbc8.jar \
  -DrepositoryId=third-party \
  -Durl=http://nexus:8081/repository/third-party/

Docker镜像仓库

创建Docker仓库

1. 创建Blob存储

为Docker镜像创建专用存储:

  1. 进入管理界面:Repository → Blob Stores
  2. Create Blob Store
  3. 配置参数:
    • Type:选择 File(本地存储)或 S3(云存储)
    • Name:docker-hub
    • Path:/nexus-data/blobs/docker-hub
    • Soft Quota:可选,设置存储配额告警

image-20240103161409621

2. 创建仓库实例

Nexus 3支持三种Docker仓库类型:

仓库类型说明:

类型说明使用场景
Docker (proxy)代理远程仓库,缓存Docker Hub镜像加速公共镜像下载
Docker (hosted)私有托管仓库存储企业内部镜像
Docker (group)仓库组,聚合多个仓库统一访问入口

配置镜像拉取

1. 创建代理仓库 Docker (proxy)

代理Docker Hub,加速镜像下载:

重要配置项:

  1. 基础配置

    • Name:docker-proxy
    • Online:勾选
    • HTTP:不配置(用于group)
    • Allow anonymous docker pull:勾选
  2. Proxy配置

    • Remote storage:https://registry-1.docker.io
    • Docker Index:Use Docker Hub
    • Auto blocking enabled:勾选
    • Maximum component age:1440(分钟)
    • Maximum metadata age:1440(分钟)
  3. Storage配置

    • Blob store:docker-hub
    • Strict Content Type Validation:勾选

国内镜像源推荐:

  • 网易镜像:https://hub-mirror.c.163.com
  • 中科大镜像:https://docker.mirrors.ustc.edu.cn
  • Docker中国:https://registry.docker-cn.com

image-20240103162218913

2. 创建主仓库 Docker (group)

创建仓库组,提供统一访问入口:

配置说明:

  1. 基础配置

    • Name:docker-public
    • HTTP:8082(对外服务端口)
    • Allow anonymous docker pull:勾选
    • Enable Docker V1 API:勾选
  2. Storage配置

    • Blob store:docker-hub
    • Strict Content Type Validation:勾选
  3. Group配置

    • Member repositories:
      • docker-proxy
      • docker-hosted(私有仓库)

image-20240103165831888

3. 启用Docker Realms

启用Docker相关的安全领域:

  1. Security → Realms
  2. 将以下Realms移动到Active:
    • Docker Bearer Token Realm
    • npm Bearer Token Realm(如果使用npm)

image-20240103170429111

4. 配置客户端Docker

Linux/Mac配置:

# 编辑Docker配置
vim /etc/docker/daemon.json

# 添加以下内容
{
    "insecure-registries": [
        "nexus-host:8082",
        "nexus-host:8083"
    ],
    "registry-mirrors": [
        "http://nexus-host:8082"
    ]
}

# 重启Docker
systemctl daemon-reload
systemctl restart docker

Windows Docker Desktop配置:

  1. 设置 → Docker Engine
  2. 添加上述JSON配置
  3. Apply & Restart

验证配置:

# 测试拉取镜像
docker pull nginx:latest

# 查看镜像信息
docker images
- Not found cache enabled 未找到启用的缓存,默认勾选
    - 用于启用或禁用 "Not Found Cache"
      功能。当启用此功能时,如果某个请求在仓库中未找到所需的内容(例如镜像或组件),仓库将会缓存这个"未找到"
      的结果。这样,当后续的请求再次发生时,仓库可以更快地响应,而不必重新执行相同的查询
- Not found cache TTL 未找到缓存TTL,默认1440
    - 指 "Not Found Cache" 功能中缓存的超时时间。一旦某个未找到的结果被缓存起来,在经过一段时间后(即 TTL
      时间)将会自动过期并从缓存中清除。
- Cleanup Policies 清理政策,不做更改
    - 用于定义清理操作的策略。它允许您指定仓库中过期或不再需要的镜像、组件或其他资源的自动清理规则。可以根据各种条件(例如最后访问时间、构建日期等)来定义清理政策,以确保仓库保持干净和高效。

配置镜像推送

配置镜像推送

1. 创建私有仓库Docker (hosted)

私有仓库用于存储企业内部镜像:

创建存储库:

  1. Repository → Blob Stores
  2. Create blob store
  3. 配置:
    • Type: File
    • Name: docker-private
    • Path: /nexus-data/blobs/docker-private

image-20240103231907873

创建仓库:

  1. Repository → Repositories
  2. Create repository → docker (hosted)
  3. 配置:
    • Name: docker-private
    • HTTP: 8083
    • Enable Docker V1 API: 勾选
    • Blob store: docker-private
    • Deployment Policy: Allow redeploy

image-20240103232044665

添加到仓库组:

  1. 编辑docker-public仓库
  2. 在Member repositories中添加docker-private
  3. 保存配置

image-20240103232319285

2. 配置权限管理

创建角色:

  1. Security → Roles
  2. Create role
  3. 配置:
    • Role ID: docker-developer
    • Role Name: Docker Developer
    • Privileges:
      • nx-repository-view-docker-docker-private-*
      • nx-repository-admin-docker-docker-private-*

image-20240103232509055

创建用户:

  1. Security → Users
  2. Create user
  3. 配置:
    • ID: docker-user
    • First Name: Docker
    • Last Name: User
    • Email: docker@example.com
    • Password: 设置密码
    • Status: Active
    • Roles: docker-developer

image-20240103233251898

3. 客户端配置与使用

Docker配置:

# 编辑Docker配置
vim /etc/docker/daemon.json

# 添加以下内容
{
    "insecure-registries": [
        "nexus-host:8082",  # 仓库组
        "nexus-host:8083"   # 私有仓库
    ],
    "registry-mirrors": [
        "http://nexus-host:8082"
    ]
}

# 重启Docker
systemctl daemon-reload
systemctl restart docker

镜像推送流程:

# 1. 登录私有仓库
docker login nexus-host:8083
Username: docker-user
Password: ********

# 2. 标记镜像
docker tag myapp:latest nexus-host:8083/myapp:latest
docker tag myapp:latest nexus-host:8083/myapp:v1.0.0

# 3. 推送镜像
docker push nexus-host:8083/myapp:latest
docker push nexus-host:8083/myapp:v1.0.0

# 4. 拉取镜像(从仓库组)
docker pull nexus-host:8082/myapp:latest

批量推送脚本:

#!/bin/bash
# push-images.sh

NEXUS_URL="nexus-host:8083"
IMAGES=("app1:latest" "app2:latest" "app3:latest")

# 登录
docker login $NEXUS_URL

# 批量推送
for image in "${IMAGES[@]}"; do
    docker tag $image $NEXUS_URL/$image
    docker push $NEXUS_URL/$image
done

image-20240103234013588

推送成功后在Nexus界面可以看到镜像:

image-20240103234244993

镜像清理策略

1. 创建清理策略
  1. Repository → Cleanup Policies
  2. Create Cleanup Policy
  3. 配置示例:

清理未使用的镜像:

Name: docker-cleanup-unused
Format: docker
Criteria:
  - Component Age: 30 days
  - Last Downloaded: 30 days

清理快照版本:

Name: docker-cleanup-snapshots
Format: docker
Criteria:
  - Name Matcher: .*-SNAPSHOT$
  - Component Age: 7 days
2. 应用清理任务
  1. System → Tasks
  2. Create task
  3. 选择“Cleanup service”
  4. 设置定时执行(如每天凌晨2点)

其他仓库类型

npm仓库

1. 创建npm仓库

代理仓库:

Name: npm-proxy
Remote Storage: https://registry.npmjs.org

私有仓库:

Name: npm-private
Deployment Policy: Allow redeploy

仓库组:

Name: npm-public
Members: npm-proxy, npm-private
2. 客户端配置
# 设置镜像
npm config set registry http://nexus-host:8081/repository/npm-public/

# 登录(发布需要)
npm login --registry=http://nexus-host:8081/repository/npm-private/

# 发布包
npm publish --registry=http://nexus-host:8081/repository/npm-private/

pypi仓库

1. 创建pypi仓库

代理仓库:

Name: pypi-proxy
Remote Storage: https://pypi.org

私有仓库:

Name: pypi-private
Deployment Policy: Allow redeploy
2. 客户端配置
# pip配置
mkdir -p ~/.pip
cat > ~/.pip/pip.conf << EOF
[global]
index-url = http://nexus-host:8081/repository/pypi-public/simple
trusted-host = nexus-host
EOF

# 上传包(使用twine)
pip install twine
twine upload --repository-url http://nexus-host:8081/repository/pypi-private/ dist/*

yum/apt仓库

yum仓库配置
# 创建仓库文件
cat > /etc/yum.repos.d/nexus.repo << EOF
[nexus]
name=Nexus Repository
baseurl=http://nexus-host:8081/repository/yum-proxy/
enabled=1
gpgcheck=0
EOF
apt仓库配置
# 添加仓库
echo "deb http://nexus-host:8081/repository/apt-proxy/ focal main" | \
  sudo tee /etc/apt/sources.list.d/nexus.list

权限管理

用户管理

1. 用户类型
  • 管理员:完全权限
  • 开发者:推送/拉取权限
  • 只读用户:仅拉取权限
  • 匿名用户:公开仓库访问
2. 角色配置示例

开发者角色:

Privileges:
- nx-repository-view-*-*-browse
- nx-repository-view-*-*-read
- nx-repository-view-*-*-add
- nx-repository-view-*-*-edit

只读角色:

Privileges:
- nx-repository-view-*-*-browse
- nx-repository-view-*-*-read

LDAP集成

1. 配置LDAP连接
  1. Security → LDAP
  2. Create Connection
  3. 配置参数:
    • Name: corporate-ldap
    • Protocol: ldaps
    • Hostname: ldap.company.com
    • Port: 636
    • Base DN: dc=company,dc=com
2. 用户映射
User Base DN: ou=users
User Object Class: inetOrgPerson
User ID Attribute: uid
Real Name Attribute: cn
Email Attribute: mail

备份与恢复

备份策略

1. 数据目录备份
#!/bin/bash
# backup-nexus.sh

BACKUP_DIR="/backup/nexus"
NEXUS_DATA="/data/nexus-data"
DATE=$(date +%Y%m%d_%H%M%S)

# 创建备份
tar -czf $BACKUP_DIR/nexus-backup-$DATE.tar.gz \
  -C $NEXUS_DATA .

# 保留最近7天备份
find $BACKUP_DIR -name "nexus-backup-*.tar.gz" \
  -mtime +7 -delete
2. 数据库备份
# 导出数据库
java -jar nexus-db-export.jar \
  --output=/backup/nexus-db-$DATE.sql
3. 恢复流程
  1. 停止Nexus服务
  2. 恢复数据目录
  3. 恢复数据库(如使用外部数据库)
  4. 启动Nexus服务
  5. 验证数据完整性

性能优化

JVM参数优化

# $NEXUS_HOME/bin/nexus.vmoptions
-Xms4g
-Xmx4g
-XX:MaxDirectMemorySize=6g
-XX:+UnlockDiagnosticVMOptions
-XX:+LogVMOutput
-XX:LogFile=../sonatype-work/nexus3/log/jvm.log
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-Djava.net.preferIPv4Stack=true

存储优化

  1. 使用SSD存储
  2. 分离不同类型仓库到不同磁盘
  3. 定期执行Compact Blob Store任务

网络优化

# Nginx代理优化
proxy_buffering off;
proxy_request_buffering off;
client_max_body_size 0;
proxy_http_version 1.1;
proxy_set_header Connection "";

监控与告警

监控指标

  1. 系统指标

    • CPU使用率
    • 内存使用率
    • 磁盘使用率
    • 网络流量
  2. 应用指标

    • 请求数/分钟
    • 响应时间
    • 错误率
    • 仓库大小

Prometheus集成

# prometheus.yml
scrape_configs:
  - job_name: 'nexus'
    metrics_path: '/service/metrics/prometheus'
    static_configs:
      - targets: ['nexus-host:8081']
    basic_auth:
      username: 'admin'
      password: 'admin-password'

常见问题

1. 登录问题

问题:Error 401 Unauthorized

解决:

  • 检查用户名密码
  • 检查用户状态
  • 检查Realms配置

2. 推送失败

问题:Error 413 Request Entity Too Large

解决:

# Nginx配置
client_max_body_size 5G;

3. 存储空间不足

解决:

  1. 执行Cleanup任务
  2. 执行Compact Blob Store
  3. 扩展存储空间
  4. 配置自动清理策略

4. 性能问题

优化建议:

  1. 增加JVM内存
  2. 使用SSD存储
  3. 启用CDN加速
  4. 优化网络带宽

相关文章