
1. 下载Tomcat10之前你必须先搞清楚的版本问题很多人下载Tomcat10的时候第一反应是去搜索引擎找“Tomcat10下载”然后随便点开一个下载站把zip包拿下来解压就准备部署项目。这个流程在Tomcat 9及以前基本没问题但到了Tomcat 10这里有个非常关键的变化如果你不知道项目大概率跑不起来。Tomcat 10和Tomcat 9之间最本质的区别不是版本号差了一位而是整个Java Web的命名空间从javax.*迁移到了jakarta.*。这件事的来龙去脉得从Java EE归属权说起。当年Oracle把Java EE捐给了Eclipse基金会但“Java”这个商标Oracle还攥在手里所以Eclipse基金会接手后把Java EE改名成了Jakarta EE规范里所有的包名也一并调整javax.servlet变成了jakarta.servletjavax.servlet.http变成了jakarta.servlet.http。Tomcat 9实现的是Java EE 8规范依然用javaxTomcat 10实现的是Jakarta EE 9/10规范全面换成了jakarta。这就带来一个非常现实的后果你在Tomcat 9上跑得好好的war包直接丢进Tomcat 10大概率报java.lang.NoClassDefFoundError: javax/servlet/...或者ClassNotFoundException。不是你的代码出了问题而是Tomcat 10里根本不存在javax.servlet这个包了。所以如果你是老项目迁移第一步不是下载而是先想清楚项目里所有依赖Servlet API的代码、第三方库、注解是否已经适配了jakarta.*命名空间。如果没适配下载安装完也只是拿到一个跑不起来的环境。另外Tomcat 10本身还有细分版本。10.0.x实现的是Servlet 5.0规范对应Jakarta EE 910.1.x实现的是Servlet 6.0规范对应Jakarta EE 10。官方维护策略里10.0.x已经进入EOL停止维护阶段新项目直接选10.1.x别犹豫。至于Tomcat 11那是后话需要JDK 17起步普通项目暂时没必要追。1.1 JDK版本对应关系别装完了才发现不兼容Tomcat是用Java写的运行它必须依赖JDK。不同Tomcat版本对JDK版本的要求不同这个在Apache官网每个版本的文档里都有说明但很多教程从来不提导致有人用JDK 8去跑Tomcat 10.1启动直接报UnsupportedClassVersionError。我把对应关系整理成一张表下载前先对照一下Tomcat版本最低JDK版本对应Servlet规范对应Jakarta EE版本Tomcat 9.0.xJDK 8Servlet 4.0Java EE 8Tomcat 10.0.xJDK 8Servlet 5.0Jakarta EE 9Tomcat 10.1.xJDK 11Servlet 6.0Jakarta EE 10Tomcat 11.0.xJDK 17Servlet 6.1Jakarta EE 11注意Tomcat 10.0虽然官方说最低JDK 8能跑但10.1.x明确要求JDK 11。我自己的经验是既然都上Tomcat 10了JDK至少用11有条件直接上17或21。原因不光是版本兼容JDK 11之后的垃圾回收器选择、ZGC等新特性在长连接高并发场景下表现更好而且很多现代框架Spring Boot 3、Spring Framework 6本身也要求JDK 17起步你要是还用JDK 8后面框架版本一升级全是坑。检查自己JDK版本的命令很简单java -version输出里如果有“version 1.8.0_xxx”说明是JDK 8跑Tomcat 10.1会直接报错。如果输出是“version 11.x”或“version 17.x”那没问题。另外JAVA_HOME环境变量也要确认指向的是JDK安装目录而不是JRE目录。很多Windows机器上装了多个Java版本系统里java -version显示的是新版本但JAVA_HOME还指向老版本Tomcat启动用的是JAVA_HOME这样就会莫名其妙报错。1.2 选哪个发行版zip、tar.gz、Windows Installer还是源码Tomcat官网的Binary Distributions下载区每个版本都会给出一堆文件格式新手很容易懵。我逐个说下用途。zipWindows和通用系统用的压缩包解压即用不需要安装程序。这是最推荐的方式环境干净不污染系统注册表删掉文件夹就是卸载。tar.gzLinux/macOS下的压缩包解压即用。Windows Installer.exe安装包会帮你注册Windows服务、写注册表适合生产环境里要让Tomcat以系统服务方式开机自启的场景。但这也意味着卸载时容易残留新手不推荐。src开头的源码包一般开发者不用下除非你要自己编译或看源码。我的建议是无论Windows还是Linux一律用解压版。原因很简单Tomcat本身是绿色软件解压就能跑没必要走安装程序那层封装。Windows下如果后面需要注册成服务可以用bin目录里的tomcat10w.exe或者命令行手动注册效果一样还更可控。2. 官方下载渠道与文件校验别去第三方站点碰运气确定好版本和文件格式后下载地址这个问题我要多说几句。搜“Tomcat10下载”出来的网站很多都是第三方下载站有的会捆绑广告有的会改文件内容最离谱的是我见过有人从某下载站拿到的所谓“Tomcat 10”解压出来是Tomcat 7改了后缀。所以认准官方源是第一步。Tomcat的官方下载页面是Apache Tomcat官网的/download-10.cgi路径。进去之后你会看到几个Mirror镜像链接随便选一个就行。Apache官方推荐的镜像站会按地区给你自动分配国内一般推荐清华、阿里云或者华为云的镜像速度快且稳定。官方下载页的from下拉列表里就能选。如果你需要下载历史版本不要去主下载页翻——那里永远只挂当前最新版。历史版本在archive.apache.org/dist/tomcat/tomcat-10/目录下按版本号一层一层找。2.1 文件命名里的alpha、beta、RC、GA是什么意思在下载页你会看到类似apache-tomcat-10.1.39、apache-tomcat-10.1.39-deployer、apache-tomcat-10.1.39-fulldocs这样的文件另外还会看到v10.1.39-alpha、v10.1.39-beta、v10.1.39-RC1这些目录。这些后缀的意思是alpha内部测试版功能不完整Bug遍地千万别用于任何环境。beta公开测试版功能基本完成但还不够稳定。RCRelease Candidate候选发布版基本和正式版功能一致理论上没有大问题了。GA正式发布版文件名里通常不写GA直接写版本号比如apache-tomcat-10.1.39就是GA版。deployerWeb应用部署工具包一般不用下载。实际下载时认准不带alpha/beta/RC的版本号目录里面的文件就是GA版。目录结构通常是tomcat-10/v10.1.39/bin/下面放着所有二进制包。2.2 下载后一定要做SHA512校验这一点极少有教程提但实际生产环境中非常重要。Apache所有官方文件都提供了SHA512校验值就是防止文件在传输过程中被篡改或者下载不完整。你在下载页的bin目录里每个.tar.gz或.zip文件旁边都有一个.sha512后缀的同名文件里面是一串哈希值。Windows下校验方法certutil -hashfile apache-tomcat-10.1.39.tar.gz SHA512Linux/macOS下校验方法shasum -a 512 apache-tomcat-10.1.39.tar.gz把输出的哈希值和.sha512文件里的比对一模一样就是没问题的。这一步其实花不了30秒但能避免绝大多数“解压后启动报错怎么查都是文件损坏”的问题。尤其是用浏览器多线程下载器断点续传的文件很容易出现“表面完整、实际缺字节”的情况。3. Windows环境安装Tomcat10从解压到服务注册Windows下安装Tomcat10整个流程可以浓缩成四步解压、配环境变量、启动、验证。但每一步都有细节我按顺序给你捋一遍顺便把容易踩的坑指出来。3.1 前置准备配置JAVA_HOME和CATALINA_HOME先确认JDK已安装且JAVA_HOME环境变量已设置。Windows下设置环境变量的路径是右键“此电脑” - 属性 - 高级系统设置 - 环境变量。这里有个隐藏的坑JAVA_HOME到底是配到“用户变量”还是“系统变量”。如果你这台机器只有你一个人用Java配到用户变量就够Tomcat启动时会读取当前用户的JAVA_HOME。但如果你的Windows服务是以Local System账户运行的它读不到用户变量只能读系统变量。所以为了少踩坑JAVA_HOME和CATALINA_HOME统一配到系统变量。CATALINA_HOME指的就是你解压Tomcat后那层目录的完整路径。举个例子我把Tomcat解压到了D:\dev\apache-tomcat-10.1.39那么CATALINA_HOME就是D:\dev\apache-tomcat-10.1.39不是D:\dev也不是里面的bin目录。很多教程不解释清楚有人直接把CATALINA_HOME配到了D:\dev\apache-tomcat-10.1.39\bin结果startup.bat一执行就报找不到catalina.bat。配置好后在Path变量里加上%CATALINA_HOME%\bin这样后续可以直接在命令行输入startup启动不用每次cd到tomcat目录。3.2 目录结构速览搞清楚每个文件夹是干嘛的解压完成后的目录结构大致是apache-tomcat-10.1.39/ ├── bin/ # 启动、关闭、配置脚本 ├── conf/ # 核心配置文件 ├── lib/ # Tomcat及Web应用共用的Jar包 ├── logs/ # 日志输出目录 ├── temp/ # 临时文件 ├── webapps/ # 放置Web应用war包或目录 └── work/ # JSP编译后的class文件bin里最常用的几个文件startup.batWindows启动脚本shutdown.batWindows关闭脚本catalina.bat run前台启动日志直接打印在窗口里排查问题更方便tomcat10w.exeTomcat服务管理器图形界面service.bat注册/卸载Windows服务的命令行工具conf目录里最重要的文件是server.xml端口配置、连接器参数、Host配置都在里面。刚装好的Tomcat不需要改它也能跑起来当你需要部署实际项目时再研究。3.3 启动Tomcat闪退问题排查双击bin\startup.bat正常情况下会弹出一个新的命令窗口输出类似Tomcat started.然后你打开浏览器访问http://localhost:8080能看到默认首页说明成功。但Windows上最常见的现象是双击startup.bat后窗口一闪而过什么都没看到。这不是Tomcat启动成功又自动关闭了而是脚本执行出错但窗口在你看到错误信息之前就关了。解决办法是先打开一个命令行窗口手动cd到Tomcat的bin目录直接执行startup.bat。这样命令窗口不会自动关错误信息就留在屏幕上了。绝大多数闪退的原因是JAVA_HOME没配好或者JAVA_HOME指向了不存在的路径。脚本第一件事就是去找JAVA_HOME找不到就直接退出。如果日志显示UnsupportedClassVersionError说明JDK版本不匹配回看第一节的版本对照表。如果显示“端口8080被占用”那得先找到占用端口的进程并处理掉方法我在后面专门讲。另一个排查技巧用catalina.bat run代替startup.bat启动。run模式是前台运行控制台会实时打印Tomcat的启动日志包括每个LifecycleListener初始化的信息哪里出错一目了然。我在Windows上调试Tomcat问题时几乎都会用这个命令。3.4 把Tomcat注册成Windows服务开发环境里双击startup.bat没问题但生产环境如果跑在Windows Server上你得让Tomcat开机自启、崩溃后自动重启这时候就要注册成Windows服务。Tomcat自带了service.bat脚本。管理员权限打开命令行cd到bin目录执行service.bat install Tomcat10服务名称你可以自己取默认叫Tomcat10。注册成功后打开“服务”管理窗口services.msc能看到这个服务。启动方式建议改成“自动延迟启动”避免开机时和其他服务抢资源。Tomcat注册成服务后默认用Local System账户运行此时它会读取系统变量里的JAVA_HOME和CATALINA_HOME如果在系统变量里没配服务启动时就会报错。这也是为什么前面我强调要配到系统变量而不是用户变量。卸载服务用service.bat remove Tomcat10还有个图形化的服务配置工具tomcat10w.exe可以调整JVM内存参数、配置日志、设置启动模式。双击运行在“Java”选项卡里可以设置初始堆大小Initial memory pool和最大堆大小Maximum memory pool生产环境建议初始堆和最大堆设为相同值避免JVM运行时频繁扩容。4. Linux环境安装Tomcat10命令行完整实操Linux服务器上安装Tomcat10比Windows简单但不讲究的话也会踩坑。尤其是权限问题这里多说一句永远不要用root直接跑Tomcat。生产规范里这是大忌root启动的Tomcat一旦被入侵整个服务器都会被控制。正确做法是单独建一个系统用户运行Tomcat。4.1 下载、解压、创建独立用户以CentOS/RHEL系和Ubuntu/Debian系为例通用的操作流程如下。先下载官方tar.gz包wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.39/bin/apache-tomcat-10.1.39.tar.gz如果dlcdn这个CDN在你网络环境下速度很慢可以用清华镜像站wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-10/v10.1.39/bin/apache-tomcat-10.1.39.tar.gz下载后解压到指定目录。我习惯放在/opt/tomcat下但为了方便将来升级会先解压到/opt/tomcat-10.1.39再把/opt/tomcat软链到它mkdir -p /opt tar -zxvf apache-tomcat-10.1.39.tar.gz -C /opt ln -s /opt/apache-tomcat-10.1.39 /opt/tomcat创建独立系统用户useradd -r -s /sbin/nologin tomcat-r表示创建系统账户-s /sbin/nologin表示该账户不能登录shell只能用于运行进程这是安全基线要求。然后赋予Tomcat目录权限给这个用户chown -R tomcat:tomcat /opt/apache-tomcat-10.1.39 chmod -R 755 /opt/apache-tomcat-10.1.394.2 配置JAVA_HOME与环境变量Linux下JAVA_HOME一般写在/etc/profile或/etc/profile.d/tomcat.sh里。如果你用默认JDK路径先确认一下Java安装在哪readlink -f $(which java)比如输出是/usr/lib/jvm/java-17-openjdk-amd64/bin/java那JAVA_HOME就是/usr/lib/jvm/java-17-openjdk-amd64。但Tomcat启动脚本本身不强制读系统的JAVA_HOME环境变量它更推荐你把JAVA_HOME写到bin/setenv.sh里。如果存在bin/setenv.shTomcat启动脚本会自动加载它。这样每个Tomcat实例可以独立指定JDK路径不会影响机器上其他Java程序。创建/opt/tomcat/bin/setenv.sh#!/bin/bash export JAVA_HOME/usr/lib/jvm/java-17-openjdk-amd64 export CATALINA_HOME/opt/tomcat export CATALINA_BASE/opt/tomcat注意写完后要给执行权限chmod x /opt/tomcat/bin/setenv.sh还有一个容易忽视的点Tomcat默认的JVM内存参数生产环境一定要在setenv.sh里覆盖千万不要改catalina.sh——因为每次升级Tomcatcatalina.sh会被新版覆盖你的自定义配置就丢了。setenv.sh不会被覆盖它是官方预留的自定义入口。我通常会加export CATALINA_OPTS-Xms1g -Xmx2g -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m这里的CATALINA_OPTS只影响Tomcat本身的JVM参数不会影响部署在里面的Web应用通过JAVA_OPTS读取的内容区分清楚。4.3 用systemd管理Tomcat实现开机自启现代Linux发行版普遍使用systemd。创建/etc/systemd/system/tomcat.service[Unit] DescriptionApache Tomcat 10 Web Application Container Afternetwork.target [Service] Typeforking Usertomcat Grouptomcat EnvironmentJAVA_HOME/usr/lib/jvm/java-17-openjdk-amd64 EnvironmentCATALINA_HOME/opt/tomcat EnvironmentCATALINA_BASE/opt/tomcat EnvironmentCATALINA_PID/opt/tomcat/temp/tomcat.pid ExecStart/opt/tomcat/bin/startup.sh ExecStop/opt/tomcat/bin/shutdown.sh Restarton-failure RestartSec10 [Install] WantedBymulti-user.target这里Typeforking很关键因为startup.sh启动后父进程会退出子进程继续在后台运行systemd必须知道这个特性才能正确管理Tomcat进程。CATALINA_PID用来记录进程ID供shutdown时判断要结束谁。配置好之后执行systemctl daemon-reload systemctl start tomcat systemctl enable tomcatenable就是设置开机自启。查看运行状态systemctl status tomcat4.4 防火墙与远程访问配置Linux上装完Tomcat本机能访问curl localhost:8080但外面访问不了九成是防火墙拦了。开放端口CentOS/RHEL系firewall-cmd --permanent --add-port8080/tcp firewall-cmd --reloadUbuntu/Debian系使用ufwufw allow 8080/tcp另外还要确认你的云服务器安全组策略里入方向放行了8080端口这个问题在云上部署时非常容易忽略本地防火墙开了云平台控制台没放行照样连不上。5. 启动验证与首轮检查确定Tomcat真的在干活装好Tomcat只是起点能启动、能访问、能部署应用才是终点。这一节讲讲启动后的验证路径和几个高频检查项。5.1 验证Tomcat是否真正可用启动成功后浏览器访问http://localhost:8080能看到Apache Tomcat默认首页。如果你在远程服务器上把localhost换成服务器IP。默认首页上有几个链接Server Status、Manager App、Host Manager点击它们都会弹出一个登录框这是Tomcat自带的Web管理界面。先别急着登录默认配置下你是进不去的因为管理界面默认只允许本地访问并且没有任何可用的用户。所以如果你只是想确认Tomcat装了没看到首页就够了。更彻底的验证方法是用curl走一遍HTTP请求curl -I http://localhost:8080能看到类似HTTP/1.1 200的响应头说明Tomcat的HTTP连接器正常工作。如果返回404可能是端口配错或者应用没部署对如果拒绝连接说明Tomcat进程可能没起来去查日志。5.2 日志是最好的老师静态看这三个文件很多人不爱看日志遇到问题就百度但Tomcat的日志其实是最好懂的路径就在logs目录下。catalina.outTomcat启动和运行的核心日志包含JVM、连接器、生命周期事件。启动报错基本都在这里。localhost.log每个Web应用在启动和停止时的详细日志。如果某个应用部署失败信息会出现在这个文件里。manager.log通过管理界面部署应用相关操作的日志。排查问题的标准流程是先看catalina.out有没有Exception再看localhost.log里有没有Deployment of web application ... has finished这行如果没看到这行说明应用启动过程中出错了。日志文件默认按天滚动老日志会带日期后缀保留在logs目录里别找错文件。5.3 修改默认端口与JVM内存参数默认8080端口在生产环境很可能要改成别的端口。改端口在conf/server.xml里找到Connector节点Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 /把port改成你想要的比如80。但Linux下1024以内的端口需要root权限才能绑定而Tomcat又不建议用root跑所以要么把端口改成8081以上的高位端口要么用nginx做反向代理转发到8080后者是生产环境更常见的做法。改完端口记得重启bin/shutdown.sh bin/startup.shJVM内存参数按4.2节说的写在setenv.sh里。5.4 部署第一个应用实战一下部署Web应用到Tomcat有三种方式直接把war包扔进webapps目录Tomcat会自动解压并部署。解压成目录把整个目录放进webapps。在conf/server.xml里的Host节点添加Context标签指定docBase指向应用目录这种方式不推荐因为修改server.xml需要重启Tomcat而前两种方式可以热部署。第一个方式最常用。把编译好的war包复制到webapps目录cp myapp.war /opt/tomcat/webapps/Tomcat会在几秒内自动解压并部署。观测localhost.log如果出现Deployment of web application archive [myapp.war] has finished说明部署成功。然后访问http://server-ip:8080/myapp/就能看到应用了。注意war包的文件名就是访问路径的上下文根Context Pathmyapp.war对应的访问路径是/myapp不是根路径。如果你想让它直接映射到根路径http://server-ip:8080/把war包改名为ROOT.war覆盖默认的ROOT应用即可。6. 安装过程中最常见的坑与排查思路最后这部分我把这几年帮别人排查Tomcat安装问题时遇到的高频坑做一个集中梳理。每一条都是真实案例不是空谈。6.1 端口被占用启动报错却不知道谁占了8080报错信息通常长这样SEVERE [main] org.apache.catalina.core.StandardService.initInternal Failed to initialize connector [Connector[HTTP/1.1-8080]] java.net.BindException: Address already in useWindows下找出占用8080的进程netstat -ano | findstr 8080最后一列是PID然后tasklist | findstr 1234确认进程身份后如果是僵尸Java进程可以taskkill /F /PID 1234Linux下用ss -lntp | grep 8080或者老牌的netstat -lntp | grep 8080会显示进程名和PID。如果是你自己之前启动的Tomcat没关干净直接:pkill -f catalina.*start但如果8080被一个不认识的进程占用千万别乱kill先确认它是什么再处理。另外还有个常见场景Nginx或其他Web服务占用了8080。这时你不想停掉已有服务还不如给Tomcat换个端口见5.3节。6.2 启动闪退但没看到任何报错信息Windows下双击startup.bat闪退但命令行执行却不报错这种诡异情况我遇到过好几次。原因通常是JAVA_HOME配置里带了多余的空格或引号。比如JAVA_HOMEC:\Program Files\Java\jdk-17 # 错误示范正确写法是不带引号JAVA_HOMEC:\Program Files\Java\jdk-17路径里含空格没问题关键是环境变量值不要加引号。Tomcat的脚本会在内部自己处理带空格的路径你加了引号反而会让它拼接出错误的路径。另一个闪退原因是CATALINA_HOME配错了层。有人把CATALINA_HOME直接指向了bin目录导致startup.bat去bin\bin里找catalina.bat找不到就秒退。检查方式很简单命令行输入echo %CATALINA_HOME% echo %JAVA_HOME%看看分别输出什么一眼就能发现问题。6.3 远程访问Tomcat管理界面总是403访问https://server:8443/manager/html时提示403 Access Denied很多人的第一反应是没配用户。其实Tomcat默认有双重保护一是在conf/tomcat-users.xml里必须配置manager-gui角色和用户二是conf/Catalina/localhost/manager.xml里默认限制了访问IP只允许127.0.0.1和::1本机地址访问。排查办法先改tomcat-users.xml在tomcat-users节点里加role rolenamemanager-gui/ user usernameadmin passwordyour-strong-password rolesmanager-gui/然后重启Tomcat。如果还是403去看manager应用的META-INF/context.xml文件在webapps/manager/META-INF/context.xml里里面有类似Valve classNameorg.apache.catalina.valves.RemoteAddrValve allow127\.\d\.\d\.\d|::1|0:0:0:0:0:0:0:1 /这段配置只允许本地访问。把它注释掉或者把allow改成你办公网的IP段比如192\.168\.1\.\d。改完重启才能生效。6.4 Tomcat 10应用迁移的通用报错处理前面反复强调过javax到jakarta的差异。如果你确实需要把老项目迁到Tomcat 10最快速不是手动改代码而是用官方提供的迁移工具。Apache Tomcat官方维护了一个叫tomcat-jakartaee-migration的工具它可以自动把war包或jar包里的javax.servlet等包名批量改写为jakarta.servlet。下载地址在Apache官网的/tomcat/jakartaee-migration/页面。基本用法java -jar tomcat-jakartaee-migration-*.jar 旧应用.war 迁移后.war工具会扫描class文件里的字节码引用、配置文件、JSP标签库描述符等替换成对应的jakarta.*命名空间。它处理完的war包再丢到Tomcat 10里基本能跑通。但要注意迁移工具不是万能的。如果你的应用里有自己硬编码的字符串去反射加载javax.servlet.Filter之类的类工具改不到字符串常量需要自己全局搜一遍。另外第三方库比如老的JSTL实现、老的Shiro、老版本Spring如果没有适配Jakarta EE 9迁移工具也无能为力这种只能升级第三方库版本。我的建议是迁移前先用工具处理war包放Tomcat 10跑起来看localhost.log和catalina.out报错把失败的第三方库一个个升级。实际迁移一个中等规模项目如果第三方库版本都比较新大半天能搞定如果依赖了大量老库可能得按天计。6.5 频繁重启后端口有时钟偏差导致的启动失败这个坑相对小众但在云服务器上遇到过。Tomcat启动时会校验Session ID生成的随机数种子如果服务器时钟跳变导致熵不足SecureRandom初始化会非常慢甚至超时启动日志里表现为卡在Creation of SecureRandom instance很久。解决办法是在setenv.sh里加export CATALINA_OPTS$CATALINA_OPTS -Djava.security.egdfile:/dev/./urandom在Linux上可以显著加快Tomcat启动速度。Windows下如果遇到启动奇慢也可以加上对应的系统属性。这个参数不会影响安全性只是换一个更高效的随机数生成源。结语最后说点实际的。我在部署Tomcat时的习惯是下载完先不改任何配置直接启动看默认首页确认环境没问题再去做端口修改、内存参数调整、应用部署这样能最大程度减少“一上来就改了一堆配置最后不知道哪步改错了”的情况。安装Tomcat本身不难但下载前版本选错、环境变量配错、端口被占这种问题遇到一次就得折腾半天。希望这篇教程能帮你把每一步都走得明明白白少踩几个坑。