技术博客
深入浅出:GitHub Actions在项目自动化部署中的应用

深入浅出:GitHub Actions在项目自动化部署中的应用

作者: 万维易源
2024-12-31
GitHub Actions自动部署项目管理代码发布
> ### 摘要 > 本文旨在指导读者如何利用GitHub Actions实现项目自动化部署。通过配置工作流文件,用户可以轻松设置从代码提交到自动部署的完整流程。GitHub Actions支持多种编程语言和平台,能够与不同的服务器环境无缝集成。借助其强大的事件触发机制,开发者可以在每次代码更新时自动执行构建、测试和部署任务,极大提高了开发效率和部署的可靠性。 > > ### 关键词 > GitHub Actions, 自动部署, 项目管理, 代码发布, 服务器应用 ## 一、自动化部署的基础准备 ### 1.1 GitHub Actions概述 GitHub Actions 是 GitHub 提供的一项强大功能,它允许开发者通过定义工作流文件(workflow files)来自动化各种软件开发任务。这些任务可以包括代码构建、测试、部署等。GitHub Actions 的核心优势在于其灵活性和集成性,能够与多种编程语言和平台无缝对接,支持从简单的脚本执行到复杂的多阶段流水线操作。 在 GitHub Actions 中,每个工作流都是由一个或多个作业(jobs)组成的,而每个作业又包含一系列步骤(steps)。这些步骤可以是预定义的操作(actions),也可以是自定义的 Shell 或 PowerShell 脚本。GitHub Actions 支持事件驱动机制,这意味着它可以响应特定的仓库事件(如推送代码、创建标签、合并请求等),从而触发相应的自动化流程。 对于现代软件开发团队来说,GitHub Actions 不仅简化了持续集成和持续交付(CI/CD)的过程,还极大地提高了开发效率和代码质量。通过将重复性的任务自动化,开发者可以专注于更具创造性和挑战性的工作,同时确保每次代码更新都能顺利部署到生产环境中。 ### 1.2 自动化部署的优势 自动化部署是现代软件开发中不可或缺的一部分,它不仅提升了开发效率,还显著增强了项目的可靠性和安全性。通过使用 GitHub Actions 实现自动化部署,开发者可以获得以下几方面的显著优势: 首先,**提高部署速度**。手动部署往往需要耗费大量时间和精力,尤其是在面对频繁的代码更新时。借助 GitHub Actions,开发者只需配置一次工作流文件,之后每次代码提交都会自动触发部署流程,大大缩短了从开发到上线的时间周期。 其次,**减少人为错误**。手动操作容易出现疏忽或误操作,这可能导致部署失败或引入新的问题。自动化部署通过标准化的流程和严格的验证机制,确保每次部署都按照预定的步骤进行,从而降低了出错的概率。 再者,**增强团队协作**。自动化部署使得整个团队能够更加高效地协同工作。不同成员可以在各自的分支上进行开发和测试,而主分支始终保持稳定。当有新的功能或修复被合并时,GitHub Actions 会自动处理后续的构建和部署任务,确保所有成员都能及时获取最新的代码版本。 最后,**提升项目透明度**。通过 GitHub Actions 的日志记录和通知功能,团队可以实时跟踪每次部署的状态和结果。无论是成功还是失败,详细的日志信息都能帮助开发者快速定位问题并采取相应措施,从而保证项目的持续健康发展。 ### 1.3 创建GitHub仓库和配置文件 要开始使用 GitHub Actions 实现自动化部署,首先需要创建一个 GitHub 仓库,并在其中添加必要的配置文件。以下是具体步骤: 1. **创建 GitHub 仓库**:登录到 GitHub 网站,点击右上角的“+”号,选择“New repository”。根据提示填写仓库名称、描述等信息,然后点击“Create repository”按钮完成创建。 2. **初始化仓库**:在本地计算机上打开终端或命令行工具,使用 `git clone` 命令将新创建的仓库克隆到本地。接着,在仓库根目录下创建一个名为 `.github/workflows` 的文件夹,用于存放工作流文件。 3. **编写工作流文件**:在 `.github/workflows` 文件夹中创建一个新的 YAML 文件,例如 `deploy.yml`。这个文件将定义具体的自动化部署流程。以下是一个简单的示例: ```yaml name: Deploy to Server on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '14' - name: Install dependencies run: npm install - name: Build project run: npm run build - name: Deploy to server uses: appleboy/ssh-action@v0.1.7 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: 22 script: | cd /path/to/project git pull origin main npm install npm run build ``` 这段代码定义了一个名为 `Deploy to Server` 的工作流,它会在每次推送到 `main` 分支时触发。工作流包含五个步骤:检出代码、设置 Node.js 环境、安装依赖、构建项目以及通过 SSH 部署到服务器。 ### 1.4 配置GitHub Actions工作流 配置 GitHub Actions 工作流是实现自动化部署的关键步骤。工作流文件通常以 YAML 格式编写,位于仓库的 `.github/workflows` 目录下。一个完整的工作流文件应包含以下几个主要部分: - **触发条件**:指定哪些事件会触发工作流。常见的触发条件包括 `push`、`pull_request`、`release` 等。例如,`on: push` 表示每次推送到仓库时触发工作流。 - **作业定义**:定义一个或多个作业,每个作业代表一个独立的任务。作业可以运行在不同的虚拟机环境中,如 `ubuntu-latest`、`windows-latest` 或 `macos-latest`。 - **步骤定义**:每个作业由一系列步骤组成,每一步可以是一个预定义的操作(action)或自定义的脚本。例如,`uses: actions/checkout@v2` 表示使用官方提供的 `checkout` 操作来检出代码。 - **环境变量和秘密管理**:为了保护敏感信息,GitHub Actions 提供了环境变量和秘密管理功能。用户可以通过仓库设置页面添加秘密(secrets),并在工作流文件中引用它们。例如,`${{ secrets.HOST }}` 表示引用名为 `HOST` 的秘密。 通过合理配置工作流文件,开发者可以根据项目需求定制个性化的自动化部署流程。无论是简单的静态网站还是复杂的微服务架构,GitHub Actions 都能提供强大的支持,确保每次代码更新都能顺利部署到目标环境中。 ### 1.5 工作流中的基本步骤和指令 在 GitHub Actions 工作流中,每个步骤(step)可以执行特定的任务或操作。这些步骤可以是预定义的操作(actions),也可以是自定义的 Shell 或 PowerShell 脚本。以下是几种常见步骤及其对应的指令: 1. **检出代码**:使用 `actions/checkout` 操作从仓库中检出最新代码。这是大多数工作流的第一步,确保后续步骤能够访问最新的代码库。 ```yaml - name: Checkout code uses: actions/checkout@v2 ``` 2. **设置环境**:根据项目需求设置所需的开发环境。例如,对于 Node.js 项目,可以使用 `actions/setup-node` 操作来安装特定版本的 Node.js。 ```yaml - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '14' ``` 3. **安装依赖**:运行必要的命令来安装项目依赖。对于 Node.js 项目,通常是执行 `npm install` 或 `yarn install`。 ```yaml - name: Install dependencies run: npm install ``` 4. **构建项目**:执行构建命令,生成可部署的输出文件。对于前端项目,这可能是运行 `npm run build` 或 `yarn build`。 ```yaml - name: Build project run: npm run build ``` 5. **部署到服务器**:通过 SSH 或其他方式将构建好的项目部署到目标服务器。可以使用第三方操作如 `appleboy/ssh-action` 来简化这一过程。 ```yaml - name: Deploy to server uses: appleboy/ssh-action@v0.1.7 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: 22 script: | cd /path/to/project git pull origin main npm install npm run build ``` 通过合理组合这些步骤,开发者可以构建出复杂且高效的自动化部署流程。每个步骤都可以根据项目需求进行调整和扩展,确保最终的部署过程既安全又可靠。 ## 二、部署环境的搭建与配置 ### 2.1 设置服务器环境 在实现自动化部署的过程中,设置一个稳定且高效的服务器环境是至关重要的。这不仅为后续的部署提供了坚实的基础,还确保了项目的可靠性和性能。首先,选择合适的服务器平台至关重要。根据项目的需求,可以选择云服务提供商如 AWS、Azure 或阿里云等,这些平台提供了丰富的资源和灵活的配置选项。 接下来,安装并配置必要的软件和服务。对于大多数现代 Web 应用程序,通常需要安装以下组件: - **操作系统**:推荐使用轻量级且稳定的 Linux 发行版,如 Ubuntu 或 CentOS。 - **Web 服务器**:Nginx 或 Apache 是常见的选择,它们能够高效地处理 HTTP 请求并提供静态文件服务。 - **应用运行时环境**:根据项目的技术栈选择相应的运行时环境。例如,Node.js 项目需要安装 Node.js 和 npm,Python 项目则需要 Python 解释器和 pip。 - **数据库**:如果项目依赖于数据库,需安装 MySQL、PostgreSQL 或 MongoDB 等数据库管理系统,并进行适当的配置以确保数据的安全性和性能。 此外,还需确保服务器的安全性。通过配置防火墙规则、启用 SSL/TLS 加密以及定期更新系统补丁,可以有效防止潜在的安全威胁。最后,为了便于管理和监控,建议安装日志管理工具(如 ELK Stack)和性能监控工具(如 Prometheus),以便实时掌握服务器的运行状态。 ### 2.2 配置SSH密钥以安全访问服务器 为了确保 GitHub Actions 能够安全地与远程服务器进行通信,配置 SSH 密钥是必不可少的一步。SSH 密钥对由公钥和私钥组成,其中公钥存储在服务器上,而私钥则保存在本地或 GitHub Secrets 中。这种方式不仅提高了安全性,还避免了频繁输入密码的麻烦。 具体步骤如下: 1. **生成 SSH 密钥对**:在本地计算机上打开终端,执行 `ssh-keygen -t rsa -b 4096` 命令生成一对 RSA 密钥。系统会提示你输入保存路径和密码短语(passphrase)。建议将密钥保存在默认位置,并设置一个强密码短语以增加安全性。 2. **添加公钥到服务器**:将生成的公钥(通常是 `~/.ssh/id_rsa.pub` 文件的内容)复制到服务器上的 `~/.ssh/authorized_keys` 文件中。可以通过以下命令完成: ```bash ssh-copy-id user@your-server-ip ``` 3. **测试连接**:使用 `ssh user@your-server-ip` 命令尝试连接到服务器。如果一切正常,你应该能够无需输入密码直接登录。 4. **将私钥添加到 GitHub Secrets**:在 GitHub 仓库的设置页面中找到“Secrets”选项卡,点击“New repository secret”。将私钥内容粘贴到值字段中,并命名为 `SSH_PRIVATE_KEY`。这样,GitHub Actions 就可以在工作流中引用这个秘密变量。 通过以上步骤,你可以确保 GitHub Actions 在执行部署任务时能够安全地访问服务器,同时避免了敏感信息的泄露风险。 ### 2.3 使用GitHub Secrets存储敏感信息 在自动化部署过程中,不可避免地会涉及到一些敏感信息,如服务器 IP 地址、用户名、密码等。为了保护这些信息不被泄露,GitHub 提供了强大的秘密管理功能——GitHub Secrets。通过将敏感信息存储在 GitHub Secrets 中,开发者可以在工作流文件中安全地引用这些变量,而无需将其暴露在代码库中。 以下是使用 GitHub Secrets 的具体步骤: 1. **进入仓库设置页面**:登录到 GitHub,导航至目标仓库的设置页面。在左侧菜单中找到“Secrets and variables”下的“Actions”。 2. **添加新的秘密**:点击“New repository secret”,然后填写秘密名称和值。例如,可以添加名为 `HOST` 的秘密来存储服务器 IP 地址,`USERNAME` 存储用户名,`KEY` 存储 SSH 私钥等。 3. **在工作流文件中引用秘密**:在 YAML 文件中使用 `${{ secrets.SECRET_NAME }}` 语法引用已添加的秘密。例如: ```yaml with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} ``` 通过这种方式,不仅可以保护敏感信息的安全性,还能方便地管理和更新这些变量。当需要更改服务器配置或凭据时,只需在 GitHub Secrets 中修改相应值,而无需修改工作流文件本身。 ### 2.4 编写部署脚本 编写高效的部署脚本是实现自动化部署的关键环节之一。一个好的部署脚本应该简洁明了、易于维护,并且能够处理各种可能的异常情况。根据前面的工作流文件示例,我们可以进一步优化和扩展部署脚本,以满足更复杂的需求。 首先,确保脚本具有良好的结构和注释。每个主要操作都应有清晰的说明,帮助其他开发者理解其作用。例如: ```yaml - name: Deploy to server uses: appleboy/ssh-action@v0.1.7 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: 22 script: | # 更新项目代码 cd /path/to/project git pull origin main # 安装依赖 npm install # 构建项目 npm run build # 重启服务 pm2 restart all ``` 其次,考虑添加错误处理机制。通过捕获潜在的错误并输出详细的日志信息,可以帮助快速定位问题并采取相应措施。例如,在每个关键步骤后添加检查点: ```yaml - name: Deploy to server uses: appleboy/ssh-action@v0.1.7 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: 22 script: | set -e # 如果任何命令失败,则立即退出脚本 # 更新项目代码 cd /path/to/project git pull origin main || { echo "Failed to pull code"; exit 1; } # 安装依赖 npm install || { echo "Failed to install dependencies"; exit 1; } # 构建项目 npm run build || { echo "Failed to build project"; exit 1; } # 重启服务 pm2 restart all || { echo "Failed to restart services"; exit 1; } ``` 最后,还可以引入更多的自动化工具来简化部署流程。例如,使用 PM2 来管理 Node.js 应用程序的进程,或者使用 Docker 来容器化应用程序,从而提高部署的一致性和可移植性。 ### 2.5 测试自动化部署流程 在完成所有配置和脚本编写后,进行全面的测试是确保自动化部署流程顺利运行的最后一道防线。通过模拟真实的部署场景,可以验证每个步骤是否按预期执行,并及时发现和修复潜在的问题。 首先,触发一次完整的部署流程。可以通过向 `main` 分支推送一次小的代码更新来启动工作流。观察 GitHub Actions 的日志输出,确保每个步骤都能顺利完成。特别注意以下几点: - **代码检出**:确认代码是否正确从仓库中检出,并且版本是最新的。 - **环境设置**:检查 Node.js 版本和其他依赖项是否正确安装。 - **构建过程**:确保构建命令成功执行,并生成正确的输出文件。 - **服务器部署**:验证项目是否成功部署到服务器,并且服务能够正常运行。 其次,模拟不同的异常情况。例如,故意引入代码冲突或网络故障,观察工作流是否能够正确处理这些异常,并输出有用的错误信息。通过这种方式,可以增强系统的鲁棒性和容错能力。 最后,邀请团队成员参与测试。多人协作可以发现更多潜在的问题,并提出改进建议。通过不断的迭代和优化,最终实现一个高效、可靠的自动化部署流程,为项目的持续发展奠定坚实的基础。 ## 三、自动化部署的进阶技巧 ### 3.1 编写GitHub Actions脚本 编写 GitHub Actions 脚本不仅仅是简单的代码组合,它更像是为项目注入灵魂的过程。每一个步骤、每一行代码都承载着开发者的智慧与心血。在这个过程中,开发者需要像一位精心雕琢艺术品的工匠,确保每个细节都完美无缺。 首先,编写一个高效且可靠的 GitHub Actions 脚本需要从项目的实际需求出发。以 Node.js 项目为例,我们可以进一步优化和扩展部署脚本,使其更加灵活和强大。通过引入更多的自动化工具,如 PM2 来管理应用程序的进程,或者使用 Docker 容器化应用程序,可以显著提高部署的一致性和可移植性。 ```yaml - name: Deploy to server uses: appleboy/ssh-action@v0.1.7 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: 22 script: | set -e # 如果任何命令失败,则立即退出脚本 # 更新项目代码 cd /path/to/project git pull origin main || { echo "Failed to pull code"; exit 1; } # 安装依赖 npm install || { echo "Failed to install dependencies"; exit 1; } # 构建项目 npm run build || { echo "Failed to build project"; exit 1; } # 使用 PM2 管理服务 pm2 restart all || { echo "Failed to restart services"; exit 1; } ``` 此外,编写良好的注释是至关重要的。清晰的注释不仅有助于其他开发者理解脚本的作用,还能在未来的维护中节省大量时间。例如,在每个关键步骤后添加详细的说明,帮助团队成员快速上手并进行调试。 最后,不要忽视错误处理机制的重要性。通过捕获潜在的错误并输出详细的日志信息,可以帮助快速定位问题并采取相应措施。这不仅能提升系统的鲁棒性,还能增强团队的信心,确保每次部署都能顺利进行。 ### 3.2 自动化部署的最佳实践 自动化部署不仅仅是为了简化流程,更是为了提升整个团队的工作效率和项目的可靠性。在这个过程中,遵循一些最佳实践可以让我们的工作更加顺畅,避免不必要的麻烦。 首先,**保持工作流文件的简洁和模块化**。将复杂的工作流拆分为多个独立的作业(jobs),每个作业负责特定的任务。这样不仅可以提高代码的可读性和可维护性,还能更好地利用并行执行的优势,缩短整体部署时间。 其次,**合理配置触发条件**。根据项目的实际情况,选择合适的触发事件。例如,对于主分支上的代码更新,可以选择 `on: push` 触发;而对于拉取请求(pull request),则可以使用 `on: pull_request`。通过这种方式,确保每次代码变更都能及时触发相应的部署任务,同时避免不必要的资源浪费。 再者,**充分利用环境变量和秘密管理功能**。敏感信息如服务器 IP 地址、用户名、密码等应存储在 GitHub Secrets 中,并在工作流文件中安全引用。这不仅能保护敏感数据的安全性,还能方便地管理和更新这些变量,而无需修改工作流文件本身。 最后,**定期审查和优化工作流**。随着项目的不断发展,原有的部署流程可能会变得不再适用。因此,建议每隔一段时间对工作流进行一次全面审查,查找并修复潜在的问题,引入新的工具和技术,持续优化部署流程,确保其始终处于最佳状态。 ### 3.3 常见问题与解决方案 在实现自动化部署的过程中,难免会遇到各种各样的问题。面对这些问题时,我们需要冷静分析,找到最有效的解决方案。以下是几种常见的问题及其应对策略: 1. **SSH 连接失败**:这是最常见的问题之一,通常由 SSH 密钥配置不当引起。确保私钥已正确添加到 GitHub Secrets 中,并且公钥已正确添加到服务器的 `~/.ssh/authorized_keys` 文件中。此外,检查防火墙规则是否允许来自 GitHub 的连接,必要时调整相关设置。 2. **构建失败**:构建失败可能是由于依赖项缺失或版本不兼容引起的。确保所有必要的依赖项都已正确安装,并且使用的工具和库版本与项目要求一致。可以通过在本地环境中模拟相同的构建过程来排查问题,找出具体的错误原因。 3. **部署超时**:如果部署过程耗时过长,可能会导致超时错误。此时可以考虑优化部署脚本,减少不必要的操作步骤,或者增加 GitHub Actions 的运行时间限制。另外,检查网络连接是否稳定,确保远程服务器能够快速响应。 4. **权限不足**:某些操作可能需要更高的权限才能执行。确保用于部署的用户具有足够的权限,例如,可以尝试使用 `sudo` 提升权限,或者通过配置服务器上的用户权限来解决问题。 5. **日志记录不完整**:有时日志信息不够详细,难以帮助我们快速定位问题。为此,可以在关键步骤后添加更多的日志输出语句,确保每次操作的结果都能被准确记录下来。此外,启用 GitHub Actions 的详细日志模式,获取更丰富的调试信息。 通过不断积累经验,总结常见问题及其解决方案,我们可以逐步提高自动化部署的成功率,确保每次部署都能顺利完成。 ### 3.4 监控与日志记录 监控和日志记录是自动化部署中不可或缺的一部分。它们不仅是发现问题的有力工具,更是保障系统稳定运行的重要手段。通过实时跟踪每次部署的状态和结果,团队可以迅速响应异常情况,确保项目的持续健康发展。 首先,**启用详细的日志记录**。GitHub Actions 提供了丰富的日志功能,可以记录每个步骤的执行情况和输出信息。通过仔细分析这些日志,开发者可以快速定位问题并采取相应措施。此外,还可以将日志信息发送到外部日志管理系统(如 ELK Stack 或 Splunk),以便更方便地进行集中管理和查询。 其次,**设置通知机制**。当部署成功或失败时,及时通知相关人员是非常重要的。可以通过集成第三方通知服务(如 Slack、Microsoft Teams 或电子邮件)来实现这一目标。这样,团队成员可以在第一时间了解部署状态,及时采取行动。 再者,**监控服务器性能**。除了关注部署过程本身,还需要密切监控服务器的性能指标,如 CPU 使用率、内存占用、磁盘 I/O 等。通过安装性能监控工具(如 Prometheus 或 Grafana),可以实时掌握服务器的运行状态,提前发现潜在的性能瓶颈,确保系统始终处于最佳状态。 最后,**定期审查和优化监控策略**。随着项目的不断发展,原有的监控策略可能会变得不再适用。因此,建议每隔一段时间对监控配置进行一次全面审查,查找并修复潜在的问题,引入新的工具和技术,持续优化监控体系,确保其始终处于最佳状态。 ### 3.5 持续优化与迭代 自动化部署是一个不断进化的过程,只有通过持续优化和迭代,才能真正发挥其最大潜力。每一次改进都是对现有流程的完善,每一次创新都是对未来挑战的准备。 首先,**收集反馈意见**。团队成员和最终用户是最直接的感受者,他们的反馈意见往往能为我们提供宝贵的改进建议。通过定期召开会议或使用在线协作工具(如 Jira 或 Trello),收集大家的意见和建议,共同探讨如何进一步优化部署流程。 其次,**引入新技术和工具**。技术的发展日新月异,不断涌现的新工具和框架可以为我们的工作带来更多的可能性。例如,Docker 和 Kubernetes 的结合可以实现更高效的容器化部署,GitOps 流程可以简化基础设施的管理。通过学习和应用这些新技术,我们可以不断提升自动化部署的能力和效率。 再者,**优化部署策略**。随着项目的规模不断扩大,原有的部署策略可能会变得不再适用。此时可以考虑引入蓝绿部署(Blue-Green Deployment)或滚动更新(Rolling Update)等高级部署策略,确保每次更新都能平滑过渡,最大限度地减少对用户的影响。 最后,**建立知识库和文档**。将每次优化的经验和教训记录下来,形成一个完整的知识库和文档体系。这不仅能帮助新成员快速上手,还能为未来的改进提供参考依据。通过不断完善这个知识库,我们可以逐步建立起一套成熟且高效的自动化部署体系,为项目的持续发展奠定坚实的基础。 通过不断的探索和实践,我们将逐渐掌握更多关于自动化部署的知识和技巧,为项目的成功贡献自己的力量。 ## 四、总结 通过本文的详细阐述,读者可以全面了解如何利用 GitHub Actions 实现项目自动化部署。从基础准备到进阶技巧,每个环节都至关重要。首先,GitHub Actions 的灵活性和集成性使其成为现代软件开发中不可或缺的工具,能够显著提高部署速度并减少人为错误。其次,通过合理配置工作流文件,开发者可以根据项目需求定制个性化的自动化流程,确保每次代码更新都能顺利部署到生产环境中。 在实际操作中,设置服务器环境、配置 SSH 密钥以及使用 GitHub Secrets 存储敏感信息是实现安全高效部署的关键步骤。编写高效的部署脚本和引入错误处理机制,则进一步增强了系统的鲁棒性和可靠性。此外,遵循最佳实践如保持工作流简洁、合理配置触发条件以及充分利用环境变量,有助于提升整体效率。 最后,持续优化与迭代是自动化部署成功的重要保障。通过收集反馈意见、引入新技术和工具、优化部署策略,并建立完善的知识库和文档体系,团队可以不断改进和完善自动化部署流程,为项目的持续健康发展奠定坚实基础。
加载文章中...