闲鱼双11端侧实践总结

492次阅读  |  发布于3年以前

如果今年双十一期间你有来过闲鱼的话,你会发现今年闲鱼双十一有非常大的不同,以往闲鱼更多是在双十一前后引导用户出售换新之后的旧物,今年首次在双十一期间构建让去用户去买的场,用户也能上闲鱼捡漏买好货了。今年闲鱼双十一是即买又卖,业务上有很多变化,时间跨度很长。这对于闲鱼端侧既是挑战也是机会,此次双十一我们除了将之前的技术积累更广泛应用,也在一些领域有新的突破。下面整体介绍下今年双十一闲鱼端侧的思考与沉淀。

双十一挑战

今年闲鱼双十一既包含买又包含卖,对应产品功能也都是独立的。由于闲鱼是首次搞这么大规模的双十一,对于业务来说挑战也很大,基本在9月中旬才确定需求范围,那时候产品才进入将业务需求转化为PRD,加上双十一封网时间要求,留给研发的时间已经非常紧张了。为了保障双十一成功上线,我们主要从下面几方面进行准备,后面会依次详细介绍。

  1. 稳定性保障:双十一期间App流量激增,如何提前设计与演练,保障峰值情况下业务体验。
  2. 会场体验:双十一总共加起来有20+会场,会场体验是如何提升的,PHA方案首次应用如何平稳度过双十一。
  3. 端外体验:除了闲鱼App之外,闲鱼在手淘、支付宝、以及微信等端外渠道也有很多流量,如何保障用户端外体验以及提升用户到端内的转化。

稳定性保障

技术演练

  1. 开关有效性自检:为保证双十一期间,可能发生的开关降级导致的问题,需收集配置以及AB开关。由于相关开关太多,其中也有不少已废弃的开关,策略上我们依据pv最高的几个页面进行关联整理开关,由相关业务同学分别验证打开和关闭的逻辑。
  2. 拉端演练:闲鱼作为闲置交易App,双十一期间手淘等集团App唤端到闲鱼的场景必然变多;此外,加上媒介活动投放,也会增加三方广告渠道到闲鱼的唤端。这里拉端包含已经安装闲鱼情况下的普通唤端,也包含未安装闲鱼走下载安装后的场景还原。通过演练保障外部流量能够更好利用。
  3. 容灾演练:考虑双十一期间,后台可能发生降级、限流等情况,端侧需在请求失败和请求返回字段缺失情况下演练。要求:请求失败时,重要页面(如首页)展示上次缓存数据;返回字段缺失时,端侧保证不Crash。目标针对首页、详情、搜索结果页等几个重要页面的关键请求,进行测试。为模拟网络请求字段缺失,基于mitmproxy编写广度遍历算法,每次请求删除不同的返回字段。
#!/usr/bin/python3

import json
from mitmproxy import ctx, http
from mitmproxy.net.http.http1.assemble import assemble_request

class IdleFishModifyResponse:
    def __init__(self):
        self.num = 0
        self.whitelist = ['${请求 url1}','${请求 url2}']

    def response(self, flow):
        inWhiteList = False
        for white in self.whitelist:
            if white in flow.request.pretty_url:
                inWhiteList = True

        if inWhiteList:
            jsonObj = json.loads(flow.response.content.decode('utf-8'))

            ctx.log.info("delete index=" + str(self.num))
            ctx.log.info("before modify:" + flow.request.pretty_url)
            ctx.log.info(flow.response.content.decode('utf-8'))

            if isinstance(jsonObj['data'], list):
                self.removeOne(jsonObj['data'])
            elif isinstance(jsonObj['data'], dict):
                self.removeOne([jsonObj['data']])
            flow.response.content = json.dumps(jsonObj).encode('utf-8')

            ctx.log.info("after modify:" + flow.request.pretty_url)
            ctx.log.info(flow.response.content.decode('utf-8'))

            self.num = self.num + 1

    def removeOne(self, objList: list):
        return self.dfs(objList, 0)

    def dfs(self, objList: list, index):
        children = []
        for obj in objList:
            if isinstance(obj, dict):
                for key in obj:
                    if index == self.num:
                        obj.pop(key, None)
                        return True
                    children.append(obj[key])
                    index = index+1
            if isinstance(obj, list) and len(obj) > 0:
                children.append(obj[0])

        if len(children) == 0:
            return False

        return self.dfs(children, index)

addons = [
    IdleFishModifyResponse()
]

埋点降级

由于阿里集团App基本使用同一套埋点基建,为保证双十一期间,闲鱼重要埋点不受影响,需梳理哪些埋点可以被降频采集。这里重要的埋点包括用增、算法、搜索等。基于Top 100埋点,梳理可进行降级的埋点:其中包括启动框架监控、部分消息等相关埋点。

会场体验

性能优化

此次双十一会场除了全面应用资源离线缓存以及首屏请求预请求之外,主要通过优化渲染方案以及控制模块大小来优化性能。

闲鱼会场渲染方案里默认第一次搭建数据请求返回模块数一般在4-6个,包含一些不可见模块(例如处理PHA滚动),往往不够首屏内容。用户体感是首屏上面几个模块先渲染出来了,然后首屏剩下的模块再渲染出来。在针对这次双十一会场模块进行分析之后,将首屏请求返回模块数固定在10个,虽然这样页面模块上屏时间会延后,但是结合首屏请求Prefetch以及模块资源离线缓存整体会场页首屏可交互时间相比之前能提升400-800ms。

模块大小不仅影响模块资源下载时间,并且在执行阶段也会影响端上解析与执行时间。因此在研发初期我们就将基础Util进行收敛到闲鱼统一的底层Util,减少资源大小。然而发现部分带有动效的模块,单个模块甚至存在超过300k的情况。排查发现这些模块依赖了rax-swiper/universal-animation/universal-transition这些动效基础库,而这些基础库为了覆盖更多场景每个都有100k+,而所需要的动效不需要那么完整的功能,我们将这些动效都通过CSS实现之后,将每个模块的大小控制在30k以内。

最终线上会场首屏平均时间在2.5s(其中主会场由于互动模块资源较多性能相对更差点),相比集团其他团队还有些差距。这主要由于目前会场里闲鱼商品数据投放还是通过模块渲染完之后再次发起请求获取的,并没有接入到搭建平台里直接投放,在会场多个商品楼层的情况下对于整体首屏性能影响会非常大。目前闲鱼前端也在筹备新的产研平台,后续会将闲鱼商品的投放能力与搭建系统的数据服务融合。搭建页面性能这块之前关注较少,还有非常大的优化空间,预渲染、SSR等很多优化方式都可以在后续大促/营销活动中尝试。此外由于整体会场节奏非常紧张,模块一直在调整升级,临近上线离线缓存推包的次数也比较多,覆盖率存在问题,后续大型重要活动中也需要注意。

PHA首秀

闲鱼双十一会场与天猫双十一会场比较类似,主会场顶部有TabHeader可以切换分会场,底部有TabBar可以切换分会场。以往都是通过新开页面的方式打开分会场,切换会场每次都会刷新页面,用户体验不够好。这次考虑采用PHA容器(Progressive Hybrid App:淘宝自研Hybrid容器)来实现,点击在当前页面切换,用户体验更好。当时的情况是,闲鱼App在10月初的正式版本接入了PHA,线上仅有一个产品页在使用PHA投放,多TAB容器还未实际应用。为了让PHA容器能够应用于会场,我们主要丛以下几方面准备:

1 . 研发方式:初期准备使用搭建方案实现PHA多TAB容器,与相关团队评估双十一使用风险较大之后转为源码开发,使用淘系前端提供的跨端研发平台方案,并且评估双十一流量情况,保证线上稳定性。

2 . 线上监控:前端监控业务逻辑层报错;客户端监控容器层报错。为了解决Android客户端缺失日志上报的问题,期间还有一次紧急发布修复该问题。此外在双十一期间还单独安排PHA容器相关同学值班。

3 . 降级预案:根据最终选择的跨端研发平台方案,最终降级方式采用资源位投放更换、客户端开关降级、前端业务逻辑层降级、一休重定向结合的方案。

会场正式上线之后还遇到一些问题,主要有新域名源站cdn缓存、前端jsbridge sdk升级配PHA调用等,通过之前的预案都依次解决,确保线上稳定与体验。

接口容灭

接口容灾采用闲鱼前端自研容灾方案。双十一期间服务端接口相对比较稳定,主要在拍卖会场出现了一些问题。由于业务未注意拍品下架时间,到下架时间之后服务端查询不到商品,前端通过容灾方案请求之前缓存到CDN的商品数据,避免了页面空窗的情况。闲鱼容灾技术方案如下图所示,详细方案[可见闲鱼前端如何做容灾] 。

端外体验

端外唤端优化

双十一配合有外部媒介投放,此次针对性对于鸿蒙(跳转对应应用市场)&抖音(针对Schema链接优化唤端页面加载逻辑)做了适配处理,也首次在某些场景投放了支持Universal Link的会场链接。同时还升级唤端数据协议,可以按照渠道/页面/区块追溯唤端以及下载数据,详细方案见[闲鱼唤端的背后] 。

商品发布升级

闲置商品发布是闲鱼最核心的用户价值。这次双十一我们升级了商品发布器,将商品属性选择能力与端内保持一致,用户端外发布的商品也能具备结构化信息。左右分别是新老版本闲鱼端外发布器。

微信传播体验

在互联互通背景下,微信内也能打开闲鱼链接,双十一期间我们也开展了微信商品详情体验优化项目,打通微信唤端链路,让用户无论是在微信内体验还是唤端闲鱼体验都更好。在双十一期间微信内商品详情页打开pv是平时的2.5倍,助力商家在微信私域内运营其商品。左右分别是iOS和Android下的唤端体验,其中iOS唤端路径:点击唤端ULK -> 弹框确认 -> 拉起闲鱼,Android唤端路径:点击唤端 -> 浮层提示浏览器打开 -> 浏览器打开 -> 拉起闲鱼。

未来展望

今年可以说上闲鱼的“第一次”双十一,业务形态和复杂度已经和前几年有很大差别。闲鱼之前给用户的心智更多是“闲置能赚钱”,用户来闲鱼只是处理自己的闲置商品;而现在“闲不住?上闲鱼!”,闲鱼对于用户来说有更多价值,来优品捡漏高性价比商品,去会玩找同好。这对于闲鱼端侧会有更多新的挑战,无论是通过启动框架特殊处理、直接打开落地页等方式缩短唤端链路时长,还是废弃无用开关、代码CI建设等方式继续保障稳定,以及会场体验上PHA如何和闲鱼已有容器优化结合、渲染机制如何继续优化、SSR如何接入等。闲鱼技术也在持续探索,欢迎你的加入!

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8