☰
jre-11.0.10.zip实战:Java运行时安装部署与避坑指南
2026/10/16 22:36:58 网站建设 项目流程

简介:JRE 11 是从 JDK 11 中提取的精简运行环境,面向服务器资源紧张、只需运行 Java 11 应用的运维与开发人员。相比完整 JDK 的 279MB 占用,压缩包仅 56.27MB,解压后约 158MB,能有效降低磁盘与内存消耗,特别适合无图形界面的生产服务器、Docker 镜像制作或容器化部署场景。这份资源共包含 350 个文件,以 84 个 dll 动态链接库、40 个 exe 可执行文件为核心,同时保留 license、copyright 等合规文件,以及 security、policy、cacerts 等安全与证书配置,另有 modules、classlist、release 等关键元数据,目录结构完整,可直接解压后配置 JAVA_HOME 使用。目前已有 4215 人学习下载,适合需要快速获取轻量级 JRE 的服务器管理员。通过这份精简包,你可以避免安装完整 JDK 带来的冗余组件与潜在攻击面,降低维护成本,同时保留 Java 运行时所需的核心模块、时钟时区映射、字体配置等必要内容,开箱即用,让 Java 11 应用在受限环境中稳定运行。

1. jre-11.0.10.zip 不是装完就能跑的玩具:先搞清楚你在装什么

如果你以为拿到 jre-11.0.10.zip,解压完java -version出来版本号就算部署成功,那你很快就会在第一个真实服务上翻车。这个压缩包里确实是一套完整的 Java 运行时——启动器、核心类库、模块描述文件都在,但它没有安装器、没有注册表项、没有环境变量、没有开机自启的服务。所有“让系统认识它”的工作都留给你自己。更关键的是,11.0.10 这个版本正好卡在 Java 8 与 Java 11 的迁移分水岭上:老应用直接换运行时,大概率会撞上模块缺失、ClassNotFound 甚至 SSL 握手失败。这篇文章要解决的就是三件事:这包是什么、怎么装、装完踩坑怎么排。适合正在给项目统一运行时、做 Java 8 升 11 评估,或者准备把 JRE 直接打包进容器镜像的从业者。

2. 先弄清楚版本与形态:JRE 11、zip 分发和 JDK 到底差在哪

2.1 版本号怎么读:11.0.10 意味着什么

Java 的版本号从 9 开始换了规则:11 是特性版本,0 是安全更新版本,最后的 10 是这个安全更新序列里的补丁号。换句话说,11.0.10 是 Java 11 生命周期里比较靠后的一个稳定快照,发布于 2021 年初。它对外的行为和你现在去官网下的最新 Java 11 补丁几乎一致,但内部包含了截至发布时间点的全部安全修复和 bugfix。对一个生产团队来说,锁定一个具体补丁号是好事——11.0.10 之后的行为不会再漂移,升级与否完全由你决定。

很多人在这一步会混一个概念:拿到的是jre-11.0.10.zip,就以为运行时的版本号是“11.0.10”,编译器也是“11.0.10”。不对。JRE 里没有编译器,它只负责“跑”,不负责“编译”。你后面所有javac相关的操作都得回到 JDK 环境里完成。我见过有人把 JRE 当成 JDK 用,在服务器上敲了半天javac发现命令不存在,又去修改 PATH 指向隔壁目录,最后把两个运行时搞混。记住一条:JRE 的 bin 目录里,最重要的可执行文件是java(和 Windows 上的javaw),不是javac。

版本号还有个容易忽略的细节:java -version输出的第一行会写openjdk version "11.0.10"之类的内容,但第二行才是真正的运行模式信息。64 位与 32 位的差异也体现在这一行里,后文讲到架构坑的时候会再强调。这一行值得你养成瞄一眼的习惯,很多部署事故的预兆就在这里。

2.2 zip 分发 vs 安装器:解压型部署的适用边界

JRE 的二进制分发形态很多:Windows 上有安装向导,也有纯 zip;Linux 上有 tar.gz、rpm、deb 等。既然你这个文件的结尾是.zip,那就要搞清楚为什么有人愿意用 zip 而不是双击安装。

安装器的本质是“侵入”:写注册表、改 PATH、建立卸载条目、可能还会塞一个自动更新计划任务。好处是小白友好,坏处是在多用户环境、云主机镜像、CI 构建机上,这种侵入常常引发冲突——你装一个新版本,老版本的东西还留在 PATH 里,版本打架就成了必然。zip 分发则完全是“寄生式”:解压到哪个目录,运行时就跑在哪个目录;不写注册表,不碰系统 PATH 的默认值,所有配置都由你显式指定。这正是它在无管理员权限的部署场景里被大量使用的原因。

同时要认清边界:zip 分发不等于免配置。你至少要做四件事:确定安装目录、设置 JAVA_HOME、把bin目录加进 PATH、验证版本。容器化场景里,zip 的优势更明显——镜像构建时解压一次,目录结构完全可控,最终镜像里只需要保留那套目录和启动脚本。Linux 下也有人用 tar.gz,但从 Windows 团队接手过来的部署习惯,zip 反而是最不容易引起争议的格式。

2.3 JRE 与 JDK 的目录差异:包里到底有什么、缺什么

拿到 zip 后,我建议你先做一次“目录侦察”,不要急着配置。用下面这条命令看压缩包内部结构:

unzip -l jre-11.0.10.zip | head -30

unzip -l是列出内容而非解压。head -30只取前 30 行,目的是快速扫一眼顶层目录和典型文件。正常你会看到bin/、conf/、lib/、legal/这些顶层目录,以及一个描述构建信息的release文件。注意,这里不会看到javac,也不会看到 JDK 才有的jmods/、include/、src.zip。

解压后再看两个关键位置。第一个是bin/,它决定了你能执行什么命令;第二个是lib/,真正的运行时核心modules文件在这里,它把所有 JDK 模块打包成了一个镜像文件。conf/里是运行时配置,比如security/java.security、net.properties,这些在 Java 8 时代往往散落在不同位置,现在统一收进了conf目录。

unzip -q jre-11.0.10.zip -d /tmp/jre-check cat /tmp/jre-check/*/release | head -5

这里用通配符*是为了绕开“解压后顶层目录名不确定”的问题,不同渠道打出的包目录名可能有差异。release文件是纯文本,里面会直接写JAVA_VERSION="11.0.10",比java -version更快确认这个目录的真实版本。这个文件也是后面脚本化部署时用来做版本断言的首选。

2.4 该给应用配 JRE 还是 JDK:一个务实的判断标准

判断标准不复杂:如果你要在目标机器上编译代码、跑单元测试、用jstack、jmap、jcmd诊断线上问题,那就应该配 JDK;如果只是把一个已经构建好的 jar 包跑起来,JRE 完全够用,而且更省空间、攻击面更小。Java 9 之后 JDK 里不再单独塞一个jre子目录,运行时直接依托 JDK 模块镜像,所以你在 JDK 里也能跑应用,这导致很多人干脆“一律装 JDK”。

但从风险和可维护性看,生产环境给 JRE 单独留一个目录还是更清晰的做法。让应用只依赖一套最小运行时,避免开发人员在服务器上“顺手”改代码、重新编译,把生产环境搞成不可复现的状态。我见过不少团队,生产机器上既有 JDK 8 又有 JRE 11,PATH 里指向 JDK 8,JAVA_HOME 指向 JRE 11,两个变量互相打架,最后跑出来的进程根本不是你以为的那个版本。所以我的建议是:构建与编译固定在 JDK 环境,运行与部署固定在 JRE 目录,两者分开,互不污染。

3. 从压缩包到可用环境:Windows 与 Linux 两条完整安装路径

3.1 Windows 落地方案:解压、环境变量与首次验证

Windows 上的 zip 解压可以用图形界面,也可以直接用 PowerShell。考虑到部署要可重复,建议走命令行。下面这一段是针对用户级安装的完整操作:

$jreRoot = "C:\java" New-Item -ItemType Directory -Force -Path $jreRoot | Out-Null Expand-Archive -Path .\jre-11.0.10.zip -DestinationPath $jreRoot -Force $javaHome = Join-Path $jreRoot "jre-11.0.10" [Environment]::SetEnvironmentVariable("JAVA_HOME", $javaHome, "User") $currentPath = [Environment]::GetEnvironmentVariable("Path", "User") [Environment]::SetEnvironmentVariable("Path", "$javaHome\bin;$currentPath", "User")

第一行把安装根目录定为C:\java,New-Item -Force保证目录存在。Expand-Archive是解压动作,-Force处理目标目录已有内容的情况。紧接着设置用户级 JAVA_HOME,注意这里指向的是解压后的根目录,不是bin子目录。最后把$javaHome\bin追加到用户 PATH 的前面。SetEnvironmentVariable的第三个参数User表示只改当前用户的变量,不改系统级配置,这样避免触发 UAC 权限提示,也最安全。

新开的终端才会加载这些变量,当前窗口仍然是旧 PATH。验证时先开一个新的 PowerShell 窗口再执行:

echo $env:JAVA_HOME java -version

如果java还是指向旧版本,不要急,大概率是系统级 PATH 里已有的目录排在前面。可以用where.exe java查看当前解析到哪个路径,然后调整本脚本里 PATH 的拼接位置,或者干脆在命令里用绝对路径:C:\java\jre-11.0.10\bin\java -version。绝对路径验证,是摆脱所有环境变量干扰的终极手段。

3.2 Linux 落地方案:/opt 安置与命令接管

Linux 上的思路和 Windows 一致,但有一个路径差异:生产环境更推荐放到/opt下统一管理,脚本化也更方便。先解压到临时目录,再移动到最终位置:

sudo mkdir -p /opt/jre sudo unzip -q jre-11.0.10.zip -d /tmp/jre-staging sudo mv /tmp/jre-staging/jre-11.0.10 /opt/jre/11.0.10

如果你记不住解压后的顶层目录名,先跑unzip -l jre-11.0.10.zip | head看一眼再移动。接着把环境变量写进/etc/profile.d/jre11.sh,这样所有登录用户的新会话都自动加载,而不是只对当前 shell 生效:

cat <<'EOF' | sudo tee /etc/profile.d/jre11.sh export JAVA_HOME=/opt/jre/11.0.10 export PATH="$JAVA_HOME/bin:$PATH" EOF

这里用tee写入,比直接echo >更安全,避免编辑器权限问题。注意<<'EOF'用引号包住,变量名不会被当前 shell 提前展开。写完这个文件后,当前会话可以手动source /etc/profile.d/jre11.sh立即生效,新登录的会话则会自动带上。验证命令不变:

java -version readlink -f "$(which java)"

readlink -f会显示出最终的完整路径,排查“明明配了 JAVA_HOME 但 java 不是它”的问题时非常有效。

3.3 用预编译 class 跑通闭环:没有 javac 的 JRE 怎么验证

装完环境变量只是第一步,真正要验证的是“这个 JRE 能不能把我的东西跑起来”。很多新手在这里会卡住:JRE 里头没有编译器,写好的.java文件怎么执行?答案是:你在有 JDK 的机器上把代码编译成.class,再把.class丢到只有 JRE 的机器上运行。JRE 里没有javac,这个前提从 1.0 时代就是如此,Java 9 之后模块化更加彻底,想临时编译更是毫无可能。

先写一个最小可用的类,故意让它打印运行时版本和类路径,这样能验证我们想要的所有信息:

public class RuntimeCheck { public static void main(String[] args) { System.out.println("java.version=" + System.getProperty("java.version")); System.out.println("java.home=" + System.getProperty("java.home")); System.out.println("classpath=" + System.getProperty("java.class.path")); } }

在安装了 JDK 的机器上编译:

javac -d out RuntimeCheck.java

-d out指定 class 输出到out目录。然后把out/RuntimeCheck.class传送到只有 JRE 的目标机,执行:

/opt/jre/11.0.10/bin/java -cp out RuntimeCheck

这里的-cp out是 classpath 参数,告诉 java 去哪个目录找类。输出里如果看到java.version=11.0.10,说明 JRE 能正常加载类、定位 home 目录、解析 classpath;如果报ClassNotFoundException,先确认 class 文件确实在 out 目录下,再确认你没有把-cp拼成-classpath的简写导致路径丢失。这套最小闭环是后面所有排障的基线,保存下来,出了怪问题先跑它。

3.4 批量部署脚本:解压、校验、版本检查一次完成

当你不止一台服务器,而是十台、二十台时,再一台台手动配置就不可接受了。把安装流程写成一个 bash 脚本是常见做法,我一般会在脚本里加上版本断言,防止解压后才发现目录搞错:

#!/bin/bash set -euo pipefail JRE_VERSION="11.0.10" INSTALL_DIR="/opt/jre/$JRE_VERSION" PKG="jre-11.0.10.zip" unzip -q "$PKG" -d /tmp/jre-staging TOP_DIR=$(ls -d /tmp/jre-staging/* | head -1) sudo mkdir -p /opt/jre sudo mv "$TOP_DIR" "$INSTALL_DIR" grep -q 'JAVA_VERSION="11.0.10"' "$INSTALL_DIR/release" "$INSTALL_DIR/bin/java" -version 2>&1 | grep -q "11.0.10" echo "JRE $JRE_VERSION installed at $INSTALL_DIR"

set -euo pipefail是脚本安全基线:任何命令失败立即退出,未定义变量直接报错,管道中任何一环失败都终止。TOP_DIR用ls -d取出解压后的第一个顶层目录,避开目录名不确定的问题。grep -q 'JAVA_VERSION="11.0.10"'是双重保险,前面靠目录名,这里靠文件内容,两个都过了才继续。最后执行的java -version输出到 stderr,所以要2>&1才能被 grep 捕获。这个脚本可以并行推送到多台机器上执行,也可以在 CI 里作为部署任务的一步。

4. 避坑:安装 JRE 11.0.10 最容易翻车的 5 个现场

4.1 java -version 输出的不是你要的版本

最经典的翻车现场:配置全做完了,打开终端java -version,结果显示1.8.0_xx。原因几乎都是 PATH 顺序问题。系统里已经存在旧版 Java,它的路径排在$JAVA_HOME/bin之前,shell 先找到旧的就用旧的。查证顺序很重要:先which java看当前解析路径,再echo $JAVA_HOME看配置值,两个对不上就调整 PATH。

解决方法是把 JAVA_HOME 里的bin往前挪。Linux 下我推荐硬链接接管:sudo ln -sf /opt/jre/11.0.10/bin/java /usr/bin/java,这一条会直接覆盖/usr/bin/java的旧链接。Windows 下则检查系统环境变量里的 Path,把旧版本的条目删掉,或者把那一条挪到用户级变量之后。注意改动后要开新终端,已经运行的进程不受影响。

4.2 把 Java 8 服务直接搬到 11,启动期报 ClassNotFoundException

现象是应用启动几秒后就抛java.lang.ClassNotFoundException: javax.xml.bind.JAXBException或NoClassDefFoundError。这不是 JRE 装坏了,是 Java 9 开始把 JAXB、JAX-WS、CORBA 这些 Java EE 模块从默认的运行时里拆了出去,11.0.10 里不再包含它们。Java 8 时代直接裸写import javax.xml.bind.*的代码,到这里会全线崩掉。

正确的解法是在应用依赖层面补库,而不是去 JRE 里找补。用 Maven 或 Gradle 引入 JAXB API 和对应的运行时实现,把依赖打进你的应用包;或者升级到已经适配 Java 11 的框架版本。千万不要尝试往 JRE 的lib目录里塞 jar,那是一条不归路,下次换版本又得重来,而且没人能维护这种私有补丁。

4.3 32 位应用配 64 位运行时:启动即失败

另一类高频翻车:双击 jar 没反应,或者命令行报“找不到或无法加载主类”,但同一个包换台机器就能跑。怀疑方向之一就是架构不匹配。jre-11.0.10.zip 在不同渠道有 32 位和 64 位两种构建,文件名看起来差不多,但内部bin/java的架构不同。32 位应用配了 64 位 JRE,或者反过来,启动期会出现各种离奇错误。

先用系统命令确认机器架构:Linux 执行uname -m,Windows 执行echo %PROCESSOR_ARCHITECTURE%。再执行目标 JRE 的java -version,输出里会包含64-Bit或32-Bit字样,Java 11 默认打印的是Java HotSpot(TM) 64-Bit Server VM这样的描述,注意看64-Bit这一段文字。两边对齐了再继续。如果应用本身是老旧的 32 位 native 库,那 JRE 也必须选 32 位版本,这点由应用决定,不由机器位数决定。

4.4 内部 CA 导致 SSL 握手失败

应用启动时连不上内部服务,报PKIX path building failed或者unable to find valid certification path to requested target。这不是 JRE 坏了,而是 JRE 自带的cacerts信任库不认你们公司内部的根证书。Java 8 时代你可能配过一遍,切到 11.0.10 之后信任库文件是全新的,之前导入的证书全部失效。

解决方法是把内部 CA 导入新 JRE 的信任库:

keytool -importcert -alias internal-ca -file ca.crt -cacerts -storepass changeit

-cacerts选项是 Java 9 之后新增的快捷方式,等价于指定lib/security/cacerts路径,不用再去记目录。changeit是信任库默认密码,生产环境里如果改过,就换成你自己设置的密码。缺这一步,SSL 握手失败会在切到新 JRE 的第一天集中爆发,是一种典型的“换了运行时忘带信任库”的踩坑。

4.5 解压后目录不可写:Java 启动器崩溃在临时文件上

还有一类比较隐蔽的问题:JRE 目录本身没毛病,但启动时一闪而过,抛Error occurred during initialization of VM或者java.io.IOException。原因很可能是解压后的目录权限不对,或者系统临时目录指向了一个不存在的路径。Java 启动器在初始化阶段会创建临时文件,如果TMPDIR、TEMP、TMP这些变量指向无效位置,整个过程就会直接中断。

Linux 下先检查解压目录的属主和写权限:ls -ld /opt/jre/11.0.10,确认当前用户对该目录有写权限;再echo $TMPDIR看临时目录是否存在。Windows 下重点看是否把 JRE 解压到了C:\Program Files这类需要管理员权限的目录,而你的服务又用普通用户启动——那初始化阶段必然写不进去。解决很简单:目录权限放开,临时目录改为/tmp(Linux)或%USERPROFILE%\AppData\Local\Temp(Windows)。这种问题最折磨人,因为错误信息很短,但方向查对了十分钟就能定位。

5. 把这套运行时真正“钉”在项目里:校验、锁定与容器化

5.1 压缩包完整性:先做 SHA-256 再谈部署

JRE 的 zip 包从下载到传到服务器,中间经过几次拷贝,文件损坏并不罕见。更危险的是,你无法保证拿到的包没有被篡改或截断。所以在任何部署动作之前,先做完整性校验。前提是你有一个可信的 SHA-256 值,这个值通常与压缩包一起发布在官方渠道或你们内部制品仓库的说明里。

Linux 上的校验很直接:

sha256sum jre-11.0.10.zip echo "发布方给的哈希值 jre-11.0.10.zip" | sha256sum -c -

第一条命令打印本地文件的哈希,你自己比对;第二条用-c参数直接校验。如果输出显示OK,说明文件与发布方一致。Windows 下用certutil -hashfile jre-11.0.10.zip SHA256得到哈希后手动比对。别嫌这一步麻烦,部署一个损坏的 JRE 包,后面排查起来的时间成本远高于这十秒钟。

5.2 锁定版本:从源码到生产只认一个运行时

部署完 JRE 只是开始,真正的坑在于“版本漂移”。今天装的 11.0.10,三个月后系统里因为某个依赖被升级成了 11.0.11,没人记得什么时候变的,也没人在意——直到线上出现只有新版本才有的行为变化。解决办法是把版本作为一个显式变量写入部署脚本和 CI 配置,而不是“哪个版本在那里就装哪个”。

export JRE_VERSION="11.0.10" export JRE_HOME="/opt/jre/$JRE_VERSION"

在你的 CI 流水线里,这个变量是每次部署任务的输入参数;升级要么改这个变量,要么改代码仓库里的配置文件并留下记录。配合 5.1 的哈希校验,每次部署都能确保从压缩包内容到实际目录都是同一个版本。我见过很多团队栽在“装过一次成功就不管了”上,等出了问题想复现环境,谁都不知道生产跑的是哪一版。版本锁定不是技术问题,是纪律问题。

5.3 容器镜像里的 JRE:最小体积的两种做法

容器化部署时,JRE 的 zip 形态反而比安装器更友好。你不需要任何系统级写入,只需要在构建文件里解压、设置环境变量:

FROM 最小基础镜像 ADD jre-11.0.10.zip /tmp/jre.zip RUN cd /opt \ && unzip /tmp/jre.zip \ && rm /tmp/jre.zip \ && mv /opt/<解压后目录名> /opt/java \ && ln -s /opt/java/bin/java /usr/bin/java ENV JAVA_HOME=/opt/java \ PATH=/opt/java/bin:$PATH

ADD会自动处理本地 zip 文件,RUN里串行执行解压、清理、重命名和软链,目的是让最终镜像里没有多余的压缩包和临时文件。注意<解压后目录名>要替换成实际解压产物,先用unzip -l确认再写进构建文件。这是容器化场景里最通用的路径。

另一种更彻底的做法是直接裁剪运行时,这就是下面要说的 jlink。

5.4 模块裁剪:jlink 与这个 zip 的协作边界

JRE 11 自带完整模块镜像,但有些场景下你只需要 java.base、java.logging、java.sql 这些基础模块,剩下的都是冗余。裁剪这件事,得回到 JDK 环境用jlink完成。JRE 包里没有jlink,也没有jmods模块描述文件,这就是二者协作的边界。

先看看当前 JRE 里有哪些模块可以裁剪:

/opt/jre/11.0.10/bin/java --list-modules

输出会列出所有可用模块。如果确认只需要其中一部分,就在 JDK 机器上执行:

/path/to/jdk-11.0.10/bin/jlink \ --module-path /path/to/jdk-11.0.10/jmods \ --add-modules java.base,java.logging,java.sql,java.naming,java.management \ --output /opt/jre-custom

--module-path指向 JDK 的jmods目录,--add-modules列出你要保留的模块,--output指定生成目录。裁剪后生成的目录结构跟 JRE 几乎一致,可以直接替代原版使用。但要小心:裁剪时漏了运行期必需的模块,应用启动时会报ClassNotFoundException或NoClassDefFoundError。如果你不确定要用哪些模块,就一次多加点,或者干脆保留完整 JRE——裁剪省下的几十 MB 不一定值得拿稳定性去换。

裁剪后的运行时是我个人更偏爱的形态,它把“这个 JRE 到底由哪些模块组成”写进了构建脚本,版本和内容都完全可追溯,不再是一个黑匣子。如果你已经开始在容器里用 JRE,下一步就应该考虑把 jlink 纳入镜像构建流程。

6. JVM 参数固化:把 GC 日志、内存上限与容器识别一次性写进环境脚本

部署 JRE 的最后一步,不是把java -jar写进启动命令就完事,而是把 JVM 参数固化成一份环境脚本,让你在每台机器上看到的运行时行为都一致。我自己的习惯是给每个应用单独配一份jre-env.sh,内容像这样:

export JAVA_HOME=/opt/jre/11.0.10 export PATH="$JAVA_HOME/bin:$PATH" JAVA_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC" JAVA_OPTS="$JAVA_OPTS -Xlog:gc*:file=/var/log/app/gc.log:time,uptime,level,tags:filecount=5,filesize=20m" JAVA_OPTS="$JAVA_OPTS -XX:-OmitStackTraceInFastThrow -Dfile.encoding=UTF-8" export JAVA_OPTS

-Xms512m -Xmx2g设置了稳定且上限明确的堆内存。-XX:+UseG1GC在 Java 11 里已经是默认收集器,显式写出来是因为将来如果有人换回 Java 8,这个参数能立刻暴露版本差异。-Xlog:gc*是 Java 9 之后统一日志框架的写法,它会自动滚动,避免 GC 日志无限膨胀。-XX:-OmitStackTraceInFastThrow是排障利器,不加它,像 null 指针反复抛出时 JVM 会自动省略堆栈,你看到的只有一句NullPointerException,没有任何现场;加上这个参数,每次异常都有完整堆栈,代价是性能略降,调试期值得。最后固化文件编码,避免中文日志变成乱码。

在容器里运行时,参数-XX:+UseContainerSupport在 Java 11 中已默认开启,JVM 会自动读取容器限制的内存而不是宿主机内存。验证方法是用一行命令确认 JVM 最终识别到的堆上限:/opt/jre/11.0.10/bin/java -XX:+PrintFlagsFinal -version | grep -i maxheapsize。如果输出跟容器限制一致,说明内存识别没有出问题。我们当年把一个内部服务切到 11 时,就是栽在没带 GC 日志上,出问题没法复盘,后来我养成了习惯:任何环境拿到 JRE,先只做两件事——锁版本、写日志参数,再谈跑应用。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询