阿里云飞天发布时刻,领先大模型限免,超7000万 tokens免费体验 了解详情
写点什么

Ousta 如何在两分钟的测试周期内模拟客流

  • 2016-12-05
  • 本文字数:3432 字

    阅读完需:约 11 分钟

主要结论

  • Ousta 的模拟服务会监听系统事件,并通过司机专用应用程序的 API 模拟车队司机做出回应。
  • 事件驱动的架构使用了“发布 - 订阅”模式,一个发布方可以有一个或多个订阅方。
  • 用微服务代表系统中每个可测试和可部署的单位,提供不同功能。
  • 弱耦合的系统在测试方面的操作更简单。

Ousta 是埃及领先的 Ride hailing 公交公司(译注:这是一种不设立固定站点,乘客随上随下的公交运营模式。详见: https://en.wikipedia.org/wiki/Hail_and_ride ),该公司的乘客数和车辆数正在经历飞速增长。我们的系统包含两个移动应用,应用可以与基于微服务的事件驱动的架构进行交互。我们通过配合使用 EDA 和微服务搭建了自动化的模拟系统,借此打造了一个可供我们快速演进的环境。

定义问题

我们分别针对乘客和司机开发了两个应用。在开始实现这些应用时,我们决定先从面向客户的乘客应用着手,乘客可以通过这个应用约车。

开发可以实时更新的应用程序会遇到额外的挑战。每次需要对约车过程进行测试时,都需要模拟下列高层事件:

  • 需要由司机应用接受约车请求
  • 车辆抵达时通知乘客
  • 将乘客送达目的地
  • 结束行程

每次移动应用或后端服务发生变化后,我们往往很难对整个流程进行测试,因为我们手头只有乘客应用和 API。

自动化!

我们开始考虑通过自动化解决方案在测试环境中测试整个流程。可是该如何针对乘客应用中进行的操作执行司机 API?我们曾考虑使用外部微服务执行司机 API,监听由于乘客操作产生的系统事件。在我们所用的事件驱动的架构帮助下,这一切可以很容易地实现。

事件驱动的架构

事件驱动的架构极为强大,针对系统执行的每个操作都会产生一个 JSON 对象形式的事件,其中包含了所需的全部信息。

例如约车请求会产生一个事件,其中包含了乘客信息、上车位置、价格等信息。JSON 事件内容如下:

复制代码
{
// Meta part contains information about the event type and category.
"meta":{
"messageCategory":"event_TripInfo",
"messageType":"newTrip"
},
"body":{
"tripId":"d2eac36c-8131-4409-8c37-863b0725fb4d",
"status":"processing",
"riderId":"4524b80a-f82a-4f1c-ad77-69a620c5c628",
"requestTime":"2016-09-09T15:42:32+0000",
"requestTimestamp":1473435752,
"currencyCode":"EGP",
"rider":{
"riderId":"4524b80a-f82a-4f1c-ad77-69a620c5c626",
"firstName":"Mostafa",
"lastName":"Saeed",
"emailAddress":"msaeedatteya@gmail.com",
"mobileNumber":"+201272509147",
"pictureUrl":null,
"rating":"5"
},
"service":{
"serviceId":"7f888b1f-14e4-4b7e-8f8d-1c1ee1df074c",
"displayName":"Super Saver",
"description":"Ousta super saver service",
"code":"Super Saver",
"image":"https:\/\/s3-eu-west-1.amazonaws.com\/oustaridersapp\/services\/ico_cartype_economy.png",
"carPictureUrl":"https:\/\/s3-eu-west-1.amazonaws.com\/oustaridersapp\/services\/img_onmap_car_taxi.png",
"priceDetails":{
"costPerDistance":"1.45",
"costPerMinute":"0.25",
"distanceUnit":"KM",
"base":"4.0",
"cancellation":"10",
"minimum":"10",
"currencyCode":"EGP",
"commissionPercentage":"0.2",
"commissionFees":"0",
"commissionType":"percentage"
}
},
"city":{
"name":"Cairo",
"code":"CA",
"location":{
"latitude":"30.0594699",
"longitude":"31.1884239"
}
},
"pickupLocation":{
"latitude":"30.067615031955",
"longitude":"31.210990101099",
"text":"Tahrir Square, Meret Basha, Qasr an Nile, Cairo Governorate"
},
// Driver & vehicle are null because ride is not accepted by a driver yet.
"driver": null,
"vehicle": null,
"paymentInfo":{
"paymentMethodId":"4496839d-8cd2-4f98-98bb-e059ca7ac5c1",
"type":"cash",
}
}
}

该事件将由多个其他微服务来处理,例如发送推送通知、短信、邮件,或处于分析需要将乘客信息存储在其他位置。我们使用 Amazon SNS 发布事件,使用 Amazon SQS 接收事件,并将消息队列中的客户事件持久存储。

  1. 使用 Amazon SNS(Simple Notification Service):AWS SNS 是亚马逊提供的发布订阅服务,可用于创建与系统逻辑有关的话题(Topic),随后可在发生特定事件后使用 AWS SDK 将事件发布到这些话题。例如当乘客需要约车时,负责预定车程的微服务为该事件创建 JSON 对象,并将事件发布至 TripEvents SNS 话题。
  2. 使用 Amazon SQS(Simple Queueing Service):AWS SQS 是一种消息队列服务,可用于订阅特定 SNS 话题,这样发布到该话题的任何消息即可持久保存在消息队列中,直到最终被服务使用。

下图展示了系统中的事件从发布到最终被不同微服务处理的完整事件流过程。

(点击放大图像)

如图所示,事件驱动的架构使得我们可以轻松地在系统中加入不同用途的新增微服务,整个过程只需要下列步骤:

  1. 新增一个 SQS 队列
  2. 将该队列订阅至特定 SNS 话题
  3. 新增监听该队列的微服务

模拟器微服务

我们曾实现过一种模拟器微服务。通过侦听 TripEvents SNS 话题,该服务可以很容易地根据产生的事件执行必要的操作。例如当收到的事件表示某位司机准备接受或拒绝某个约车请求后,该服务会通过调用 API 代表司机应用接受该行程,具体过程如上图所示。

最开始我们只实现了一种较为简单的版本,涵盖了从乘客发出请求到行程结束的整个过程。不同调用按顺序执行,每个调用之间等待 10 秒钟。完整的行程过程如下所示:

(点击放大图像)

遍布 Qusta 总部四周的“假”司机

我们希望让模拟的过程更真实,因此开始通过模拟司机在不同街道上的活动对模拟器进行优化:

  • 接到乘车请求之前
  • 行驶至上车位置
  • 到达乘客的目的地

随后我们考虑到可以在测试环境中模拟在我们位于开罗市区的总部周围四处行驶的司机。我们希望每隔 x 秒调用一次司机 API,借此向后端系统告知司机当前位置的经纬度。

模拟司机的驾驶过程

由于希望让模拟的过程显得更真实,我们还对模拟服务进行了优化,用一系列代表经纬度的坐标点代表实际路程,这些坐标点代表了从司机接受行程时的位置到乘客上车位置的全过程,以及从上车位置到乘客(请求者)在应用程序中指定的最终目的地的全过程。为此我们使用 Google Distance Matrix API 获取坐标点列表形式代表的两点间完整路径,这样在司机从 A 点到 B 点的行驶过程中模拟器就可以按顺序发送这些点的坐标。

位置更新触发器

最麻烦的部分在于,该如何设置安排好的触发器,以便将每 x 秒一次的位置更新发送给每位模拟的司机。我们考虑了一种解决方案,使用一个可自动触发给服务的 Cron 作业,但这种方式存在局限,最小间隔为一分钟。因此我们需要用一种特殊的方法使用 Amazon SQS。SQS 提供了一个名为 Delay Queues 的强大功能,使得加入队列的消息可以在实际使用前维持 x 秒的不可见状态。下图展示了我们使用这一功能模拟司机行驶过程的方法。

(点击放大图像)

位置更新的采样率

根据应用程序的需求,我们选择了每四秒一次的采样率。精确频繁的位置更新对我们的应用程序和乘车体验很重要,因为我们需要通过这样的更新计算行程的实际距离。

模拟流程总结

(点击放大图像)

独立进行的应用程序测试

模拟服务使得我们可以在将司机应用程序开发完成之前随时测试乘客应用程序的所有功能,这一特性解决了我们开发工作中一个非常大的依赖性问题,无需同时使用这两个应用程序就可以对整个行程进行测试。

两分钟内完成整个测试周期

借助上述方法,我们打造了一个完整的自动化测试解决方案,可以帮助我们更放心地发布新功能,应用变更,修复现有问题,并让每天多次的生产部署变为可能。

关于本文作者

Mostafa Saeed是 Ousta 公司的软件架构师,这是一家位于埃及,正在经历飞速增长的公交公司。Mostafa 领导着开发团队打造了一套事件驱动,可容错,基于微服务的架构。同时他也是 AWS 顾问,帮助大量初创公司应用有关高可用云,以及缩放能力方面的最佳实践。

作者 Mostafa Saeed 阅读英文原文 How Ousta Simulates Rides within a Two-Minute Test Cycle

2016-12-05 17:011659
用户头像

发布了 283 篇内容, 共 115.8 次阅读, 收获喜欢 62 次。

关注

评论

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

YashanDB ASIN函数

YashanDB

YashanDB ATAN函数

YashanDB

YashanDB ASCII函数

YashanDB

Studio 3T 2025.6 (macOS, Linux, Windows) - MongoDB 的终极 GUI、IDE 和 客户端

sysin

mongodb

使用 Rust 代码实现 FFmpeg 滤镜:简化音视频处理的新方法

Yeauty

YashanDB ARRAY_APPEND函数

YashanDB

YashanDB ARRAY_NDIMS函数

YashanDB

YashanDB AVG函数

YashanDB

海外网络加速新选择:SD-WAN专线助力企业出海

Ogcloud

网络加速 SD-WAN 海外网络专线 SD-WAN网络加速 企业出海网络

内网聊天软件有哪些?强推BeeWorks即时通讯软件!

BeeWorks

即时通讯 IM 私有化部署 企业级应用

YashanDB ARRAY_UPPER函数

YashanDB

2025 年 AI 编程新风向:从智能辅助到自主开发的跨越

飞算JavaAI开发助手

编程 AI 代码

Amazon 最新语音模型 Nova Sonic:比 4o 便宜 80%,智能停顿和打断;a16z 发布 AI 数字人报告丨日报

声网

悖论:智驾难题为何在此刻无解?

脑洞汽车

AI

休克的哪吒:一家新势力车企的失血日志

脑洞汽车

AI

即时通讯软件BeeWorks,企业如何实现细粒度的权限控制?

BeeWorks

即时通讯 IM 私有化部署 企业级应用

YashanDB AGE函数

YashanDB

YashanDB ARRAY_POSITION函数

YashanDB

YashanDB BIN函数

YashanDB

阿里巴巴 Druid 可观测性最佳实践

观测云

Druid

YashanDB ATAN2函数

YashanDB

鸿蒙智行生态联盟爆款频出,四大车企差异化布局显成效

最新动态

亮相2025全球分布式云大会,火山引擎边缘云落地AI新场景

火山引擎边缘云

边缘计算 IoT Edge AI 大底座 AI‘’ 边缘智能

Tuxera NTFS使用教程 轻松实现磁盘格式转换的教程分享 ntfsMac软件怎么用

阿拉灯神丁

MacBook Mac软件 NTFS磁盘管理器 Tuxera NTFS2024 磁盘格式读写软件

Metasploit Framework 6.4.55 (macOS, Linux, Windows) - 开源渗透测试框架

sysin

Metasploit

揭秘热门企业组网方案——SD-WAN到底有哪些优势?

Ogcloud

SD-WAN 企业组网 SD-WAN组网 sd-wan专线 SD-WAN厂家

YashanDB ARRAY_LENGTH函数

YashanDB

YashanDB ARRAY_REMOVE函数

YashanDB

YashanDB ARRAY_REPLACE函数

YashanDB

YashanDB ARRAY_TO_STRING函数

YashanDB

2025 程序员薪资大洗牌:掌握这 3 个 AI 核心技术,薪资瞬间翻倍

飞算JavaAI开发助手

编程 AI 开发者

Ousta如何在两分钟的测试周期内模拟客流_语言 & 开发_Mostafa Saeed_InfoQ精选文章