写点什么

UCHAT 之路:构建 Uber 的内部聊天解决方案

  • 2017-08-20
  • 本文字数:4789 字

    阅读完需:约 16 分钟

两年前,Uber 先前的聊天应用程序开始显示出无法适应我们的发展的迹象。有应用程序崩溃、性能打嗝以及停电中断,削弱了我们公司在线有效沟通的能力。用户满意度一直走低,所以我们需要一个新的解决方案。

我们的运营分布在 620 多个城市,能让 Uber 员工无论处于世界何地都能在台式机和移动设备上可靠地进行通信,这一点非常重要。为此,我们制定了一些核心要求。首先,我们需要一些东西能够扩展以支持不断増长的员工人数,同时也能控制其成本。我们还需要一个可以轻松与各种内部工程、业务和操作工具相集成的平台。

当我们评估互联网中继聊天(IRC)和许多其他流行的聊天客户端时,很明显,没有一个完整的第三方解决方案可以满足 Uber 的核心要求。

所以,在测试了多个现成的替代方案后,我们利用开源平台 Mattermost Puppet 构建了 uChat,它是我们的定制内部消息平台,是用于部署配置管理的 Uber 标准。在本文中,我们将讨论如何在短短三个月内,我们的团队让公司转变到能够在一个统一的聊天环境中每天向数万用户可靠地发送超过一百万条消息的新解决方案。

走向开源

为了加快开发进程,我们决定基于开源平台构建我们的解决方案。这个选择尤其有吸引力,因为我们希望直接影响路线图并控制长期的经常性成本。如果从零开始就会更加困难。

为了充分利用我们的混合构建方法,我们需要一个功能强大的开源构建块,它得有多功能的 API、高质量的代码库和充满活力的开发社区。我们评估了各种 XMPP Erlang 和基于 JavaScript 的选项。由于我们的主要要求是能够支持 Uber 的增长,因此我们特别留意那些可扩展性很好的聊天平台。

作为性能验证的一部分,我们将每个开源产品的性能推到了突破点。例如,我们的初始目标之一就是在一个单一的聊天环境中模拟 50,000 个用户的聊天行为。很快,很多这些平台就无法进行这些基本的负载测试。

图 1a:我们对测试实体线程(Thread)的设计尽可能简单,从而将注意力集中在快速验证产品声明上。

对于其他的性能选择,我们编写了一个测试工具来模拟成千上万的用户。测试集的设计(上图 1a)非常简单,这确保了我们可以用最小的努力来验证产品声明。在这个测试环境中,简单的 Go 结构的 EntityConfig(下图 1b)封装了可以登录、加入渠道和发送消息的用户。结合 Go 的本地协同程序,很容易达到我们的模拟目标。随着时间的推移,测试工具能提供更强大的功能,更好地模拟复杂的用户场景。

图 1b:EntityConfig 代表着平台上用户的基本交流需求。

经过数月的测试和供应商审查,我们选定了 Mattermost 。Mattermost 大大超出了我们的最低性能预期,并与 Uber 现有的技术堆栈很一致。此外,他们的客户端用户界面类似于那些很受Uber 员工喜欢的聊天应用程序界面。

下一个合乎逻辑的步骤是,评估该平台是否能够跟上Uber 的高增长并维持我们对聊天的操作依赖性。仔细考虑了必要的因素之后,我们问自己:Mattermost 能否达到Uber 规模?

为了测试Mattermost 在适应这些条件方面的能力,我们的负载测试旨在识别出可能影响性能的软件架构和服务器代码的主要瓶颈。我们模拟了可变消息发送速率、升高窗口和并发用户峰值以建立基准。我们创建了成千上万的假用户帐户,并编程用以登录、加入聊天室和进行聊天,目的在于触发崩溃和数据库锁定

图2:在对基于Mattermost 的聊天解决方案测试期间,当主数据库连接达到最大值而且数据库锁定时,消息发送速率下降。

在测试期间,我们并不惊讶地发现,不仅仅是后台显示出了有限的可扩展性。我们测试过的大多数用户界面都不能达到我们积极的目标:譬如,聊天室仅能容纳约一百个用户,而且现有的用户界面不能同时搜索20,000 多个频道。

当在规模测试期间遇到瓶颈时,我们针对最具影响力的性能违规者进行了修复,并从已知的稳定负载水平重复了该过程。同时,我们继续更新测试,以模仿更加现实的用例。我们的初始目标是7 万个并发用户、发送速率为每秒80 到200 条消息。如果能够成功管理这种负载,我们可以确保有足够的空间来支持将来的增长。

与开源社区合作,我们不断剖析日志、识别根本原因并发布新的修复。这里,周转速度至关重要。随着每个新的发现和构建,我们对整体系统的局限和快速适应可扩展需求的能力有了更深入的认识。

渐渐地,我们清楚地看到Mattermost 在当时最能够发展成熟到Uber 规模,我们对他们的平台也有了信心。为了帮助其他人使用我们的新合作伙伴去开发聊天平台,我们把测试工具贡献到了开源社区。

用Puppet 来管理uChat 软件架构

在对Mattermost 平台进行负载测试时,我们需要持续可靠地更改新解决方案的基础架构和应用配置。Mattermost 的高可用性(High Availability)模式仍然处于早期测试阶段,因此我们经常在代码中遇到错误。

在早期的测试和开发阶段,Uber 基础设施团队手动地修改了这些代码。可以预料的是,让新的uChat 构建和服务器配置稳定下来是一个乏味且易于回归的过程,需要频繁地进行更改以修复无意的配置错误。很明显,人工基础设施管理正在放缓我们的速度,于是我们转向了Puppet。

我们使用Puppet 来编码软件架构和服务器配置,为管理支持uChat 快速改进所需的各种服务器和网络环境提供了坚实的基础。 Puppet 可以对数据库拓扑中的多个机器实现一致的和可重复的更改,并允许我们审核更改和执行部署代码审查。

图3:uChat 最初的Puppet 工作流不能达到我们的解决方案所需要的能可靠地迭代和扩大规模的速度。

最初引入Puppet 极大地减少了部署期间的无意错误。然而,即使基本的Puppet 基础架构代码解决了我们的一些重复性和一致性问题,我们仍然没有达到所需要的速度。在这个阶段,我们没有使用不可变的服务器,这意味着改变高可用架构的Puppet 代码带来了意想不到的副作用的巨大风险。此外,我们正在使用一个大型monorepo,其中所有与Puppet 相关的更改必须收敛,从而使得问题更严重。

这种约束意味着我们无法快速地部署新的基础架构和应用程序版本以满足我们的需求,严重限制了我们的迭代速度。因此,更新的Puppet 部署配置可能需要一两天才能安全完成。同时,每小时都可收到无关的uChat 性能提升。我们新的基于Puppet 的工作流程更好,但仍有改进的余地。

图4:uChat 目前的Puppet 部署流为由我们的网站可靠性工程师维护的Puppet 模块集成了一个单独的存储库。

为了加快uChat 部署,我们将基础架构代码转换为单独的存储库作为Puppet 模块。这将允许我们独立地管理版本、隔离和测试与uChat 应用程序特定相关的配置更改,而不用管服务器基础结构配置。

在重构并彻底测试了新的Puppet 模块后,我们依靠 Puppet 代码管理器将基础设施更改推向新建的模拟和生产环境。这种基于模块的方法使我们能够将应用程序配置问题与基础设施 / 服务器配置问题分开,更容易地根据 uChat 应用程序本身的需求和发布时间表来分发更改。

图 5:上面详细介绍的 uChat 软件架构完全由 Puppet 编排。这有利于可靠地部署和微调平台所需的高质量变更控制。

通过 Puppet 模块、Puppet 代码管理器和对 A/B 部署的支持,我们终于实现了所需要的快速而一致的部署变更控制。现在,我们可以在不到一天的时间内可靠地完成整个模拟和生产环境。

创造无缝用户体验

在让基础架构变得成熟的同时,我们还必须建立一套直观的 Uber-fied 网络、桌面和移动应用程序。首先,我们克隆了 Mattermost 桌面应用程序,并开始对内部客户进行简单的白色标签。另一方面,Mattermost 移动应用程序需要进行完整的重组,以实现我们正在寻找的用户体验(UX)类型。

图 6:我们团队的设计批评改进了 Mattermost/uChat 中的用户界面,在使用 UX 识别问题点时没有任何遗漏之处。

原先的基于 iOS 和 Android 的 uChat 应用程序集成了一个简单的网络视图来加载整个 uChat 网页,导致加载时间极慢。另外,网络视图引起刷新,强制不必要的加载、不完整的文件下载和不均匀的体验。为了增强我们的员工并加快建设,我们与 Fullstack Labs 合作,在 React Native 中重写这些应用程序。正如我们与 Mattermost 所支持的平台的做法一样,我们向开源社区贡献了所构建的一切。

目前,uChat 移动客户端通过我们的内部应用程序商店进行部署,通过 Chef System Center Configuration Manager (SCCM)来管理桌面客户端。为了限制移动 uChat 版本数量,并简化持续的支持,我们在 iOS 和 Android 应用程序中构建了自定义机制,提示用户在新的 uChat 版本可用时进行升级。我们还设计了一项功能,用于在需要强制升级的情况下让旧客户端版本实效。

uChat 移动应用程序可以让 Uber 员工轻松在即时和跨设备进行通信。

我们对可扩展性平台的远景确保了我们提供与生态系统中的其他工具相集成的 UX。为了实现这一目标,我们花了几个月的时间将以前的解决方案中的 50 多个旧功能集成到了 uChat。API 和 webhooks 允许现有的内部服务集成和扩展聊天功能,例如 Uber 的内部部署系统 uDeploy ,它在新的构建完成时通知工程师;或者 Envoy ,它支持我们的办公室访客注册服务。

构建用户的信任

在实现任何的企业应用程序时,推动用户采用产品和改变现有行为是很有挑战性的。在将公司转移到诸如 uChat 这样的本土工具的同时,需要额外的关注,以灌输 uChat 比现有的消息平台更可靠的信心。为了建立这种信心,并尽可能无缝地过渡到 uChat,我们预先为所有员工提供了帐户,并迁移了近 20,000 个聊天室,员工不必重新创建或重新加入他们以前用过的任何聊天室。

尽管我们尽了最大努力,但还是有坎坷。随着我们将越来越多的员工集成到 uChat 上,间歇性中断使得一些早期用户不愿意完全采用该应用程序。为了减轻顾虑,在 uChat 逐渐稳定并有更多的时间展示自己的同时,我们也保留了旧版聊天应用程序在线。

为了进一步将 uChat 与员工进行整合,我们提高了透明度。当发现错误时我们就宣布它们、发布修复计划并部署布丁。我们还制作了广泛的监控图表,这样,任何感兴趣的人都可以看到 uChat 的实时健康状况。

一旦我们能够持续显示 uChat 的 99.9%的可用性,我们将传统聊天系统设为 depreciated。我们逐渐禁用房间创建和集成等功能,直到将插件从旧系统中完全剥离出来,从而完成了全面的调整。我们经常公布产品更新、共享使用技巧和整理如常见问题和用户指南等资源,以确保员工得到全方位的支持。我们还开设了一个反馈渠道,员工可以立即获得帮助,也可以建议新的功能。

我们从这次经验中学到的关键一课是,弃用现有聊天应用程序所需的计划和组织调整水平,需要更多的买帐和协调,远远超过我们最初所预期的。但是,通过保持透明、易用和快速的改进,我们与应用程序的早期采用者们建立了良好的关系基础,并随着时间的推移让整个公司得以过渡。

uChat 的未来

在接下来的几个月里,我们将实现新的特征,继续检测用户的反馈,并将 Mattermost, Inc. 公司和开源社区所提供的额外改进整合到产品中。

uChat 只是我们团队为促进 Uber 的协作、沟通和生产力所建立的众多解决方案之一。我们不断开发、部署和维护 Uber 的内部工具包,每年为公司节省数百万的回收生产力和软件许可费用。如果你对在像 Uber 这种快速增长的全球性公司里的下一代内部系统感兴趣,请考虑向 Uber 的员工效率工具团队(Employee Productivity Tools team)申请职位

关于作者

Marissa Alvarado-Lima 是 Uber 技术服务团队的技术撰稿人,Stanley Chan 和 Chris Duarte 是 Uber 员工效率工具团队的软件工程师,Ed Wolf 是 Uber 员工效率工具团队的资深产品经理。软件工程师 Sameer Patan 和 Josh Schipper、资深网站可靠性工程师 Matt Beard、软件工程经理 Benjamin Booth 和产品设计师 Nayong Park 对此文也作出了贡献。

查看英文原文 THE ROAD TO UCHAT: BUILDING UBER’S INTERNAL CHAT SOLUTION


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-08-20 19:003008
用户头像

发布了 21 篇内容, 共 10.5 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

银行零售如何更贴近客户?是时候升级你的客户旅程平台了

Kyligence

数据分析 客户旅程

如何用Apipost预执行脚本动态修改Query、Body、Header参数

不想敲代码

Postman 接口调试 API apipost

Flink CEP 在抖音电商的业务实践

Apache Flink

大数据 flink 实时计算

非代码的贡献也能成为Committer,我与DolphinScheduler社区的故事

白鲸开源

开源 开源社区 开源文化 开源软件 大数据 开源

图片竟能直接生成逼真音效?这AI模型也太神奇了吧!

人称T客

前端如何实现将多页数据合并导出到Excel单Sheet页解决方案|内附代码

葡萄城技术团队

数据库 前端 架构分布式

Hi3861编译烧录更快捷

HarmonyOS开发者

HarmonyOS

对话 ChatGPT:现象级 AI 应用,将如何阐释「研发效能管理」?

LigaAI

人工智能 研发效能 openai ChatGPT 企业号 2 月 PK 榜

2023年低代码发展新趋势

力软低代码开发平台

我的2022,从紫竹院到通惠河畔

虎妞先生

学习 前端 成长 年终总结

众生皆苦,我选pnpm

虎妞先生

npm 原理 前端工程化 pnpm

畅销10年的数据库技术图书,当之无愧的霸主!还有谁?

博文视点Broadview

从零开始学习BOM&DOM

虎妞先生

前端 DOM

万里数据库加入龙蜥社区,打造基于“龙蜥+GreatSQL”的开源技术底座

OpenAnolis小助手

开源 龙蜥社区 greatsql社区 万里数据库 生态适配

应用部署初探:微服务的3大部署模式

SEAL安全

微服务 企业号 2 月 PK 榜

看海泰方圆类ChatGPT技术模型!

电子信息发烧客

十分钟用vitepress搭建项目文档

虎妞先生

前端 vite Vue 3

图片竟能直接生成逼真音效?这AI模型也太神奇了吧!

科技热闻

给webpack提了一个pr之后......

虎妞先生

前端 webpack #开源

谈谈干前端三年的几点感受

虎妞先生

前端 成长 代码人生

Java高手速成 | Hibernate的配置文件与JPA API的基本用法

TiAmo

hibernate jpa api 网关

基于Verilog HDL的状态机描述方法

timerring

FPGA

干货|PCBA丝印位号与极性符号的组装性设计

华秋电子

PCB dfm

数据同步gossip协议原理与应用场景介绍

京东科技开发者

架构 Consul fabric Gossip协议 企业号 2 月 PK 榜

git中patch的用法

ModStart

探讨MySQL事务特性和实现原理

小小怪下士

Java MySQL 程序员 事务

Flomesh Ingress 使用实践(四)TLS 透传

Flomesh

Kubernetes 服务网格 ingress Pipy 流量管理

JVM性能调优,分享些好用的内存分析神器

Steven

Python从0到1丨图像增强及运算:形态学开运算、闭运算和梯度运算

华为云开发者联盟

Python 人工智能 华为云 企业号 2 月 PK 榜 华为云开发者联盟

BSN-DDC基础网络详解(二):快速接入指南

BSN研习社

BSN-DDC

Vue3项目框架搭建封装,一次学习,终身受益【万字长文,满满干货】

虎妞先生

前端 前端架构 Vue 3 vue cli

UCHAT之路:构建Uber的内部聊天解决方案_语言 & 开发_Marissa Alvarado-Lima_InfoQ精选文章