ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ECS四节点Hadoop集群与对象存储、Spark SQL实验避坑指南

ECS四节点Hadoop集群与对象存储、Spark SQL实验避坑指南

简介:《华为云大数据实验报告hhu》面向高校大数据、云计算课程学习者及华为云实操入门者,围绕云主机与云服务两条技术路径,解决从环境准备、集群搭建到交互式查询的实验落地问题。报告按四个模块组织:利用ECS与OBS配置访问密钥、打通节点SSH并安装OpenJDK,完成Hadoop集群搭建;借助云服务实现数据存储、处理与分析;在BigData Pro中购买ECS、创建OBS,并部署Hadoop与Spark集群;使用Spark SQL或Flink SQL开展大规模数据查询与结果验证。资源包内含1个docx,约4.36MB,目录与实验步骤对应清晰,便于按章节查阅命令、配置和验证记录,也可作为课程实验报告撰写与云端排错的参考。目前已有2541人学习,适合需要系统完成华为云大数据实验的读者。

1. 一台 ECS 起四节点集群:这份大数据实验报告到底值不值得照着跑

很多人对“云上大数据实验”的印象,就是开一台云主机、装个 Hadoop、跑个 WordCount 截张图交差。真照着这份实验报告完整走一遍会发现,价值不在那个 WordCount,而在于它把“弹性云服务器(ECS)+ 对象存储 + 四节点 Hadoop 集群 + Spark 交互式查询”串成了一条闭环:前半段在云主机上手工搭集群,后半段把数据落点从本地磁盘换到对象存储,最后用 Spark SQL 去查。它适合两类人:手上有大数据课程设计要交、又不想在本地虚拟机里跟网络较劲的人;以及要在真实公有云环境验证 HDFS 兼容文件系统、但不想从零写部署脚本的工程师。这份材料不完美,报告里夹着明文访问密钥和一堆硬编码的内网 IP,照着抄一定会踩坑——但坑本身,恰恰是这份报告最值钱的部分。

2. 云端四节点拓扑怎么切:角色分配、规格与对象存储选型

2.1 四节点角色分配与实例规格

报告里用的是 node1 到 node4 四台 ECS,这个数量不是随便定的。Hadoop 的默认副本数是 3,四节点刚好能满足“一份数据落在三个 DataNode 上、还剩一台可以挂掉”的最小容错组合;同时 node1 兼任 NameNode 和 ResourceManager,node2~node4 只跑 DataNode 和 NodeManager,CPU 和内存压力不会全压在管理节点上。这套分法在课程实验里够用,也最省机器。

规格上建议别省。我见过太多人开 2 vCPU / 4 GB 的入门款,装完 JDK 和 Hadoop,NameNode 一启动内存就剩几百兆,WordCount 跑到 map 0% 就再也不动了。四台机器统一的起步配置是 4 vCPU / 8 GB / 系统盘 40 GB,如果数据要落本地 HDFS,再挂一块 100 GB 的数据盘单独挂到/opt/bigdata下,把系统和数据分开,后面清理环境时不会误删。

节点角色建议规格说明
node1NameNode / ResourceManager / SecondaryNameNode4C8G管理节点,堆内存调大
node2DataNode / NodeManager4C8G数据节点
node3DataNode / NodeManager4C8G数据节点
node4DataNode / NodeManager4C8G数据节点,兼 Spark Worker

提示:四台机器尽量选同一个可用区、同一个子网,内网互通不需要额外配置,后面写/etc/hosts时也只用内网地址。

2.2 为什么数据落点要选对象存储而不是本地 HDFS

报告里有一个很容易被忽略的设计:它没有让实验数据停在本地 HDFS 上,而是要求把 ECS 和对象存储打通,WordCount 的输入输出都能走obs://开头的路径。这个选择的现实理由是——ECS 是按小时计费的,实验做完一释放,本地磁盘上的数据全没了;下次再做实验,要么重新上传,要么从头跑一遍。对象存储按量计费、容量几乎不受限,桶里的数据可以跨会话、跨机器复用,这在上课场景里非常关键。

技术上,云厂商一般会提供一个 Hadoop 兼容的文件系统实现(一个 jar 包),把它丢进$HADOOP_HOME/share/hadoop/common/lib/或者加到 classpath,Hadoop 就能把obs://bucket/path当成一个普通的文件系统来读写。上层 MapReduce、Spark 代码完全不用改,只是把路径从hdfs://换成obs://。代价是延迟:对象存储的元数据操作比 NameNode 慢一个数量级,小文件多的时候会非常明显,所以实验里要养成“先合并再上传”的习惯。

还有一种更省事的做法是并行文件系统,它提供 POSIX 语义,可以像本地目录一样挂载到 ECS 上,适合需要随机读写或者多机共享同一份训练数据的场景。两种方式在报告里都出现了,选哪个取决于你的作业是不是需要“文件系统语义”——如果只是 WordCount 这种顺序读写,直接用连接器就够了。

2.3 上机前必须先对齐的资源清单

动手前把下面这些信息一次性收集齐,比中途来回翻控制台强得多。报告里最容易出错的地方就是密钥和端点,很多“连不上”的问题到最后都是复制粘贴时多了一个空格。

资源项用途需要注意
VPC 与子网四台 ECS 的内网互通四台必须在同一 VPC
安全组放行 22 / 9870 / 8088 / 7077 / 8080 / 18080实验期可对内网全放行,别开公网
对象存储桶存输入输出数据与 ECS 同区域,避免跨区流量
访问密钥 AK/SK连接器认证用完即删,别写进截图
服务端点 Endpoint连接器寻址用服务级域名,不是桶域名
内网 IP 列表写/etc/hosts四台机器内容完全一致

注意:报告里贴出的访问密钥、SSH 公钥和公网 IP 都是真实值,这类材料在流转过程中基本等于公开。自己复现时,凡是出现在文档、截图、代码注释里的密钥,一律视为已泄露,实验结束立刻在控制台删除并重建。

3. 从空系统到 SSH 互信:节点初始化里最容易被跳过的一小时

3.1 主机名与 /etc/hosts 的固定写法

Hadoop 全靠主机名找节点,配置文件里写的是node1:9000这种形式,一旦解析不到,NameNode 起来也是白起。四台机器分别执行下面的命令设置主机名,然后统一写 hosts 文件。注意 hosts 里必须用内网 IP,公网 IP 写进去在跨节点通信时会绕出去再绕回来,慢且容易失败。

# 四台机器分别执行,node1 上的就把 node1 换成对应名字 hostnamectl set-hostname node1 # 四台机器统一追加,内容必须完全一致 cat >> /etc/hosts <<'EOF' 192.168.1.11 node1 192.168.1.12 node2 192.168.1.13 node3 192.168.1.14 node4 EOF # 验证:四台互相 ping 通、hostname -f 返回正确 ping -c 2 node3 hostname -f

hostnamectl set-hostname只改运行时主机名,重启后依然有效;hostname -f如果返回的不是短名而是带域名的长名,说明云厂商的 DHCP 下发了一套默认域名,要么在/etc/hostname里写死,要么在/etc/hosts里保证短名排在第一位,否则 Hadoop 会拿长名去通信,配好的互信直接失效。

3.2 密钥分发与 authorized_keys 的合并姿势

报告里是让每台机器生成密钥、再把四份公钥粘贴到同一个文件里。手工复制四段公钥,十个里有八个会少一个换行或者多一个空格,结果就是“配了免密但还是要密码”。写成脚本一次做完,顺便把known_hosts也处理掉,避免第一次连接时卡在 yes/no 交互上。

#!/bin/bash # 在 node1 上执行,前提:/etc/hosts 已配好,四台 root 密码一致 set -e # 1. 四台机器各自生成密钥(已存在则跳过) for h in node1 node2 node3 node4; do ssh $h "test -f /root/.ssh/id_rsa || ssh-keygen -t rsa -b 2048 -N '' -f /root/.ssh/id_rsa" done # 2. 收集四台公钥,去重后写入统一文件 : > /tmp/all_pub for h in node1 node2 node3 node4; do ssh $h "cat /root/.ssh/id_rsa.pub" >> /tmp/all_pub done sort -u /tmp/all_pub > /root/.ssh/authorized_keys # 3. 分发到四台,并修正权限 for h in node1 node2 node3 node4; do ssh $h "mkdir -p /root/.ssh && chmod 700 /root/.ssh" scp -q /root/.ssh/authorized_keys $h:/root/.ssh/authorized_keys ssh $h "chmod 600 /root/.ssh/authorized_keys" done # 4. 预置 known_hosts,消除首次连接交互 for h in node1 node2 node3 node4; do ssh-keyscan -H $h >> /root/.ssh/known_hosts 2>/dev/null done sort -u /root/.ssh/known_hosts -o /root/.ssh/known_hosts

这段脚本的核心是第 2 步:sort -u去重,保证四台机器的authorized_keys内容完全一致、每行一个公钥、末尾有换行。第 3 步的两个权限是关键——.ssh目录必须是 700,authorized_keys必须是 600,权限过宽 sshd 会直接拒绝使用这个文件,而且默认不打印任何日志,表现就是“怎么都不免密”。第 4 步用ssh-keyscan把主机指纹提前写进known_hosts,脚本化部署时能省掉大量StrictHostKeyChecking=no的临时手段。

验证方式很土但有效:四台机器上分别执行ssh node1到ssh node4,四次都应该直接进 shell 不提示密码。这一步不过,后面的start-dfs.sh一定起不来。

3.3 JDK 与 Hadoop 安装包落地

报告里是在 node1 上在线下载 OpenJDK 和 Hadoop 安装包,然后分发给其余节点。实际做的时候建议固定版本号,别用latest,四台机器版本不一致是后面最隐蔽的故障来源之一。

# 统一安装 OpenJDK 8 与 Hadoop 3.x yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel # 解压到统一目录 mkdir -p /opt/bigdata tar -zxf hadoop-3.x.x.tar.gz -C /opt/bigdata/ mv /opt/bigdata/hadoop-3.x.x /opt/bigdata/hadoop # 写环境变量,四台机器内容一致 cat > /etc/profile.d/bigdata.sh <<'EOF' export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export HADOOP_HOME=/opt/bigdata/hadoop export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin export HADOOP_HEAPSIZE=2048 EOF source /etc/profile.d/bigdata.sh hadoop version

HADOOP_HEAPSIZE这一行报告里没提,但 8 GB 的机器如果不显式指定,NameNode 默认堆只有 1 GB 左右,稍微跑点作业就会 OOM 或者频繁 Full GC。设成 2048 之后,NameNode 和 ResourceManager 各自占 2 GB 堆,四节点实验完全够用。

3.4 防火墙、SELinux 与时间同步

实验环境里防火墙是纯负担,Hadoop 节点间要开十几个端口,一个个放行不如直接关掉,用安全组在云平台侧做访问控制更清晰。SELinux 对 HDFS 目录权限的干扰也很玄学,关掉省事。

# 四台机器分别执行 systemctl stop firewalld && systemctl disable firewalld setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config # 时间同步,四台偏差超过 30 秒集群会出各种奇怪问题 systemctl enable --now chronyd chronyc sources -v

时间同步容易被忽略,但它是典型的黑匣子故障源:NameNode 和 DataNode 之间靠心跳和租约协作,机器之间时间偏差大了,会出现“DataNode 明明活着却被标记为 dead”或者“作业卡在 commit 阶段”。chronyc sources里只要能看到带^*的服务器,就说明同步正常。

4. Hadoop 配置与对象存储对接:core-site.xml 里四个必须对齐的参数

4.1 core-site.xml:默认文件系统与对象存储接入

core-site.xml是整个集群的地基,改错一个标签,四个节点全部起不来。报告里最关键的是两块配置:HDFS 的默认地址,以及对象存储连接器的四个参数。参数名通常以fs.obs.开头,别自己臆造。

<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node1:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/bigdata/tmp</value> </property> <!-- 对象存储连接器实现类 --> <property> <name>fs.obs.impl</name> <value>org.apache.hadoop.fs.obs.OBSFileSystem</value> </property> <!-- 密钥通过环境变量注入,不要把明文写进这个文件 --> <property> <name>fs.obs.access.key</name> <value>${env.OBS_AK}</value> </property> <property> <name>fs.obs.secret.key</name> <value>${env.OBS_SK}</value> </property> <!-- 服务端点,必须与桶所在区域一致 --> <property> <name>fs.obs.endpoint</name> <value>obs.cn-north-4.myhuaweicloud.com</value> </property> </configuration>

逐项说:fs.defaultFS里的node1必须是能被四台机器解析的主机名,写成 IP 也能跑,但换机器时全得改;hadoop.tmp.dir建议单独指定,不要用默认的/tmp,很多云主机/tmp分区只有几个 G,跑两个作业就写满;fs.obs.impl是连接器的入口类,jar 包不在 classpath 里时这个属性会静默失效,表现是obs://路径报No FileSystem for scheme;fs.obs.access.key用${env.OBS_AK}做变量替换,Hadoop 的 Configuration 支持env.前缀,这样密钥就不会留在配置文件里被截图带走——报告里明文贴密钥的做法,别学。

注意:端点必须用服务级域名,不是桶域名。写成bucket-name.obs.xxx.com这种形式,绝大部分连接器都不认,报的还是认证失败,很容易误判成密钥错了。

4.2 hdfs-site.xml、workers 与副本策略

hdfs-site.xml里改三件事就够跑通:副本数、NameNode 元数据目录、DataNode 数据目录。四节点环境副本数设 3,既能看到三副本分布,又不至于把四台机器写满。

<configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/opt/bigdata/hdfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/opt/bigdata/hdfs/data</value> </property> <property> <name>dfs.namenode.http-address</name> <value>node1:9870</value> </property> </configuration>

Hadoop 3.x 用workers文件(2.x 是slaves),内容是三个数据节点的主机名,一行一个,node1 写在第一行也行但通常只放工作节点:

cat > $HADOOP_CONF_DIR/workers <<'EOF' node2 node3 node4 EOF

这个文件决定了start-dfs.sh会去哪些机器上拉起 DataNode。报告里出现“集群起来了但只有一个 DataNode”的情况,九成是这里没改或者改了没分发到 node1。改完记得用scp把整个etc/hadoop目录同步到其余三台,配置不一致是分布式环境最典型的翻车方式。

4.3 格式化、启动与 jps 验收

格式化只做一次,这是血泪经验。hdfs namenode -format会在dfs.namenode.name.dir下生成 clusterID,DataNode 首次启动时把自己的 clusterID 写进数据目录,两边对不上就拒绝加入集群。第二次格式化会让 NameNode 换一个新 ID,而 DataNode 还留着旧的,现象就是“DataNode 进程在、但集群里看不到”。

# 只在 node1 上执行,且全生命周期只执行一次 hdfs namenode -format # 启动 HDFS 与 YARN start-dfs.sh start-yarn.sh # 四台机器分别检查进程 jps

验收标准是 node1 上能看到NameNode、SecondaryNameNode、ResourceManager,node2~node4 上能看到DataNode、NodeManager。少了哪个,先看对应机器上logs/目录下最新的.log,别急着删目录重来。启动完成后浏览器打开http://node1:9870,Live Nodes 显示 3 才算真正起来了。

4.4 WordCount 跑通与对象存储回读

WordCount 是这份实验的验收动作,但它真正的目的是验证两条路径:本地 HDFS 读写是否正常,以及对象存储连接器是否可以跨系统读写。建议把输入先放 HDFS 跑一遍,再把输出直接写到对象存储,一次把两个问题都暴露出来。

# 准备输入 hadoop fs -mkdir -p /input hadoop fs -put /opt/bigdata/data/*.txt /input/ # 第一次:输入输出都走 HDFS hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.x.x.jar \ wordcount /input /output/wc01 # 第二次:输出直接落到对象存储 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.x.x.jar \ wordcount /input obs://my-bigdata-lab/output/wc02 # 两边都检查一下 hadoop fs -cat /output/wc01/part-r-00000 | head hadoop fs -ls obs://my-bigdata-lab/output/wc02/

hadoop jar后面跟的 jar 包路径里版本号要跟你实际解压的一致,用通配符hadoop-mapreduce-examples-*.jar更稳妥。第二次作业如果卡在map 0%很久然后失败,先去看 ResourceManager 的 8088 页面,大概率是容器内存不够或者连接器 jar 没被分发到计算节点——MapReduce 会把依赖 jar 打进 DistributedCache,连接器 jar 如果只放在 node1 的 classpath 里,任务跑到 node2 上就会报ClassNotFoundException。稳妥做法是把连接器 jar 直接放进$HADOOP_HOME/share/hadoop/common/lib/并分发到四台。

4.5 Spark 复用同一套 Hadoop 配置

Spark 不需要单独配一套文件系统参数,它读的是HADOOP_CONF_DIR指向的目录。所以只要spark-env.sh里把这两行加上,Spark 就能直接读写 HDFS 和对象存储,连密钥都不用再配一遍。

# 在 $SPARK_HOME/conf/spark-env.sh 中追加 export HADOOP_CONF_DIR=/opt/bigdata/hadoop/etc/hadoop export SPARK_DIST_CLASSPATH=$(hadoop classpath) # conf/workers 写三个工作节点 node2 node3 node4 # 启动 $SPARK_HOME/sbin/start-all.sh

SPARK_DIST_CLASSPATH=$(hadoop classpath)这一行是关键,它把 Hadoop 的所有依赖(包括连接器 jar)一次性塞进 Spark 的运行时 classpath,省掉逐个拷 jar 的麻烦。启动后在 node1 上执行spark-sql能进交互式命令行,说明集群和配置都对上了。

5. 避坑排查:五条照着报告做却卡住的真实记录

5.1 SSH 免密配完仍要密码、DataNode 起不来

现象:ssh node2仍然提示输入密码,或者免密通了但start-dfs.sh之后jps里只有 NameNode,DataNode 一个都没有。

原因:前者基本是权限问题,.ssh目录不是 700 或authorized_keys不是 600,sshd 会静默忽略这个文件;也可能是四台机器的authorized_keys内容不一致,脚本只在一台上跑过。后者最常见的原因是格式化执行了两次,NameNode 和 DataNode 的 clusterID 对不上,日志里会明确写Incompatible clusterIDs。

解决:先ls -ld /root/.ssh和ls -l /root/.ssh/authorized_keys看权限,再md5sum四台的authorized_keys确认一致。clusterID 问题只能停集群、清空dfs.namenode.name.dir和dfs.datanode.data.dir下的内容、重新格式化一次,然后重新启动。养成习惯:格式化这个动作在任何环境里都只做一次,重装集群就先把数据目录清干净。

5.2 对象存储认证失败与端点错配

现象:obs://路径报InvalidAccessKeyId或者Status 403,但同样的密钥在控制台上能正常访问桶。

原因:三种情况最常见——AK/SK 从文档里复制时带了首尾引号或空格;端点写成了桶域名而不是服务域名;桶和 ECS 不在同一区域,连接器按区域拼出来的地址实际指向了另一个端点。还有一种是密钥本身是子账号的,权限策略里没给这个桶的读写权限,报错信息同样是 403,很容易误判。

解决:把 AK/SK 用echo -n打进环境变量,再用env | grep OBS确认没有多余字符;端点统一用控制台给出的服务级地址;跨区域问题直接在桶所在区域重建 ECS,或者换一个同区域的桶做实验。排查顺序固定为:先验证密钥能否ls一个已知存在的桶,再验证能否写,最后才跑作业,别一上来就用 MapReduce 试错。

5.3 WordCount 卡在 map 0% 或容器被 kill

现象:作业提交后进度条长时间停在map 0% reduce 0%,8088 页面显示容器状态KILLED,日志里有Container killed on request. Exit code is 137。

原因:137 是 OOM 被杀。YARN 默认的yarn.nodemanager.resource.memory-mb在 8 GB 机器上通常给到 8 GB,但单个容器默认申请 1 GB 虚拟内存、实际物理内存不够时会触发超配限制;另外yarn.nodemanager.vmem-check-enabled默认开启,虚拟内存超了也会被杀,而 JVM 的虚拟内存占用天然偏高。

解决:在yarn-site.xml里把yarn.nodemanager.resource.memory-mb设成 6144,yarn.scheduler.maximum-allocation-mb设成 4096,并把yarn.nodemanager.vmem-check-enabled设为 false(实验环境可以关,生产别关)。改完同步到四台并重启 YARN。这一条在 4 GB 内存的机器上几乎必现,所以第 2 章才建议直接上 8 GB。

5.4 集群时间漂移导致的假死

现象:集群运行一段时间后,9870 页面上某个 DataNode 显示Dead,但那台机器上jps明明有 DataNode 进程,重启后又正常,过一阵再死。

原因:节点间时间不同步,心跳包的时间戳被判为过期。云主机默认可能没开时间同步服务,或者 NTP 源不可达,机器之间的偏差会慢慢累积。

解决:四台统一启用chronyd,chronyc sources -v确认有^*标记的同步源;同时在hdfs-site.xml里把dfs.namenode.heartbeat.recheck-interval适当调大,给网络抖动留出余量。这条不解决,你会反复怀疑是 Hadoop 的 bug,实际上跟 Hadoop 一点关系都没有。

5.5 实验报告里的明文密钥

现象:报告正文和截图里直接贴着 AK/SK、SSH 公钥、内网 IP 和主机名,照着复制就能用。

原因:作者在做实验时没有脱敏,直接把控制台和终端截图贴进了文档。这类材料一旦在群里、网盘里流转,密钥等于公开,桶里的数据、甚至同账号下的其他资源都存在风险。

解决:自己复现时,密钥一律走环境变量或临时凭证,绝不写进配置文件和截图;用子账号而不是主账号,权限策略只给实验桶的读写;实验结束当天就在控制台删除密钥并重建。文档里出现的 IP、主机名、密钥、桶名,提交前统一替换成占位符,这一条比任何技术细节都重要。

6. 跑通之后的验证与脱敏:把一次实验变成可复用的检查单

作业跑绿不等于集群健康。我习惯在交报告之前做一轮端到端校验:HDFS 侧看副本是否真的落到了三台机器上,对象存储侧看输出目录里的_SUCCESS文件和 part 文件数量是否对得上,Spark SQL 再用count(*)跟 HDFS 的结果交叉验证一次。三边数字一致,才算这次实验真的跑通了。

# 1. 副本分布:每个块应该出现三次,且分布在 node2~node4 hdfs fsck /output/wc01 -files -blocks -locations # 2. 对象存储侧校验:有 _SUCCESS 且 part 文件数等于 reduce 数 hadoop fs -ls obs://my-bigdata-lab/output/wc02/ # 3. Spark SQL 交叉验证,结果应与 HDFS 上 wc01 的总行数一致 spark-sql -e " CREATE EXTERNAL TABLE wc02(line STRING) LOCATION 'obs://my-bigdata-lab/output/wc02'; SELECT count(*) FROM wc02; "

第一行fsck看的是数据可靠性,副本数不足会在输出里标Under-replicated;第二行看的是连接器写入是否完整,缺_SUCCESS说明作业没正常提交;第三行用 Spark 直接读对象存储建外部表,是验证“交互式查询”这条路是否真正打通的最快方式。LOCATION指向目录而不是单个文件,Spark 会把目录下所有 part 文件当成表数据,这也是为什么一定要确认 part 文件数量。

交报告之前还有一步:脱敏。密钥、公钥、内网 IP、主机名、桶名,一个都不能留。手工改容易漏,用一条命令扫一遍更稳:

# 扫描报告和脚本里疑似敏感信息,输出行号方便定位 grep -nE '(AK|SK|access[_-]?key|secret|ssh-rsa|192\.168\.|10\.[0-9]+\.[0-9]+\.)' report.md

命中之后逐条替换成<ACCESS_KEY>、<INTERNAL_IP>这类占位符,再重新扫一遍直到没有输出。这一步花不了五分钟,但能避免把一份带密钥的文档发给别人。

从那以后我每次做云上实验,收尾都强制走一遍这套校验加脱敏,跑通了不等于交付了,交付的是别人能照着复现、又不会泄露自己环境的那一版。希望帮到你。

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

返回列表