Ubuntu 16.04上Hive 4.2.0伪分布式部署与MySQL元数据配置实战
1. 从零开始的Hive部署:为什么选择Ubuntu 16.04?
如果你正在大数据领域摸索,或者你的项目需要一个本地的、可控的Hive环境来做数据仓库的开发和测试,那么自己动手在Ubuntu上部署一套Hive,几乎是每个数据工程师都会经历的“成人礼”。我选择Ubuntu 16.04 LTS作为起点,并不是因为它最新,恰恰相反,是因为它足够经典和稳定。很多企业遗留的生产环境、教程文档,甚至是某些特定版本的Hadoop生态组件,对Ubuntu 16.04的支持和兼容性经过了时间的考验,踩坑的路径相对清晰,解决方案也更容易找到。这能让你把精力集中在理解Hive本身,而不是和最新的系统版本、依赖库版本作斗争。
Hive是什么?简单说,它是一套构建在Hadoop之上的数据仓库工具。它允许你使用一种类似SQL的语言(HiveQL)去查询和分析存储在HDFS(Hadoop分布式文件系统)上的海量数据。对于熟悉传统数据库(如MySQL)的开发者来说,Hive极大地降低了进入大数据处理领域的门槛。但请注意,Hive本身不存储数据,也不直接执行计算,它更像一个翻译官和调度员:将你的SQL“翻译”成一系列的MapReduce或Tez任务,提交给Hadoop集群去执行。因此,安装Hive的前提,是你已经有一个可以正常工作的Hadoop环境(伪分布式或完全分布式)。本系列文章,我们就从最基础的伪分布式Hadoop环境开始,一步步在Ubuntu 16.04上搭建起一个功能完整的Hive。
2. 环境准备与前置条件检查
在开始安装Hive之前,我们必须确保地基是牢固的。一个混乱的初始环境是后续所有诡异问题的根源。这里我假设你已经有一台安装了纯净Ubuntu 16.04 LTS的机器(物理机或虚拟机均可)。我们将从系统层面开始,一步步搭建起Hive所需的所有依赖。
2.1 系统基础配置与Java环境搭建
Hadoop和Hive都是基于Java开发的,所以JDK是我们的第一块基石。我强烈建议使用Oracle JDK 8,这是Hadoop生态圈历史最悠久、兼容性最广的版本。在Ubuntu 16.04上,我们可以通过PPA源来安装。
首先,更新系统包列表并安装一些基础工具:
sudo apt-get update sudo apt-get install -y vim wget curl ssh pdshpdsh是一个并行分布式shell工具,在管理多节点集群时很有用,单机环境先装上也无妨。
接下来,添加Oracle JDK的PPA并安装:
sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install -y oracle-java8-installer安装过程中会弹出图形界面许可协议,按Tab键切换到“OK”再回车,然后选择“Yes”同意即可。
安装完成后,配置JAVA_HOME环境变量。这是至关重要的一步,很多后续问题都源于此变量配置错误。
# 查找JDK的安装路径,通常类似 /usr/lib/jvm/java-8-oracle sudo update-alternatives --config java # 记下路径,例如 /usr/lib/jvm/java-8-oracle/jre/bin/java # 那么JAVA_HOME就是 /usr/lib/jvm/java-8-oracle # 编辑环境变量配置文件 sudo vim /etc/profile在文件末尾添加以下内容(请将路径替换为你实际查到的):
export JAVA_HOME=/usr/lib/jvm/java-8-oracle export PATH=$PATH:$JAVA_HOME/bin保存退出后,执行source /etc/profile使配置立即生效。然后验证:
java -version echo $JAVA_HOME你应该能看到Java版本为1.8.x,并且JAVA_HOME变量被正确设置。
注意:有些教程会建议修改
~/.bashrc,这只对当前用户生效。为了确保所有用户(特别是以后以hadoop用户运行的服务)都能正确读取到环境变量,我习惯将其配置在/etc/profile中。这是一个个人偏好,但也避免了后续切换用户时可能遇到的“命令找不到”的坑。
2.2 创建专用用户与SSH免密登录配置
为了安全和管理方便,我们不应该使用root用户来运行Hadoop和Hive。创建一个专用的hadoop用户是个好习惯。
sudo adduser hadoop按照提示设置密码并填写一些无关紧要的信息即可。之后,我们将在这个用户下进行所有操作。
Hadoop的脚本(如启动集群)需要管理节点间无密码的SSH通信。即使在单机伪分布式模式下,它也需要能通过SSH连接到localhost。因此,我们需要为hadoop用户配置SSH免密登录到本机。
首先,切换到hadoop用户,并生成SSH密钥对:
su - hadoop ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa-P ''表示空密码,-f指定密钥文件。这将在/home/hadoop/.ssh/目录下生成id_rsa(私钥)和id_rsa.pub(公钥)。
然后,将公钥追加到授权密钥文件中,并设置正确的权限:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys现在,尝试用hadoop用户SSH登录本机:
ssh localhost如果配置正确,你应该不需要输入密码就能直接登录。首次连接会询问是否将主机加入已知列表,输入yes即可。成功后,输入exit退出SSH会话,回到原来的shell。
实操心得:如果这一步失败,提示需要密码,最常见的原因是
.ssh目录或authorized_keys文件的权限不对。确保/home/hadoop/.ssh目录权限为700 (drwx------),authorized_keys文件权限为600 (-rw-------)。可以使用ls -la ~/.ssh命令检查。
3. Hadoop伪分布式集群搭建详解
正如前文所述,Hive的运行依赖于Hadoop。我们将搭建一个伪分布式模式的Hadoop集群,这意味着所有的Hadoop守护进程(NameNode, DataNode, ResourceManager, NodeManager)都运行在同一台机器上,但它们在逻辑上仍然以分布式架构运行。这是学习和测试的最佳方式。
3.1 Hadoop安装与核心配置文件解析
首先,以hadoop用户身份,下载Hadoop。我们选择2.7.x系列的一个稳定版本,比如2.7.7。你可以在清华大学开源镜像站找到更快的下载源。
cd /home/hadoop wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz下载完成后,解压并移动到合适的目录,我习惯放在/usr/local下,并创建软链接方便管理:
sudo tar -xzf hadoop-2.7.7.tar.gz -C /usr/local cd /usr/local sudo mv hadoop-2.7.7 hadoop sudo chown -R hadoop:hadoop hadoop接下来是配置的核心部分。Hadoop的配置文件位于/usr/local/hadoop/etc/hadoop/目录下,我们需要修改其中几个关键文件。
1. 配置Hadoop环境变量 (hadoop-env.sh)编辑/usr/local/hadoop/etc/hadoop/hadoop-env.sh,找到设置JAVA_HOME的行,取消注释并修改为你的JDK路径:
export JAVA_HOME=/usr/lib/jvm/java-8-oracle如果文件中没有明确的JAVA_HOME行,直接在文件开头附近添加即可。
2. 核心配置 (core-site.xml)这个文件配置Hadoop的核心参数,最重要的是定义HDFS的默认文件系统地址(fs.defaultFS)和临时文件目录。 编辑/usr/local/hadoop/etc/hadoop/core-site.xml,在<configuration>标签内添加:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/tmp</value> </property> </configuration>fs.defaultFS告诉Hadoop客户端,默认的文件系统是HDFS,地址在localhost的9000端口。hadoop.tmp.dir是Hadoop许多进程(如DataNode)存储临时数据的目录,务必确保hadoop用户对这个目录有读写权限。
3. HDFS配置 (hdfs-site.xml)这个文件配置HDFS相关的参数。在伪分布式模式下,我们设置数据块的副本数为1(因为只有一台机器)。 编辑/usr/local/hadoop/etc/hadoop/hdfs-site.xml:
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:/home/hadoop/hdfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:/home/hadoop/hdfs/data</value> </property> </configuration>dfs.namenode.name.dir和dfs.datanode.data.dir分别指定了NameNode和DataNode存储元数据和实际数据块的本地目录。请预先创建这些目录并赋予权限:
mkdir -p /home/hadoop/hdfs/{name,data}4. YARN配置 (yarn-site.xml)YARN是Hadoop的资源调度框架。Hive在默认情况下会将查询转换为MapReduce任务,这些任务由YARN来调度执行。 编辑/usr/local/hadoop/etc/hadoop/yarn-site.xml:
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>localhost</value> </property> </configuration>5. MapReduce配置 (mapred-site.xml)首先,需要从模板文件复制一份:
cp /usr/local/hadoop/etc/hadoop/mapred-site.xml.template /usr/local/hadoop/etc/hadoop/mapred-site.xml然后编辑mapred-site.xml,指定MapReduce框架使用YARN:
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>最后,将Hadoop的bin和sbin目录添加到hadoop用户的PATH环境变量中。编辑/home/hadoop/.bashrc,在末尾添加:
export HADOOP_HOME=/usr/local/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin执行source ~/.bashrc使其生效。
3.2 HDFS格式化与集群启动验证
在首次启动Hadoop之前,必须格式化HDFS的NameNode。这是一个危险操作,它会清空NameNode上所有的元数据。只有在第一次安装,或者确定要完全重置HDFS数据时才执行。
hdfs namenode -format你会看到大量日志输出,最后几行如果出现“Storage directory ... has been successfully formatted”则表示成功。
现在,可以启动HDFS和YARN了。Hadoop提供了脚本来启动所有相关进程。
# 启动HDFS start-dfs.sh # 启动YARN start-yarn.sh你可以使用jps命令来检查Java进程是否都正常启动了:
jps你应该能看到类似以下的进程:
NameNode DataNode SecondaryNameNode ResourceManager NodeManager Jps如果缺少某个进程(比如DataNode没起来),可以去/usr/local/hadoop/logs目录下查看对应的日志文件(如hadoop-hadoop-datanode-*.log),里面通常有详细的错误信息。常见问题包括目录权限不足、端口被占用、配置文件有拼写错误等。
验证HDFS是否正常工作,可以访问NameNode的Web UI:http://localhost:50070。你应该能看到一个管理界面,显示集群的概览信息。同样,YARN的ResourceManager UI在http://localhost:8088。
为了后续Hive测试方便,我们可以在HDFS上创建一个临时目录,并赋予hadoop用户写入权限:
hdfs dfs -mkdir -p /user/hadoop hdfs dfs -chown hadoop:hadoop /user/hadoop至此,一个可用的伪分布式Hadoop集群就搭建完成了。这是Hive能够运行的基石。
4. Hive 4.2.0 安装与元数据存储配置
有了Hadoop,我们终于可以开始安装Hive了。Hive 4.2.0是一个相对较新的稳定版本,修复了许多旧版本的bug并引入了一些新特性。Hive需要一个数据库来存储它的“元数据”(Metadata),也就是表的结构、字段类型、分区信息等。默认情况下,Hive使用内嵌的Derby数据库,但这只适用于单会话、单用户的测试场景。一旦你开启第二个Hive CLI会话,就会报错。因此,在生产或严肃的开发和测试中,我们通常使用MySQL或PostgreSQL作为元数据库。这里我们选择MySQL。
4.1 MySQL元数据库安装与初始化
首先,安装MySQL服务器和客户端:
sudo apt-get update sudo apt-get install -y mysql-server mysql-client安装过程中会提示你设置root用户的密码,请务必记住。
安装完成后,登录MySQL,为Hive创建一个专用的数据库和用户:
mysql -u root -p输入你设置的root密码后,进入MySQL命令行,执行以下SQL:
-- 创建一个名为hive_metastore的数据库,字符集使用utf8 CREATE DATABASE hive_metastore DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -- 创建一个名为hiveuser的用户,并设置密码(这里示例密码为‘hivepassword’,请务必修改) CREATE USER 'hiveuser'@'%' IDENTIFIED BY 'hivepassword'; -- 授予hiveuser用户对hive_metastore数据库的所有权限 GRANT ALL PRIVILEGES ON hive_metastore.* TO 'hiveuser'@'%'; -- 授予hiveuser用户授予权限的权限(某些版本的Hive初始化脚本需要) GRANT ALL PRIVILEGES ON hive_metastore.* TO 'hiveuser'@'localhost' IDENTIFIED BY 'hivepassword'; -- 刷新权限使更改生效 FLUSH PRIVILEGES; -- 退出MySQL EXIT;重要安全提示:上述配置中
‘hiveuser’@‘%’允许从任何主机连接,密码也是示例。在生产环境中,你应该限制访问IP(例如‘hiveuser’@‘localhost’)并使用强密码。
接下来,我们需要下载MySQL的Java连接驱动(JDBC Driver)。去MySQL官网或使用wget下载对应版本的驱动jar包(例如mysql-connector-java-5.1.47.jar),并将其放置到Hive的lib目录下。
cd /home/hadoop wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.47.tar.gz tar -xzf mysql-connector-java-5.1.47.tar.gz sudo cp mysql-connector-java-5.1.47/mysql-connector-java-5.1.47-bin.jar /usr/local/hive/lib/请根据你下载的实际版本调整命令中的版本号。
4.2 Hive软件包部署与关键配置
现在,下载并安装Hive。我们到Apache镜像站下载Hive 4.2.0。
cd /home/hadoop wget https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-4.2.0/apache-hive-4.2.0-bin.tar.gz sudo tar -xzf apache-hive-4.2.0-bin.tar.gz -C /usr/local cd /usr/local sudo mv apache-hive-4.2.0-bin hive sudo chown -R hadoop:hadoop hive同样,创建软链接或直接将Hive的bin目录加入PATH。编辑/home/hadoop/.bashrc,添加:
export HIVE_HOME=/usr/local/hive export PATH=$PATH:$HIVE_HOME/bin执行source ~/.bashrc。
Hive的核心配置文件是$HIVE_HOME/conf/hive-site.xml。默认情况下这个文件不存在,我们需要从模板创建并编辑它。
cd /usr/local/hive/conf cp hive-default.xml.template hive-site.xmlhive-default.xml.template包含了所有配置项及其默认值,但非常冗长。我们最好创建一个新的、简洁的hive-site.xml来覆盖我们关心的配置。你可以先备份原始的模板,然后直接编辑hive-site.xml,或者更推荐的做法是,直接新建一个hive-site.xml,因为Hive会加载这个文件,并且它的配置优先级很高。
用编辑器新建/编辑/usr/local/hive/conf/hive-site.xml,填入以下内容。请务必将javax.jdo.option.ConnectionPassword的值替换为你为hiveuser设置的密码。
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <!-- 连接元数据库的URL --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive_metastore?createDatabaseIfNotExist=true&useSSL=false&characterEncoding=UTF-8</value> <description>JDBC connect string for a JDBC metastore</description> </property> <!-- 连接元数据库的驱动类 --> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <!-- 连接元数据库的用户名 --> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hiveuser</value> <description>username to use against metastore database</description> </property> <!-- 连接元数据库的密码 --> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>hivepassword</value> <!-- 请修改为你的密码 --> <description>password to use against metastore database</description> </property> <!-- Hive数据在HDFS上的存储路径 --> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive/warehouse</value> <description>location of default database for the warehouse</description> </property> <!-- 在命令行中显示当前数据库名 --> <property> <name>hive.cli.print.current.db</name> <value>true</value> <description>Whether to include the current database in the Hive prompt.</description> </property> <!-- 在命令行中显示表头信息 --> <property> <name>hive.cli.print.header</name> <value>true</value> <description>Whether to print the names of the columns in query output.</description> </property> <!-- 指定Hive执行引擎为MapReduce (Tez或Spark是其他选项) --> <property> <name>hive.execution.engine</name> <value>mr</value> <description>Chooses execution engine. Options are: mr (MapReduce), tez, spark.</description> </property> </configuration>配置文件中有几个关键点:
useSSL=false:在测试环境可以禁用SSL连接,避免证书问题。生产环境应启用。createDatabaseIfNotExist=true:如果hive_metastore数据库不存在,JDBC连接时会自动创建。hive.metastore.warehouse.dir:这是Hive中创建的表的默认存储位置,位于HDFS上。我们稍后需要创建这个目录并赋权。
4.3 元数据库初始化与目录权限设置
在启动Hive之前,必须初始化它的元数据库。Hive提供了schematool来完成这个工作。这个工具会连接到我们配置的MySQL数据库,创建一系列存储元数据的表。
cd /usr/local/hive bin/schematool -dbType mysql -initSchema如果一切顺利,你会看到“Initialization script completed”和“schemaTool completed”的成功信息。此时,登录MySQL查看hive_metastore数据库,应该能看到很多以TBLS、COLUMNS_V2等命名的表。
接下来,在HDFS上创建Hive的仓库目录,并赋予hadoop用户(也就是运行Hive进程的用户)写权限:
hdfs dfs -mkdir -p /user/hive/warehouse hdfs dfs -chown -R hadoop:hadoop /user/hive hdfs dfs -chmod -R 775 /user/hive/warehouse-chmod 775使得同组用户也有写权限,这在多用户环境下有时是必要的。
5. Hive CLI启动、基础测试与排错指南
经过漫长的配置,终于到了激动人心的启动时刻。Hive最传统的交互方式是通过命令行界面(CLI)。
5.1 启动Hive CLI并执行首个查询
确保Hadoop集群(start-dfs.sh和start-yarn.sh)正在运行。然后,切换到hadoop用户,直接输入hive命令:
su - hadoop hive如果一切配置正确,你会看到Hive的命令行提示符,并且前面会显示当前数据库(默认为default),这是因为我们设置了hive.cli.print.current.db=true。
hive (default)>现在,让我们执行一些最基本的操作来验证Hive是否工作正常。
1. 显示所有数据库:
show databases;你应该能看到一个名为default的数据库。
2. 创建一个测试表:
CREATE TABLE IF NOT EXISTS test_hive (id INT, name STRING) COMMENT 'This is a test table' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE;这条命令创建了一个名为test_hive的内部表,有两个字段id和name,字段间用制表符分隔,以文本文件格式存储。
3. 查看创建的表:
show tables;你应该能看到test_hive表。
4. 向表中插入一条测试数据:在Hive中,直接使用INSERT INTO ... VALUES语句效率很低,因为它会启动一个MapReduce作业。对于测试,我们可以用INSERT ... SELECT或者更简单地,直接加载本地文件。我们先插入一条数据看看:
INSERT INTO TABLE test_hive VALUES (1, 'Alice');这会触发一个MapReduce作业。你可以在YARN的Web UI (http://localhost:8088)上看到这个作业的运行情况。执行完成后,查询数据:
SELECT * FROM test_hive;如果配置了hive.cli.print.header=true,你会看到带表头的输出:
test_hive.id test_hive.name 1 Alice5. 查看表在HDFS上的存储位置:
DESCRIBE FORMATTED test_hive;在输出信息中,找到Location一项,它的值应该类似hdfs://localhost:9000/user/hive/warehouse/test_hive。你可以用HDFS命令验证文件是否存在:
hdfs dfs -ls /user/hive/warehouse/test_hive应该能看到一个类似于000000_0的文件,这就是我们插入的数据文件。
5.2 常见启动失败问题与排查思路
理想很丰满,现实往往会在第一步hive命令就给你一个下马威。下面是一些我踩过的坑和排查方法:
问题1:启动Hive时报错java.lang.NoClassDefFoundError: org/apache/hadoop/hive/conf/HiveConf
- 原因:通常是因为
HADOOP_HOME环境变量没有正确设置,或者Hive找不到Hadoop的jar包。 - 解决:
- 确认
echo $HADOOP_HOME输出正确路径。 - 检查
/usr/local/hive/bin/hive这个shell脚本。旧版本Hive可能需要手动在脚本里设置HADOOP_HOME。但更通用的方法是确保hadoop命令在PATH中,且能正常执行。Hive脚本会通过which hadoop来定位Hadoop。 - 将Hadoop的共享库(比如
$HADOOP_HOME/share/hadoop/common/*.jar)添加到Hive的CLASSPATH中。一种粗暴但有效的方法是在hive-env.sh中设置(如果该文件不存在,从模板复制hive-env.sh.template):export HADOOP_HOME=/usr/local/hadoop export HIVE_CONF_DIR=/usr/local/hive/conf export HIVE_AUX_JARS_PATH=/usr/local/hive/lib
- 确认
问题2:执行Hive命令时连接元数据库失败,报错Failed to get schema version.或Communications link failure
- 原因:Hive无法连接到MySQL元数据库。
- 解决:
- 检查MySQL服务:
sudo systemctl status mysql确保MySQL正在运行。 - 检查连接参数:仔细核对
hive-site.xml中的ConnectionURL、ConnectionUserName、ConnectionPassword。特别是密码是否正确。 - 检查MySQL用户权限:确认
hiveuser用户是否可以从localhost访问hive_metastore数据库。可以尝试用mysql -u hiveuser -p登录MySQL。 - 检查MySQL绑定地址:MySQL默认可能只绑定到
127.0.0.1。编辑MySQL配置文件/etc/mysql/mysql.conf.d/mysqld.cnf,找到bind-address,确保其值为127.0.0.1或0.0.0.0(后者允许所有IP连接,测试环境可用)。 - 检查防火墙:Ubuntu 16.04默认的
ufw防火墙可能关闭,但如果有其他防火墙规则,确保3306端口是开放的。
- 检查MySQL服务:
问题3:执行查询时报错FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
- 原因:MapReduce任务执行失败。这是最宽泛的错误之一,需要查看Hadoop任务的具体日志。
- 解决:
- 去YARN的Web UI (
http://localhost:8088)找到失败的任务,点击ApplicationMaster链接,再查看Logs,特别是stderr和stdout,里面通常有更详细的错误信息。 - 常见原因包括:HDFS目录权限不足(确保
/user/hive/warehouse目录对执行MapReduce任务的用户可写)、内存不足(可以尝试在mapred-site.xml中调小mapreduce.map.memory.mb和mapreduce.reduce.memory.mb)、类冲突等。
- 去YARN的Web UI (
问题4:Hive CLI中无法使用Ctrl+C中断长时间运行的查询
- 原因:这是Hive CLI的一个已知行为。
- 解决:打开另一个终端,用
yarn application -list找到对应的Hive查询的Application ID,然后用yarn application -kill <Application_ID>来强制杀死任务。然后再回到Hive CLI,它应该会提示任务被中断。
安装和初步配置Hive只是万里长征的第一步。一个稳定运行的Hive环境,是后续进行HiveQL学习、性能调优、集成其他组件(如Hue, Spark)的基础。在下一篇文章中,我们将深入Hive的内部,探讨其数据库、表的类型(如内部表、外部表、分区表、分桶表),以及基础的数据操作,并开始接触一些实用的HiveQL技巧。当你看到第一个查询结果成功返回时,之前所有的繁琐配置都是值得的。
