Uber工程技术栈(二):看曾经的独角兽背后用了哪些技术

日志

我们的服务彼此交互,还与移动设备进行交互,而那些交互对业务状况(比如动态定价)和内部使用(比如调试)来说都很重要。就日志而言,我们使用了多个Kafka集群,数据被归档到Hadoop及/或文件存储Web服务中,然后将数据从Kafka弃用。这些数据还被各个服务实时获取,并索引到ELK堆栈,用于搜索和可视化(ELK代表Elasticsearch、Logstash和Kibana)。

应用程序配置

我们使用Mesos上的Docker容器,借助一致的配置来运行微服务,具有可扩展性,并借助Aurora来处理长时间运行的服务和计划任务。我们的其中一个基础设施团队:Application Platform构建了一个模板库,把服务做入到可交付的Docker镜像中。

路由和服务发现

我们的面向服务架构(SOA)使得服务发现和路由对Uber的成功而言至关重要。在我们的复杂网络中,服务必须能够彼此联系。我们结合使用HAProxy和Hyperbahn来解决这个问题。Hyperbahn是Uber开发的一系列开源软件的一部分:Ringpop、TChannel和Hyperbahn都肩负一个共同的使命,为服务网络增添自动化、智能和性能。

遗留服务使用本地HAProxy实例,通过HTTP请求将JSON路由到其他服务,而前端Web服务器NGINX为后端服务器充当代理。有了这种可靠成熟的数据传输方式,故障排除起来就很容易,这在去年几次迁移到刚开发的系统的过程中显得至关重要。

然而,我们更注重长期可靠性而不是可调试性。替代HTTP的非传统协议(如SPDY、HTTP/2和TChannel)以及像Thrift和Protobuf这些接口定义语言将有助于从速度和可靠性方面改进我们的系统。Ringpop是一致的散列层,它为应用程序层面带来了合作和自愈合。Hyperbahn让服务能够简单而可靠地找到其他服务,并与之联系,即便服务是由Mesos动态调度的。

不是采用过时的轮询方式来查看是否发生了变化,我们改用一种发布-订阅模式(向订户发布更新内容)。HTTP/2和SPDY更容易支持这种推送模式。改用推送模式后,Uber应用程序中几项基于轮询的功能会出现速度大幅提升。

开发和部署

Phabricator支持大量的内部操作,从代码审查、文档编制到过程自动化,不一而足。我们使用OpenGrok这种源代码搜索和相互参照引擎来搜寻代码。至于Uber的开源项目,我们使用GitHub从事开源开发,用于问题跟踪和代码审查。

Uber工程部门竭力让开发环境尽可能酷似生产环境,于是我们主要在云提供商或开发人员的笔记本电脑上运行的虚拟机上从事开发。我们构建了自己的内部部署系统来管理代码构建。Jenkins负责持续集成工作。我们结合了Packer、Vagrant、Boto和Unison,开发用于在虚拟机上构建、管理和开发的工具。我们在开发过程中使用Clusto用于库存管理。Puppet负责管理系统配置。

我们不断努力构建和维护稳定的沟通渠道,不仅仅为了我们的服务,还为了我们的工程师。至于信息发现,我们构建了uBlame(向git-blame致意),跟踪哪些团队拥有某一项服务,并构建了Whober用于查找姓名、面部、联系信息和组织结构。我们使用一个内部的文档编制网站,使用Sphinx,自动从软件库来构建文档。一项企业提醒服务提醒我们随叫随到的工程师,确保系统正常运行。大多数开发人员在其笔记本电脑上运行OS X,我们的大多数生产实例通过运行Debian Jessie来运行Linux。

语言

在较低层面,Uber的工程师主要用Python、Node.js、Go和Java来编写程序。我们最开始使用两种主要的语言:Node.js供市场团队使用,Python供其他所有人使用。如今这些第一语言仍用于在Uber运行的大多数服务。

由于高性能的原因,我们采用了Go和Java。我们为这些语言提供了一流的支持。Java充分利用了开源生态系统,并与外部技术整合起来,比如Hadoop及其他分析工具。Go为我们提供了效率、简单性和运行速度。

我们将原来的代码库分解成微服务时,丢弃并更换了旧的Python代码。异步编程模型为我们提供了更好的吞吐量。我们使用Tornado和Python,但Go直接支持并发的功能非常适合大多数新的注重性能的服务。

必要时,我们用C和C++来编写工具(比如在系统层面开发高效率、快速度代码)。我们使用由那些语言编写的软件,比如HAProxy,但在大多数情况下,我们在实际工作中不用这些语言。

当然了,那些在架构顶层工作的系统是用Java、Go、Python和Node之外的语言编写的。

测试

为了确保我们的服务能够满足生产环境的需求,我们开发了两款内部工具:Hailstorm和uDestroy。Hailstorm驱动集成测试,并在非高峰时段模拟峰值负荷,而uDestroy有意起到了破坏作用,那样我们就能更擅长处理意外故障。

我们的员工使用应用程序的测试版,在发送到用户之前不断测试开发的新品。我们做了一个应用程序反馈报告工具,在部署到用户之前揪出任何代码错误。每当我们在Uber应用程序中拍取屏幕截图,这项功能就会提示我们在Phabricator中提交错误修复任务。

可靠性

编写后端服务的工程师负责服务运营。如果他们编写的一段代码在生产环境中出现故障,就会得到提醒。我们使用Nagios警报机制来进行监控,与一套警报系统结合起来,用于通知。

力求获得最佳可用性和每天处理10亿次打车服务,网站可靠性工程师专注于获得成功所需的服务。

2016年2月的一场技术讨论会介绍了Uber网站可靠性工程的历史。

可观察性

可观察性意味着确保Uber整体以及不同部分都顺利运行。一套系统主要由我们的纽约办事处开发,它们为Uber工程部门充当遍布全球各地的眼睛、耳朵和免疫系统。

遥测

我们用Go开发了M3,收集并存储来自Uber工程部门每一个部分(每台服务器、主机服务和每段代码)的度量指标。

我们收集数据后寻找趋势。我们通过修改Grafana(https://github.com/grafana/grafana)来构建仪表板和图形,以便更直观地将信息置于上下文来研究。每个查看仪表板的工程师往往关注某个集团或地区的数据、一组试验方面的数据,或者是与某个产品有关的数据。我们为Grafana添加了数据交叉分析功能。

原文发布于微信公众号 - nginx(nginx-study)

原文发表时间:2018-05-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SeanCheney的专栏

《Python分布式计算》 第8章 继续学习 (Distributed Computing with Python)前两章工具云平台和HPC调试和监控继续学习

这本书是一个简短但有趣的用Python编写并行和分布式应用的旅程。这本书真正要做的是让读者相信使用Python编写一个小型或中型分布式应用不仅是大多数开发者都能...

3084
来自专栏CSDN技术头条

专访当当网张亮:深度解读分布式作业调度框架elastic-job

【编者按】互联网从诞生到现在,网站的规模不断扩大,存储和处理的数据量也远远超出了人们的想象,又随着对信息实时性、多媒体需求大幅增长的现象,互联网架构面临越来越大...

2466
来自专栏Web项目聚集地

为什么一定要前后端分离?

孤独烟,中国平安研发工程师,目前负责云平台架构设计以及需求研发工作。毕业后一直从事Java开发工作,在Web开发、架构设计上有多年的实战经验。在MySQL性能优...

1591
来自专栏程序你好

个人门户系统设计方案

3104
来自专栏BestSDK

如果你的APP没有这些漏洞,就说明成功了

用户卸载你的app的原因有时候很简单,也许是你的app经常突然崩溃,或者是app界面设计得不够直观,或者是用户需要填写的个人资料过多。 这是用户体验冲突的3个例...

2814
来自专栏Linux Python 加油站

揭秘Linux工程师一路走来都需要哪些技能

大公司也是从小公司一步步走过来的,而大公司之所以与小公司不同,不在于基础的技术体系不同,而是当数据量达到一定程度后,引发的质变而已。而在思考质变带来的性能问题中...

1294
来自专栏鹅厂网事

挖掘故障中的金矿----记一次故障的详细分析

“鹅厂网事”由深圳市腾讯计算机系统有限公司技术工程事业群网络平台部运营,我们希望与业界各位志同道合的伙伴交流切磋最新的网络、服务器行业动态信息,同时分享腾讯在网...

2098
来自专栏非著名程序员

如何让你的开发效率提升 3 倍?

编程大牛、《Java 编程思想》一书的作者 Bruce Eckel 曾说过:在这个领域做得越多,我越觉得软件开发比任何行业都更接近于写作。

1061
来自专栏鹅厂网事

海量服务器安全高效管控系统设计

"鹅厂网事"由深圳市腾讯计算机系统有限公司技术工程事业群网络平台部运营,我们希望与业界各位志同道合的伙伴交流切磋最新的网络、服务器行业动态信息,同时分享腾讯在网...

3468
来自专栏云计算D1net

私有云下的身份与管理解决方案

信息化时代,企业分布式管理模式的广泛应用使当今的IT系统管理变得复杂,企业必须提供一个全方位的资源审视以确保企业资源的有效访问和管理。而云计算的不断发展使得众企...

3928

扫码关注云+社区

领取腾讯云代金券