我帮助澳大利亚的一个大型游戏网站。我们每周每天从当地时间早上 7 点到第二天凌晨 1 点举办比赛。自网站发布以来,我们从未缺席过一天。自然,这使得维护工作变得极其困难,我们发现我们的暂存服务器比我们的生产分支提前了 50 次提交。通常,主要开发人员必须非常早起床来合并分支并确保一切正常。
我们一直在尝试使我们的登台站点尽可能与生产站点相似,但我们只能使它们如此相似。
我们的网站基于 Laravel,并配有 Node.JS 服务器以实现实时功能。我们使用 Laravel Forge。
有人对我们如何更频繁地推送更新有什么建议吗?我们愿意听取任何建议。
答案1
您可以做很多事情来改进部署过程。 其中一些是:
确保您的代码经过充分测试。
理想情况下,您应该拥有 100% 的单元测试覆盖率,以及针对每种可能的情况的集成测试。
如果您还没有得到这个,您应该放下一切来处理这个问题。
研究行为驱动开发。
拥有完整的测试套件将允许您...
运行持续集成。
每当有人提交更改时,CI 就可以自动地在其上运行测试套件。如果测试套件通过,则可以立即部署(或安排部署)。对于不需要对数据库进行任何重大更改的更改,仅此一项就可以为您节省大量时间和精力。
一旦出现问题,CI 还可以给你一键回滚。
CI 是很多如果您的测试套件不完整且不正确,那么它就没那么有用,因为整个前提都取决于能够以自动化方式验证您的代码。
进行原子更新。
理想情况下,您不应该只是在生产服务器上将新文件复制到旧文件上。相反,请使用诸如 capistrano 之类的工具,它将每个文件复制到新位置,然后使用符号链接指向所需的部署。回滚是即时的,因为它只需更改符号链接以指向先前的部署即可。(尽管这不一定涵盖您的数据库迁移。)
还要研究 Docker 等容器是否可以帮助您。
进行更小、更频繁的改变。
无论你有测试、CI 还是什么都没有,这一点都可以给你带来很大的帮助。每个更改都应该有自己的 git 分支,部署应该尽可能少地进行更改。由于更改较少,部署过程中出错的可能性也较小。
就这一点而言,尽可能使更改更加独立。如果您对奥马哈游戏进行了更改,并且它不会影响德州扑克、5 张牌梭哈或其他任何游戏,那么这是唯一需要暂停维护的游戏。
分析任何长期运行的事情。
您提到部署的某些部分需要很长时间。这是大概数据库架构更改。让 DBA 查看您的数据库以及每次架构更改,以了解哪些方面可以提高性能,这是非常值得的。
让主题专家查看部署中占用大量时间的任何其他部分。
工作时间不固定。
您可能已经这样做了,但值得一提。开发人员(和系统管理员!)不再需要“朝九晚五”地工作,尤其是对于 24x7 全天候运营而言。如果要求某人花费夜间时间照看部署、修复任何问题,然后保持白天的作息时间,那么您的期望是不切实际的,而且您正在让这个人精疲力竭。
答案2
从您所说的情况来看,您每天凌晨 1 点到早上 7 点都有维护时段,问题似乎不是时间问题,而是方便问题。这很正常,许多人只是将其作为业务的一部分来处理。
您可以拥有 2 个(或更多)后端系统,前端可将流量引导至当前正在运行的系统。一旦您确定某个版本可以正常运行,就可以告诉前端切换到新系统。这应该很容易编写脚本,并且只需很短的时间。
现在,您可以选择保留旧系统,以便可以退出,或者将其更新,以便可以将其用作实时系统的备用,直到构建/测试下一次更新为止。
答案3
修改其他答案:你应该遵循蓝绿部署模型。当您想要发布新版本时,您可以将其部署到内部暂存网站。然后,您可以在下一个版本的生产站点上运行自动测试。当测试通过后,您可以指示负载平衡器使用新网站。
这有以下帮助:
- 总是会发现严重问题,且零停机时间。
- 切换到新版本完全没有停机时间,因为新版本已经启动并预热。
- 您可以随时切换回旧版本,因为它仍然在物理运行。
当您可以随时轻松部署时,您和其他人提到的所有其他问题都变得不那么严重。蓝绿部署模型是解决部署问题的相当完整的解决方案。
答案4
补充一下之前的答案:
使用允许回滚和即时切换的部署策略,Capistrano 或几乎任何其他部署系统都可以帮助您实现这一点。您可以使用数据库快照和代码符号链接等功能来快速恢复到以前的状态。
使用完整的配置管理,不要留下任何手动管理的东西。SaltStack、Ansible 和 Puppet 等系统就是例子。它们也可以应用于 Docker 容器配置和 vagrant boxes。
使用 HA 确保在升级节点时可以传递请求。如果升级失败,只需关闭节点,当节点回滚时,将其重新启动,您的 HA 解决方案就会注意到并再次将请求推送到该节点。HAProxy 就是一个例子,但 nginx 也可以正常工作。
确保应用程序可以处理并发实例,使用中央版本数据存储库来存储需要存储在磁盘上的非代码数据(例如缓存)。这样,您就永远不会在升级的应用程序运行中缓存来自不同版本的文件。当然,这将在清除缓存和执行缓存预热的基础上完成。(缓存只是一个例子)
我通常会设置工作流程,让团队经理批准将请求合并到一个特殊分支,该分支会执行所有常规 CI 工作,但作为最后一步,还会开始推送到生产节点。您基本上要做的就是运行手动 CI 部署到生产实例。如果该实例没有生成无效响应、中断或对您的数据产生奇怪的影响,则可以使用您选择的 CI 解决方案批量升级所有节点。这样,如果一个部署成功,您就知道所有部署都会对特定标记/提交有效。
现在,听起来好像您正在单个节点上运行生产应用程序,只有一个部署过程、一个源和一个目标。这实际上意味着该工作流程中的每个步骤都是一个故障点,本身就可能破坏网站。确保这种情况不会发生是所有 CI、HA 和故障转移过程的基础。不要只运行一个节点,不要只运行一个 HA 过程,不要只在一个 IP 地址上运行,不要只运行一个 CDN 等。这听起来可能很昂贵,但将机架中已有内容的副本放在具有自己连接的服务器上通常比商业站点停机时间少一小时。