介绍
优步的许多软件系统每天需要大量的变化。由于我们的系统规模和复杂性,在没有意外后果的情况下实现这些变化的重要挑战,最终减缓了开发商生产力。Flipr.是优步解决这个问题的重要组成部分。Flipr是一种为动态配置管理创建的工具,例如功能标志,elseLlists,增量卷展栏和其他高级用例。在这篇文章中,我们将描述Flipr的架构和功能,我们将展示我们如何使用它来快速且轻松地使用它来进行大量的变化,而不会牺牲可靠性。
配置系统和运行时上下文
配置系统控制一组影响应用程序行为方式的值,可以在不改变代码的情况下更改。通常,此键值映射存储在文件,数据库或服务中,因此可以从代码中独立更新,并且将有一个可以执行查找的客户端库。配置系统的主要好处是它使您可以更改应用程序行为,而无需重新编译,重新部署或重新分配代码。
在FLIPR中,我们将这些密钥和值对引用为特性。此示例客户端库查找功能使用JSON将字符串键映射到布尔值,但也可以使用其他数据类型:
简单的配置系统可用于存储如下用例的配置:
- “功能#456已启用”
- “”名称“文本框的字符大小限制为256个字符”
- “地图服务API的URL是http:// mapservice:8080 / v2”
这适用于此包括功能标记,网络配置,电路断路和紧急操作控制。
这种配置系统基于一对一的键值映射,因此在不改变代码的情况下,可以更难代表更复杂的配置使用情况,或者具有非常大的关键空间。例如,我们可能不容易存储:
- “对于当前正在提交纽约的”管理员“组的所有成员,请启用此功能#456”
- “锁定属性API以获取请求,”暂时不可用“错误消息,周三在4 PM-5PM之间”
这些用例需要在运行时未知的信息,例如用户的组成员或一天中的时间。保持改变这种配置的能力的一种方法在不更新代码的情况下,是增强配置系统,以便能够基于运行时信息返回不同的值。这是FLIPR与其他配置系统的不同之处:根据运行时上下文,FLipr属性可以每键具有多个值(即,Multimap而不是地图)。
签名得到函数更改为包含运行时上下文参数:

随着此新参数的添加,属性现在可以包括确定是否应覆盖值的异常,具体取决于上下文。我们称之为覆盖例外,例外内的规则被称为约束。客户端库检索属性的最新版本,但现在取决于运行时上下文,值可以不同:
用flipr推出一个功能
让我们走过一个例子来说明如何在实践中使用Flipr。特色标志是一种众所周知的技术,开发人员使用安全和快速推出代码更改。首先,我们部署服务和应用程序代码,如任何标准更改,而是使用功能标志所通用的新代码和功能。此标志可以作为基于从配置系统检索的布尔值的IF语句,如下所示:
部署代码时,应用程序行为没有更改,因为所有新行为都是由要素标志所界面的,并且最初属性被设置为错误的。以下是在json中的财产看起来如何:
接下来,我们可以更新值以启用与ID 1.在城市中的2个特定用户的功能启用该功能。以下示例显示与以前相同的属性,但现在指定该值应该是相同的真的如果上下文包括密钥Cityid.这具有价值1:
每当更新属性时,将分发到需要它们的所有主机。下次客户函数被调用,它将使用最新的更新规则,并且服务将开始使用特定请求的新代码。
如果出现问题,我们可以通过将值更新回来来恢复或关闭更改错误的,并且由于配置通过网络调用更改,并且不涉及代码更改,我们不必等待长期部署或向App Store运送二进制文件 - 它只需几秒钟即可。
启用功能后,我们可以监控我们的指标,运行集成测试并查找问题。如果一切看起来不错,下一步就是为更大的用户组织启用该功能,如城市中所有注册的测试师。然后,如果该更改通过验证,我们可以继续将观众扩展到多个城市,最终是所有用户。如果检测到任何问题,我们仍然能够回滚并恢复旧行为。这种逐步扩展使用功能的方法允许我们快速安全地推出和测试功能。
功能标记只是如何使用Flipr的一个示例。基于规则的基于规则的配置可以用于允许列表/校舍,实验,基于地理或时间的目标和许多其他配置用例。
建筑学
概述
在本节中,我们将简要描述所有Flipr的主要组件。通常,Flipr只是服务,具有UI和用户的客户端库。我们的基础架构的大规模也需要一组组件来帮助分发数据,这有助于可靠性。
UI.
客户主要通过UI进行交互。以下是属性异常构建器UI的屏幕截图,其中用户可以创建和更新具有异常的属性:
还有广泛的UI功能,用于管理和更新属性,卷展览,回滚,对等方面评价,权限管理,历史记录以及许多其他功能。
后端API.
Flipr支持广泛的API,以便其他服务可以以编程方式使用FLIPR。此API使用标准优步软件网络堆栈公开。API直接支持UI和网关服务,以及其他特殊用例,不可用,例如我们的生产工程团队使用的紧急控制和操作功能。
门户网关
扩展到这么多的服务器可以对后端服务提供大量压力,但由于大多数用例都是只读的,我们可以使用保持最新副本缓存的网关服务的扇出缓存,所以backend doesn’t get directly hit with traffic.
对网关的复制是异步的,因此通过客户端进行更改和读数最终是一致的。在实践中,具有扇出缓存的最终一致的模型已被证明是可扩展,可靠和性能的,即使是UBER比例的船队范围。FLIPR还在转向基于订阅模型的新分发系统,以实现相同的规模,但具有更有效的资源使用。
主机代理人
如网关部分所述,主机代理是FLIPR的扇出缓存的一部分。主机代理负责从网关中拉动数据并持续更改磁盘。坚持磁盘的一个大优势是,如果网关,后端,网络或许多其他问题存在问题,客户端仍然可以继续运行,因为它们只是继续从磁盘副本中读取。主机代理也用于指标,一致性监控,以及向客户提供代码的获取部分,以帮助升级和更改。在主机上可能有多个容器,但单个主机代理程序将所有必需的配置保持最新。
客户库
客户端库使读取Flipr配置数据以了解优步的所有支持的语言。这些库将磁盘格式读入内存并监视更新。它们还负责每当服务请求配置值时评估约束和异常。客户的主要功能是得到我们在该示例中看到的功能,但是通常存在其他版本,例如在Golang库中的类型安全获取功能。一些客户端库还提供用于调用后端API的实用程序函数,以通过API进行写入和更新。
特征
特性
写入例外的约束系统具有很大的灵活性。它允许编写规则,以考虑许多逻辑维度,例如地理,城市ID,用户ID,驱动程序ID,车辆ID,设备类型,应用程序版本,时间,实验处理等。所有这些都可以与各种布尔操作以非常灵活的方式编写任意复杂的异常。
属性也可以具有模式,由架构定义。Flipr在编辑UI中的值以降低运行时错误的风险时强制执行架构。
运营
FLIPR有很多功能,有助于保持系统可靠地运行。它有一个一致性检查系统,可以确保磁盘上的文件与后端一致。堆栈中的所有组件都有指标,警报和监控,以确保随机呼叫工程师立即知道如果出现问题。有助于减轻不一致性和处理紧急情况的工具,例如胸围缓存和强制更新的工具。还有一个有关工程师计划,确保系统和客户在时钟周围支持。
规模
Flipr管理超过350k的活动性质,每周约有150k变化。此配置数据在Uber跨越50k +主机使用超过700种服务,为我们的后端系统产生约300万QP。
安全特性
为了使FLIPR安全,可靠,符合安全性和隐私要求,FLIPR具有广泛的安全性,可靠性和审计功能。对于大多数FLIPR更改,需要对等评审,这是通过FLIPR的标准化代码审查工具和自定义UI强制执行。有访问控制和权限系统,以确保仅授权用户可以查看和更新配置。卷展栏在物理尺寸上逐渐执行,因此工程师可以逐步和安全地进行更改,而不是在全球范围内应用变化,这减少了任何意外后果的爆炸半径。如果在进行变化后检测到问题,还可以与我们的监控系统集成,以便如果在发生变化后检测到问题,则可以自动回滚。在不久的将来,我们还添加了一些令人兴奋的集成测试功能,可以实现一些非常易于使用的配置更改的预生产测试。
概括
这篇文章是FLIPR的高级概述 - 它是什么以及它的工作原理。在下一个帖子中,我们将介绍一些真正的用例,展示Flipr有助于Uber如何保持灵活,使我们的系统保持最新,而不会导致干扰我们日常生产力的问题。如果对你有趣,为什么不来和我们一起工作,我们正在招聘!。











