「Slack」Slack 技术演进模式:在正确的时间采用革命性的技术( 二 )

  • 当我们的团队意识到 React 将会对我们的代码库产生重大影响时 , 只是做一些零碎的小手术是无法让 React 的性能优势得以体现的 。 但进行大规模的重写也是不可能的 , 因为风险与回报比不允许我们这么做 。 当 React 进入第二阶段 , 一个真正的迁移项目开始启动了 。 项目制定了一个计划 , 并配备了大量的开发人员 。 随着项目的进行 , 有很多团队也选择了新的视图样式 。 但在这个中间阶段 , 很多旧的视图仍然存在 , 并需要维护 。
  • 在第三阶段 , 我们将客户端代码库中的遗留视图清理干净 。 我们终于在 2019 年 7 月发布了一个只使用 React 的桌面版 Slack 。
  • Hack 在服务器端 , 我们从 2016 年开始从 PHP 迁移到 Hack 。 这次迁移的一个关键部分是在我们的 PHP 代码中逐步引入类型:
    • 在 2017 年 , 我们进入了第一阶段 , 一些类型爱好者开始在代码库中使用简单的类型 。
    • 有些人在代码进入生产环境之前发现这些类型可以捕获 bug , 于是也开始使用类型 。 这无意中就让 Hack 的类型系统进入了第二阶段(其他用户也受到了影响) 。 不过 , 新的类型注释也带来了一些问题 , 于是我们展开了一场有关标准静态类型与动态类型的讨论 。 通过讨论和积累经验 , 我们达成了一个大致的共识——加大类型使用规模利大于弊 , 并且大多数团队都选择使用类型 。 在第二阶段 , 我们做出了更大的努力进行代码迁移 , 让新加入的代码可以使用静态类型 。
    • 困难的部分留给了第三阶段 。 对 Slack 自身的内部对象变量进行合理化调整 , 并对一些复杂的核心模块进行转换 , 这些都是非常耗时的 。
    Vitess Vitess 是一个用来进行 MySQL 水平扩展的集群系统 , 在进行数据分片策略演化过程中 , 我们选择了它 。
    • 第一阶段开始时 , 我们对 Vitess 的能力进行了严格的评审 。 我们花了很多时间在手动管理自有分片解决方案上 , 而 Vitess 的自动化能力解决了我们的大部分痛点 。 Vitess 团队最终确信这项技术是值得采用的 。
    • 将一些低风险的工作负载(如 RSS 提要)迁移到 Vitess 的工作始于第二阶段 。 在第二阶段早期不太需要 Vitess 团队之外的人参与 , 但因为是一个新的数据存储系统 , 所以仍然需要运维支持 。 随着越来越多的表被迁移到 Vitess , 我们逐渐降低了风险 , 让 Vitess 满足了我们的应用场景需求 。 我们开发了用于回填的工具 , 制定了一些在迁移过程中会用到的术语(例如把重复数据叫作“暗读”) , 总结了可能会出现的各种问题 。
    • 我们已经迁移了数百个表 , 总计超过了查询工作负载的 50% , 但在第三阶段仍然要处理一些“难表”和“长尾表” 。 一些关键表存在复杂的依赖关系和查询模式 , 它们比在第二阶段迁移的表更难处理 。 另外 , 我们有一些“长尾表” , 进行逐张手动迁移很不值得 , 因此我们正在开发工具进行批量迁移 。
    LibSlack 与以上那些经历了各个采用阶段的技术相比 , 我们的跨平台 C++ 客户端库并没有走到第三阶段 , 并且最终停止了 。
    • 在第一阶段 , LibSlack 工程师验证了业务逻辑和数据缓存可共享客户端库的概念 , 并深入开展了编译和交付跨平台库的相关工作 。
    • 然而 , 该项目在第二阶段并没有取得进展 。 库与我们的桌面客户端之间的技术和战略不兼容性变得很明显 。 事实证明 , 在我们的 iOS 和 Android 客户端中使用 LibSlack 库重新实现现有的逻辑和缓存会非常麻烦 。 不过 , 由于 Windows 手机的停产 , Slack 需要维护的客户代码库减少了一份 。
    到最后我们并没有进行全面的迁移 。 我们将从 LibSlack 中学到的东西以各种方式应用到移动和桌面客户端开发工作中 。 代码工件并没有被长期采用 , 但这个项目让我们学会了应该如何构建客户端以及如何组织我们的工程团队 。


    推荐阅读