我们关于Uber for BusinesRaybet2s (U4B)的最后一篇文章讨论了如何实现我们的骑行概况功能。今天,我们希望对我们解决的技术挑战进行更多洞察力。只是因为我们的使命是提高企业的经历并不意味着我们正在写作cobol.从90年代开始,每年在我们的服务器上部署一次。事实上,商业团队Raybet2的优步不断地推动边界,并拥有成为我们的新平台技术的第一批采用者的记录。让我们来看一个例子乘坐政策,这是我们实时验证乘坐情况的方式。
在公司,保证
想象一下,您正在运行100人公司的旅游部门。您的40强大销售团队在全球范围内不断旅行,从机场到酒店,旅馆到会议,会议,晚餐,以及俱乐部的晚餐。等待,什么吗?员工经常会不小心把公司的钱花在私人出差上,而现在你只能在成堆的收据、费用报告和账单中筛选TPS报告,试图弄清楚哪些批准。
如果旅行经理甚至不需要查看费用报告,以确保他们的员工不费用错误的旅行?如果员工不必担心挑选右卡,收取收据和提交报告怎么办?我们讨厌自己做那些事情,所以我们在U4B上决定是时候在董事会中简化了这一点。
输入U4B政策
为客户使用我们的客户集中平台,我们添加了乘坐政策。帐户管理员在我们的Web应用程序中创建了一个策略,现在他们的员工只能在策略适用时乘车。如果他们迟到了,我们将自己用它为员工提供乘坐家庭,它的工作原理很棒。让我们来看看我们如何建造这个功能。
系统要求
首先,让我们弄清楚一些U4B策略系统要求。从客户的角度来看,我们需要一个简单但强大的系统,让用户表达复杂的约束而无需编写任何代码或伪代码。这是一个有趣的问题,本身就是一个有趣的问题,但对于简洁起见,让我们专注于后端要求。
考虑这种潜在的约束,用英文表达:
“如果它在星期三星期五晚上9点之后,你可以骑车,你要离开办公室。”
很明显,我们的系统需要处理一些简单的特征:
- 不平等(时间>下午9点)
- 成员(日期[星期三、四、五])
- 布尔操作数(时间和日)
但它也必须处理一些更复杂的问题,比如地理空间条件(离开办公室)。前三种不需要解释;最后我们可以改写成更熟悉的形式。要想知道某人是否“在办公室”,最简单的方法就是检查哈德琳用户位置与Office之间的距离低于给定阈值。我们可以将此过程蒸发到两个组件:函数执行(Haversine距离)和另一个不等式检查(距离<阈值)。
我们还需要实时评估这些规则;如果他们在政策中,我们不希望骑手必须等待。这意味着甚至包括异常值的可接受性能的上限是几十毫秒的地方。
执行它的规则,如1999年
既然我们知道了我们的需求,我们就可以开始思考如何解决这个问题了。许多工程师将以大致相似的方式来处理它:
这个经过的经验和真正的解决方案可以看到整个行业。缺点是针对每个特定域的问题重复执行此循环。W.E希望推动自己做得更好,并以小巧,干净,简单的方式创造一些可重复使用的东西,这些方式结束这种虐待循环。这是挑战:
使用任意数量的现有工具,在30行代码中编写上述问题的解决方案。
在您在正式语法上疏浚旧教科书之前,请考虑是否已经解决了此问题的任何工具和图书馆是明智的。简短的答案是:有很多。如果你熟悉项目PegJS,它将为您生成一个解析器,当您知道自己刚刚完全省略了第2步时,您可能会感到非常高兴。
这是一个很好的优化,但我们可以进一步拯救自己写作代码的麻烦任何上述步骤通过组合已经存在的小型开源模块。如果,而不是写我们自己的域名-具体的语言,我们使用了一个非常的子集通用的这些工具已经存在的语言。这是2016年,所以我当然谈论javascript.。
虽然ECMAScript定义了JavaScript如何解释,但它不会定义一个单一的方法来解析JavaScript成一致的格式。幸运的是,其他工程师有这个定义。一个向JS解析器公开API的项目蜘蛛猴为我们提供了一个用于JavaScript AST表示的语言,许多工具都涌现,使用这种格式。这是一个非常强大的东西;我们在JavaScript生态系统中委托我们代码质量的许多工具,例如林德斯和代码覆盖范围图书馆,依赖于低级的这个表示。
现在我们已经有了语法(JavaScript),我们需要的另外两个工具(解析器和求值器)已经以形式存在esprima和静态评估。Esprima使用一些有效的JavaScript作为输入,然后输出AST。当给定一组事实时,静态eval遍历AST并以安全的方式计算它。
这让我们只是一个小小的粘合剂代码来完成我们的挑战:
我们在只有七行代码中的规则引擎是我们非常简单的规则引擎的基础。我们现在可以评估任何有效的JavaScript表达式:
我们还能够公开函数以评估更复杂的规则。现在需要改变语法,Lexer和解析器的东西现在是一个琐碎的变化:
简单的应用程序haversine node.js模块,我们现在可以在办公室实施我们的支票。
模块化和可扩展
虽然我们可以只用几行代码实现一个简单的规则求值器,但这个系统的真正强大之处在于它的模块化和可扩展性。为了从用户在web应用中选择一些选项到一个可执行规则,我们需要通过几个转换步骤,将这些步骤分成层:
以上图广泛地将系统分为四层:输入,域,规则和执行。让我们考虑我们的原始要求(“您可以骑行,如果它在周三星期五下午9点之后,您将离开办公室)将这些层遍历到最终产品中。
输入
输入层描述了我们如何允许用户创建规则。我们已经讨论过允许用户从下拉菜单中选择时间,但是我们可能希望让工程师直接用JavaScript编写规则或扩展接口以允许自然语言输入。对于我们的示例,当用户在UI中选择选项时,我们可以创建杰森这些投入的表示:
领域
存在域层以将一个或多个输入强制到可以执行的规则中。对于骑行策略,我们将所有原子规则与相同类型(例如,时间)结合起来`||`不同类型的规则“& &”但是,其他系统可能不同。例如,我们可能希望为可用的通勤时间表示“6 AM-9AM,或8点至下午8点”。这使我们可以从多个不同的组件转换为一组规则,必须全部通过,以便乘车发生:
请记住,这是一个有效的JavaScript表达式,然后我们可以在请求时将其传递给规则层和执行层(这两者我们都已经讨论过)。请注意,系统的模块化在评估时也是有益的。如果我们有一个复杂的规则,需要从其他分布式系统获取大量的事实数据,我们可能希望使用“惰性求值器”来优化执行。我们可以简单地将static-eval模块替换为一个知道如何在需要时从其他系统获取数据并在其中任何条件返回false时发生短路的模块。
请求时间
我们已经展示了这个系统满足所有规则评估需求的同时仍然有一个非常简单和模块化的实现,但是为了在请求时运行,它的性能足够好吗?为了确保系统执行得足够好,可以插入到请求流中,当附加程序请求汽车时执行的逻辑,我们用这个规则评估器进行了基准测试基准博士。平均执行时间约为100微差异非常小的秒数(0.0001标准偏差),良好的限制。
这只是技术挑战的一个例子Raybet2优步企业团队每天都解决。我们对他们没有短缺,所以,如果您有兴趣帮助我们将优步带入商业世界,浏览我们的工程空缺。
Demaine会是Uber业务基础设施团队的软件工程师吗Raybet2由于U4B于2014年推出。
标题映像:在2015年在功能亮起时设置U4B乘坐策略的界面。
喜欢你在读什么?订阅我们的时事通讯对于Uber Engineering Blti8 竞猜雷竞技appog的更新。雷竞技到底好不好用








