“云无界、端无边” OGeek 技术峰会 9月17日 南京不见不散! 了解详情
写点什么

美团点评云真机平台实践

  • 2020 年 2 月 27 日
  • 本文字数:4740 字

    阅读完需:约 16 分钟

美团点评云真机平台实践

背景

随着美团点评业务越来越多,研发团队越来越庞大,对测试手机的需求显著增长。这对公司来说是一笔不小的开支,但现有测试手机资源分配不均,利用率也非常有限,导致各个团队开发、测试过程中都很难做到多机型覆盖。怎么样合理、高效利用这些测试手机资源,是摆在我们面前的一道难题。


现有的方案

为了解决这些问题,业内也出现了一些手机管理和在线调试使用的工具或平台,比较常见的有:


  • OpenSTF

  • 百度 MTC 的远程真机调试

  • Testin 的云真机

  • 腾讯 WeTest 的云真机

  • 阿里 MQC 的远程真机租用


其中 OpenSTF 是开源项目,其他的平台大多也都是基于 OpenSTF 原理实现的。因此,我们对 OpenSTF 项目进行了深入研究。


遇到的问题

我们首先按照 OpenSTF 官方的方案进行了搭建,并进行了小规模的应用,但渐渐的我们发现了它的一些问题:


  • 模块过多而且耦合紧密,解耦难度较大,每次修改需要更新所有模块,难以快速迭代开发。

  • 部分技术选型落后。由于 OpenSTF 出现的时间比较早,部分技术已经落后于目前的主流。例如 OpenSTF 前端选用 AngularJS 1.0 进行开发,在生态链方面已经落后于其他流行的框架;数据库方面选用非关系型数据库 RethinkDB,在数据计算和性能方面弱于 MySQL 等关系型数据库,同时 RethinkDB 资料较少,不便于开发与维护。

  • OpenSTF 屏幕图像传输采用图片单张传输的方式进行,而且画质不能由用户来调节,实际应用中占用带宽很高,在网络比较差的情况下会有严重的卡顿现象,体验很差。


我们的方案

架构设计

根据业务场景的需要,并吸取了 OpenSTF 结构优点,我们采用 Agent/Server 模型的模块化设计方案。下面分别介绍主要模块的功能:


  • Agent 模块。Agent 模块与 OpenSTF 的 provider 类似,部署在服务器上或者用户的电脑上,Agent 连接真实的手机,并且将手机的屏幕图像通过 Websocket 动态代理到 Websocket 服务器上,然后通过消息中心来进行消息的传递。

  • Server 模块。Server 用来集中管理和调度手机,与 OpenSTF 结构不同的是,我们的 Server 端包含 Web 服务器、Websocket 服务器、动态代理以及消息处理服务等部分,Server 将用户的访问动态代理到对应的 Web 服务器和 Websocket 服务器上,并通过消息处理模块向消息中心传递消息,实现用户与 Agent 端手机的交互。

  • 数据存储模块。数据存储模块用来保存整个平台的数据,例如手机的状态、用户使用记录等。数据存储模块由 MySQL 数据库和一个 RPC 服务组成,Server 不再直接读写数据库,而是通过一个 RPC 服务来进行数据的读写操作。

  • 消息中心。与 OpenSTF 的 triproxy 功能类似,是连接手机和 Server 的枢纽,消息中心主要处理屏幕的操作以及手机的状态变更等消息。


通过模块化设计,项目结构比 OpenSTF 更加清晰。下面是整个系统的设计图:



架构的优势

Agent 模块我们直接复用了 OpenSTF 的 provider 大部分功能,包括 minicap、minitouch 等。在此基础上,我们也扩展了一部分 OpenSTF 缺失的功能,比如:


  • 在 provider 的基础上进行了二次开发,使其支持画质/帧率调节(下文会有详细说明)。

  • 加入健康检测功能,检测手机网络是否正常、是否设置了网络代理等。

  • 加入 Inspector 功能,方便获取 UI 控件树(下文会有详细说明)。

  • 对 Agent 进行了版本区分,便于 Web 端根据不同的 Agent 版本对相应的功能展示和隐藏。


在 Server 模块中,我们引入了动态代理的机制,并且重新开发了 Web 部分,采用了 Vue 2.0 + iView 来实现,数据库采用了 MySQL。


相比 OpenSTF 原生架构,总结下来有以下优势:


  • 模块耦合程度低,开发和部署更方便。OpenSTF 各个功能模块不仅数量多而且代码耦合紧密,在此基础上进行二次开发和部署非常困难。而我们将整个项目分为 Server、Agent、消息中心、数据存储四个模块,四个模块功能和代码都是独立的,基本上没有耦合关系,支持快速迭代开发,部署也很方便。

  • 前端框架更主流,开发和维护成本低。OpenSTF 前端是使用 AngularJS 1.0 实现的,AngularJS 1.0 已经处于废弃阶段,各种第三方组件基本已经停止支持,AngularJS 2.0 的社区和生态并未成熟,而我们采用了 Vue 2.0 前端框架,Vue 2.0 相对已经成熟,在美团侧也已经有大量应用,能够快速开发高质量的 Web 功能。

  • 数据库性能强,设计灵活、维护方便。OpenSTF 使用 RethikDB 作为数据库,RethikDB 是一个 NoSQL 型数据库,它有非常多的缺点,比如处理大量数据时的性能很差,资料非常匮乏,排查问题和数据库维护都非常困难。而我们采用了 MySQL 数据库,很好的解决了这些问题,并且实现了 Server 模块与数据读写的分离,这样在更新数据库表结构的时候无须同时修改 Server 端的代码,只要保证 RPC 服务的接口格式一致即可,开发和维护更加方便。


除了这些基础的功能之外,我们还开发了一些特色的功能,下面我们来详细介绍。


特色功能

与客户端自动化相结合

为了合理、高效利用测试手机资源,我们与客户端自动化进行了结合,主要有两个方面:


  • 与集团内部的云测平台深度融合。在云测平台的服务器节点上部署 Agent 代码,为云测平台自动化任务创建者提供自动化过程展示和远程调试功能,同时将云测平台空闲的手机开放给更多人使用。

  • 开放 API。我们开放了一些 API 给普通用户,供用户查询手机状态、占用手机、连接 adb 调试等,用户可以使用脚本调用 API,然后直接在平台的手机上进行自动化测试。



预约功能

当一台手机处于繁忙状态时,用户必须要等待手机空闲后才能使用,由于手机空闲时间不确定,就会给用户带来很大的不便。为了解决这个问题,我们开发了手机预约的功能,用户可以预约处于繁忙状态的手机,当手机空闲时,自动帮预约用户占用 15 分钟,并通过即时通讯工具通知预约人。


画质调节

远程调试平台的核心是实时获取屏幕图像,由于屏幕传输需要比较大的网络带宽,在网络不佳的情况下就会出现卡顿现象。因此,我们针对不同的网络做了一些流畅度的优化,下面来介绍一下其中的细节。


屏幕获取的原理是通过 minicap 来高速截图,每秒最高可达 60 张,然后将这些截图显示在 Web 上。因此,我们考虑从两个方面来优化网络带宽的占用,第一个是调节截图的质量,minicap 本身支持调节画质(OpenSTF 固定设置了 80%的压缩比),关键代码如下:


var rate =  Number(match[6])    if (rate > 2 && rate < 100) {      log.info(rate)      if (rate > 30) {        options.screenJpegQuality = 80      }else if (rate > 15) {        options.screenJpegQuality = 50      }else {        options.screenJpegQuality = 20      }
frameProducer.restart() framerate = rate }
复制代码


第二个是调节每秒发送的图片张数,也就是帧率,我们可以在 Agent 端控制发送图片的数量,关键代码如下:


# 首先修改帧率发送部分:function wsFrameNotifier(frame) {    if (latesenttime == 0 || Date.now()-latesenttime > 1000/framerate) {      latesenttime = Date.now()      return send(frame, {        binary: true      })    }  }# 再加入调整帧率的代码:case 'rate':    var rate =  Number(match[6])    if (rate > 2 && rate < 100) {      framerate = rate    }    break
复制代码


那么,帧率和图片压缩比调节到多少才能满足不同网络环境的需要呢?我们先来看一组数据:


图片压缩比图片尺寸
100%69.82KB
80%46.78KB
50%41.87KB
20%37.84KB
10%35.84KB


表中是使用 minicap 做的图片压缩实验,从数据中我们可以看到当图片质量降低到 80%时图片大小降低比较明显,而图片质量并没有明显的下降。继续降低图片质量,图片大小降低有限。我们再来看另外一组数据:


帧率图片压缩比实际流量
60100%4.02M/S
6080%2.74M/S
6050%2.41M/S
3080%1.43M/S
3050%1.22M/S
3020%1.10M/S
1550%0.63M/S
1520%0.55M/S
1510%0.52M/S


表中是各种帧率和压缩比组合产生的实际流量数据。


从数据中我们可以看到最高帧率和压缩比的组合下,流量达到了 4M/S,而 80%压缩比时流量减小到了 2.7M/S,降低非常明显。考虑到实际网络情况,我们将 60 帧、80%压缩作为了高画质选项


而图片质量从 80%降低到 50%时图片大小下降并不明显,此时降低帧率就成了很好的选择。当帧率降低到 30 帧时流量降低了一半,1.2M/S 的流量能够满足大部分网络状况使用,30 帧也能保证操作的流畅度,于是 30 帧、50%压缩比成为了中画质的选项


低画质主要是为了保证在较差的网络环境能够正常使用,500K/S 的流量是红线。我们将 15 帧、20%压缩比作为低画质选项,此时图片质量和帧率较低,但能够保证基本的使用体验。



除了通过降低图片质量和帧率来减小手机屏幕图像传输的流量外,将图像使用 H264 等编码压缩成视频传输也是一种有效降低流量的办法,相对于图片,图像的压缩率将会更高,用户的操作体验也会更好。但是图像压缩编码原理比较复杂,相关技术我们还在研究当中。


App Mock

在做 App 测试过程中经常需要抓包,一般情况下,我们通过修改 WiFi 的代理然后用抓包工具就可以实现。但是这样做的效率比较低,多个工具切换也非常不便。借助集团的 Mock 平台,我们开发了一键 Mock 功能,能够快速完成相应 App 的 Mock 操作。带来的好处是我们可以一边操作 App,一边查看 App 发出的请求,大大提高了测试的效率。



App Inspector

App Inspector 功能可以让用户在平台上使用真机的同时查看页面控件树及页面元素,并且支持 Xpath,更加方便高效的查找页面元素,给 UI 自动化测试提供了很大便利。



这个功能我们是借助 Uiautomator 实现的。基本原理是写一个 Uiautomator 用例,用来获取当前页面的 Hierarchy,然后将用例打包成一个 JAR 放到 Agent 端。当在 Web 端触发获取控件树时,Agent 将 JAR 包推送到手机上并运行,此时会在手机端生成一个 XML 文件。然后再使用 cat 命令获取 XML 内容并在前端解析。用例核心代码如下:


public class launch extends UiAutomatorTestCase {
public void testDumpHierarchy() throws UiObjectNotFoundException { File file = new File("/data/local/tmp/local/tmp/uidump.xml"); UiDevice uiDevice = getUiDevice(); String filename = "uidump.xml"; uiDevice.dumpWindowHierarchy(filename); } }
复制代码


当然,你也可以用 adb 命令来获取 Hierarchy:


adb shell uiautomator dump /data/local/tmp/uidump.xml
复制代码


但这种方式不能获取动态页面,比如视频播放页面。


数据报表

为了更好的了解平台的运营情况,我们做了详细的数据统计,主要从使用次数、使用时间、设备数量、使用分布等方面进行统计。目前我们管理的手机近 300 台,平均每个月有超过 500 名研发人员在使用我们的平台,每天的使用次数达到 280 次,每天总使用时长超过 60 小时。




其他小功能

除了以上几个比较大的功能点,我们也做了一些贴心的小功能,比如:检测手机网络是否设置代理、检测手机已安装的应用版本及安装时间、快速安装最新版本的测试包、支持 App 内的 Schema 跳转等等。这些小功能为研发人员节省了很多时间,提升了他们的工作效率。



未来规划

iOS 手机支持

目前,云真机平台只支持 Android 手机,对 iOS 手机的支持正在进行中。我们已经初步完成了主要功能的开发,预计很快将与大家见面。


产品优化

我们计划继续扩展产品功能,比如支持 Log 日志展示和性能数据采集等。目前云真机平台已经在美团点评内部平稳运行超过两年,我们会继续不断迭代版本、打磨产品,提供更好的使用体验。


作者简介

  • 东初,大众点评平台质量工具组负责人。7 年互联网行业测试、开发经验,2015 年加入原大众点评。先后主导了云真机平台、单元测试平台、web 安全实验平台等项目的开发,致力于用工具来提升研发团队的工作效率。

  • 李帅,大众点评高级测试开发工程师。2015 年加入原大众点评,主要负责云真机平台的开发以及客户端底层组件的测试。热衷于钻研测试领域的前沿技术,并推动了多项新技术落地。


2020 年 2 月 27 日 11:14873

评论

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

突破困局

Neco.W

感悟 工作 创业心态

Gartner 【RPA市场竞争格局】:中国厂商首次进入国际视野

人称T客

Android原生人脸识别Camera2+FaceDetector 快速实现人脸跟踪

sar

联邦学习与推荐系统

博文视点Broadview

人工智能 大数据 学习 推荐系统

健身一周年:持续锻炼带来无法想象的改变

Skipper

学习 职业 专注 健身

宕机原因千千万,被雷劈了最无奈

田晓旭

多线程与线程安全(实例讲解)

YoungZY

Java 多线程 线程安全

Vol.3 人工智能这么热,你必须知道一点儿!

pyfn2030

人工智能

源码分析 | Mybatis接口没有实现类为什么可以执行增删改查

小傅哥

Java 源码分析 小傅哥 mybatis 编程思维

一致性算法 Raft 简述

架构精进之路

raft 一致性算法

Vol.2 谷歌不只有搜索

pyfn2030

谷歌Google

原创 | 使用JUnit、AssertJ和Mockito编写单元测试和实践TDD (十)在项目中准备测试环境

编程道与术

Java 编程 软件测试 TDD 单元测试

使用<input>标签实现六个格子验证码输入框

brave heart

Java vue.js 大前端

你的团队是干什么的?

姜戈

团队管理 团队职能

实现元素等高: Flexbox vs. Grid

寇云

CSS css3

Vol.1 Java初探,新手必看!

pyfn2030

编程 新手指南

python实现·十大排序算法之计数排序(Counting Sort)

南风以南

Python 排序算法 计数排序

你真的会用Mac中的Finder吗

Winann

macos 效率 App Mac

你的团队想做出什么成果?

姜戈

团队管理

揭秘神经拟态计算:缘何成为AI界新宠?

最新动态

Anaconda与虚拟环境

halapano

Python virtualenv Anaconda

管理规划篇

姜戈

团队管理 团队组织

100天从 Python 小白到大神最良心的学习资源!

JackTian

Python GitHub 学习 Python-100-Days Python-Core-50-Courses

终于,我也到了和Eclipse说再见的时候,难说再见

程序员小跃

Java eclipse IDEA

好的软件工程原则

pydata

ARTS week 2

锈蠢刀

Spring Security 两种资源放行策略,千万别用错了!

江南一点雨

Java spring springboot springsecurity

你为什么“啃不动”你手中的技术书?

图灵社区

Java Python 算法 HTTP R语言

redis过期策略和内存淘汰机制

wjchenge

码农远程办公指北

大伟

如何用一台电脑制作一部动画短片?

zhoo299

动画 CG

首届腾讯云大数据峰会暨Techo TVP开发者峰会

首届腾讯云大数据峰会暨Techo TVP开发者峰会

美团点评云真机平台实践_文化 & 方法_美团技术团队_InfoQ精选文章