BT

你的观点很重要! 快来参与InfoQ调研吧!

蘑菇街11·11:在微信小程序做大促,技术如何支撑?

| 作者 龙隼、明淳、偷天、西行 关注 0 他的粉丝 发布于 2017年11月11日. 估计阅读时间: 15 分钟 | ArchSummit社交架构图谱:Facebook、Snapchat、Tumblr等背后的核心技术

据腾讯旗下的企鹅智酷发布的数据以及腾讯财报公布的数据,微信生态内月活跃用户数据已经超过9亿,在获取用户成本日益高涨的情况下,微信内的用户数据无疑是一个巨大的宝库,因此蘑菇街也一直在关注着如何更好地获取微信内的用户流量。

早在2015年的时候,蘑菇街其实已经在微信体系内有了对应的玩法,比如微信商城、App分享、早期的拼团业务等等,受制于H5在微信生态内的体验,以及微信本身对营销类业务的管理态度,导致效果不太明显。2017年以来,随着微信对小程序的持续投入及扶持,小程序也已经有了类似于native的体验,很多新的玩法结合着小程序不断推出。在这种情况之下,蘑菇街和微信共建了“蘑菇街女装”小程序(在微信->钱包->第三方服务内),希望在微信生态内给用户提供更好的体验。

另外,由InfoQ举办的ArchSummit全球架构师峰会即将于12月8-11日北京举行,大会与阿里巴巴合作策划了双11架构专场,并邀请了顶级技术专家担任出品人,设置了“新一代DevOps”、“人工智能与业务应用”、“架构升级与优化”等17个热门话题,目前大会日程已出,欢迎前来讨论交流。

早期蘑菇街在微信生态内的系统结构

如上图所示,从客户端过来的请求直接打在代理层,经过Nginx中转下发到各业务层,和PC架构并没有太大区别。在蘑菇街体系里由于是标准服务化拆分加前后端分离的结构,因此各个业务很容易进行业务扩展,这个技术体系延续了很长一段时间,一直持续到迁移到小程序才移除掉。在这段时间里,由于缺乏统一管理,越来越多的问题被暴露出来。

  • 难以形成统一规范

    如前面提到的,因为接入业务的团队比较多,那么势必各团队的标准不同。比如前端接入的方式不一样,有些达不到安全标准,有可能一些边缘业务会存在安全漏洞。

    各业务统计的时候,去推动系统以及业务埋点比较难,有的业务是前端埋点,有的是服务端埋点,有的埋点格式不同,有的可能少了一些埋点事件。蘑菇街内很多运营策略包括营销活动对数据依赖还是很高的,在数据缺失或者不准的情况下,会影响业务的正常开展。

  • 整体性能差,导致用户体验差

    系统接口以及页面是在微信容器内打开,用户交互需要有额外的渲染过程,这个过程会受到网络的影响,导致很多时候用户在没有等到页面完全加载完成就流失掉了。

    H5和native的体验相比差了很多,特别是微信生态内涉及到免登流程,这块会和微信多次公网交互。电商体系内很多功能又必须登录以后才能使用,比如领券、下单等,直接让用户输入蘑菇街的账号密码,流失率非常高,走免登流程在弱网环境下超过5秒以上的情况很多,如果是在双11这样的大流量高并发情况之下,结果会更加糟糕。

  • 质量以及管理成本高

    没有统一的发布流程及版本控制,在开发过程中难以把控。一段需求集中期可以按照项目制的方式来管理,等项目阶段结束之后,需求管理就松散了,随着时间的发展没有人能够了解业务发生的变化。

  • 资源浪费

    各业务需要独自承接网络流量,有些业务负载很低,但为了支持业务正常运行,也提供了服务器使用。

微信小程序系统结构

上图所示为进入微信小程序后的系统结构,这是早期和微信官方合作时初步定下来的方式,因为当初定的工期(技术调研评估到测试上线28天)比较紧,我们在考虑如何避免原来架构的问题之后,定下来的一个方案。核心点在于,前端按照小程序的一套体系来实现,服务端基于统一的网关透出。既需要在短期内快速迁移已有业务,又需要考虑到后期能够复用蘑菇街已有的技术工具。如下为微信小程序做的一些变更。

  • 开发规范统一

    蘑菇街基于微信小程序本身的体系,同时结合蘑菇街现有的开发方式,统一开发规范,以提升复用性并降低出现问题的几率。小程序内初步形成了一些组件规范,新开发的功能都会以组件的形式落地,避免重复出现问题。

  • 流程规范化

    用来改善原本分散的开发方式,以班车流程化的方法来管理,统一收集评估需求,按照固定的发布计划发布项目,避免计划外的功能上线导致问题。发布权限收拢起来到固定人手里,由这类接口人去保证代码规范和质量。

  • 服务端基于统一网关(MWP)透出

    蘑菇街为无线端开发了一个基础平台MWP(Mobile Wireless Platform),在此平台隔离无线请求和具体的应用服务,后续对网络层的优化都可以在统一的网络层上进行,降低实施成本。

    此外在这个网关内还提供dsl的功能,可以在客户端包装底层逻辑,提高客户端的灵活性。有关MWP的更多知识可以了解另外一篇内容

  • 全链路业务区分平台处理

    以往微信容器内的业务,和蘑菇街的主业务相互耦合,但由于是运营独立,定制化的需求又比较多,因此针对性的逻辑开发也越来越多,导致系统难以维护。

    在业务开发过程中,蘑菇街对系统进行梳理,对于全链路的系统进行逻辑拆分,以分平台的方式来开发,从商家入驻到商品招商到导购业务,再到详情、交易、促销、支付以及资金结算等等,在整体业务上定义了统一的分平台标识。不光从业务上解决了以前相互耦合的情况,后续蘑菇街继续推出的新小程序也能够低成本地接入,并且各自独立不会互相影响。系统架构上也可以做低成本的扩展,后续会详细介绍。

前端技术演进

第一版蘑菇街微信小程序上线之后,体验相比以前有了很大的改善,业务数据也持续增长。随着业务的发展,微信小程序本身的一些限制,制约了我们的业务发展。

  • 小程序包大小限制。
  • 页面层级限制。
  • 组件对于蘑菇街业务而言,复用度不高。

针对上述问题,前端在技术体系上做了一些调整,并且积累出一些工具,更加方便于和蘑菇街已有的一些系统接合。

VX

针对vue内的sfc结构组件,将template中的模板部分转化到小程序的wxml,style里的css部分转化为小程序的wxss,script里的js部分转化为小程序的js。

  • 模板层比较复杂,需要对vue进行语法分析得到抽象语法树,然后再一一映射到小程序的语法,就是一次把字符串拆成ast,再转化成另一种语法的字符串的过程。
  • CSS部分主要是单位转化,把px、rem单位转成小程序里的rpx。
  • js部分是核心,虽然不需要语法上的转化,但是需要实现一套统一标准,保证在vue和小程序端都能跑起来,其实就是要实现一个框架。但是为了方便,我们并没有重新构造一套框架,而是将vue的核心部分(除了模板渲染)搬到了小程序里,模板渲染依旧使用小程序内置的。

目前vx已经能够实现微信小程序和H5代码生成,正在对接Xcore中。

Min

Min是蘑菇街基于实践摸索沉淀出来的一套面向小程序组件化的解决方案。通过Min,小程序开发者可以优雅高效地进行自定义组件的开发和使用,为开发者赋能。Min目前提供Min Dev(开发环境)和MinUI(UI组件库)。

Min Dev一期提供了CLI服务(后续将提供GUI服务,进一步降低普及成本),包括开发范式、一键式搭建开发环境、Demo预览小程序、内置化文档、自动编译打包、组件一键发布、安装、更新等能力。

MinUI是一套小程序UI基础组件库,基于统一的UI规范,是一套基于Min的小程序组件化开发最佳实践。一期提供了18个基础UI组件,并提供了一个独立的演示版小程序供开发者体验。

目前Min已经开源。有关Min的更多介绍请戳这里

动态模块加载

微信小程序的包有2MB的大小限制,蘑菇街作为一家电商公司,本身功能就特别复杂,一些基础功能譬如图墙、商品详情、下单、支付、IM、退货退款还有维权等等功能,占用的空间就比较多了,电商促销也很多,经常会有各类运营活动促销页推出来,因此2MB的包大小极大地限制了我们的业务发展。

动态模块的机制是结合蘑菇街现有的技术体系——蘑方构建出来的,蘑方本身是一个工具,里面维护了公司内部的各类业务组件库以及基于组件搭建页面的功能。在微信小程序中,此机制就是尽量把业务需要的组件库以及页面框给打包到小程序包内,在搭建页面后台里其实维护的是组件组合的配置,以.json存储在ats上。小程序中展现形式多样化的页面,如活动页面,其实是在页面渲染的过程中动态加载配置,然后进行组合渲染。这种机制的出现可以很好地解决小程序包越来越大的问题。

其实在业务上我们还做了很多其他的尝试,比如业务分包、代码控制等,也可以改善包大小的限制问题。

其实小程序内打开H5页面也可以很好地解决这类问题,在我写这篇文章的时候微信已经支持这个功能。不过我们上述方案在一定程度上比小程序原生的方式灵活,体验又会比H5更好。

服务端技术演进

业务服务分组

当业务增长达到一定规模之后,提供业务功能调用的服务端集群对应的调用源可能会比较多,这时候我们希望针对性地对一些服务做分组管理,比较简单的方式是以部署机器的方式来做,也可以按照调用来源的方式来做。

举个例子,如上图所示,当一个服务集群C对外提供服务S1和S2,有两个外部调用集群A和B同时订阅了S1和S2两个服务,当A和B的调用量远远达不到C的服务能力的时候,这个架构本身问题不大。

但是当A或者B一方甚至两方的调用量激增起来,这个时候调用集群就有可能互相影响。我们在架构上做了一些调整,让消费集群可以互不影响。我们把服务集群C拆分为C1和C2(两个集群都可以提供S1和S2服务),消费集群在订阅的时候,可以按照规则选择订阅哪个服务集群。此时A和B调用的集群分开,服务集群C1和C2页互不影响,业务相互隔离,从稳定性和容量规划上来看更加合理。

分组可以基于多种规则来定制,比较灵活,在实际使用过程中更多还是以服务器分组的方式进行,维护成本更低。

面向小程序(数据)的容灾策略

这里以导购类业务来举例说明数据容灾的一些变化。这类业务的特别之处在于业务变化快,表现上以数据展示(数据加工)为主,交互逻辑简单,相对于详情和交易这类需要实时交互的业务而言,可以以低成本的方式做一层数据容灾。当上层业务出现问题的时候,本身应用容灾的逻辑都失效了,那么这个时候数据就是最后一层容灾了。

如上图所示,前端请求到服务端,正常返回进行渲染,展示给用户看。当这个过程中出现异常,譬如服务端逻辑错误、网络中断等,这种情况对于电商而言商品类的曝光量会收到很大影响,相对应的广告收入也会降低。为了解决此类问题、提升系统的可靠性,我们提供了两种方式去做数据容灾,核心思路都是以空间换稳定性。

  • 第一种是可以穷举的条件组合情况,我们在服务端计算出对应的数据场景,将之定期同步到CDN上。
  • 第二种是依赖于用户操作(以用户搜索商品为主)的场景,那么会进行打点并且去离线统计,覆盖约90%左右的用户访问数据,定期同步到CDN上。

当前端请求失败的情况发生时,会直接请求CDN上的容灾数据,数据更新在分钟级。

补充说明下,这只是我们已有的多级容灾策略的一种补充,仅仅用来保证最上层业务数据的正常透出。

个性化推荐

蘑菇街的推荐系统始于2016年,经过一年的发展,现在蘑菇街全站很多产品都已经接入,包括商品、店铺、搜索、导购以及社会化等。

推荐系统的整体架构可以分为三个部分:

  1. 推荐数据存储层:使用的是蘑菇街自研的一套KV内存数据库,用来存储推荐数据、特征数据的底层存储介质。
  2. 推荐数据计算层:针对推荐结果、用户特征、排序模型进行离线计算,基于用户行为、推荐内容的特征数据进行实时计算。
  3. 推荐投放服务层:按照特定的召回策略,组织推荐结果投放展示。

在推荐投放服务层,算法工程师面向场景开发推荐结果召回策略;系统工程师为了策略脚本的执行,提供数据结构和运行时环境,保证系统稳定性,二者协同提供个性化投放服务。

蘑菇街的推荐投放服务,有两个重要特征:

  1. 推荐内容类型多。作为一家社会化电商公司,提供的除了传统电商平台的商品、店铺、搜索、广告等电商平台的推荐数据,我们还提供了社交内容的推荐,并且范围扩大到了红人、直播等业务。推荐的场景是完全不同的。
  2. 跨团队协作。蘑菇街内部有多个算法团队,所在地也分北京和杭州,需要在一套系统上开发多种需求,沟通对接存在成本。

以上两点决定,蘑菇街开发出来的一套通用的推荐投放系统,向上可以统一透出各类结构化数据,完成数据补全、格式化工作,向下可以快速接入多种数据源,满足不同业务线的推荐需求。

展望

微信本身的活跃用户群体十分庞大,随着微信在小程序内的投入日益增加,蘑菇街对这块也是越发看重。

现阶段蘑菇街的用户群体还偏年轻化,性别也是女性用户占绝大多数,进入小程序以后用户群体就完全不一样了,因此对于蘑菇街的基础工具系统带来了更大的挑战,比如如何管理商品、店铺,做一些营销活动等;对于推荐系统也带来了更大的机会,我们可以有更多的策略运用在不同的场景上。

蘑菇街目前面向小程序的积累还远远比不上在PC、native、Xcore的积累多,因此接下来组件和工具的积累就显得格外重要。对于数据的积累,特别是用户层面行为和偏好数据的积累,后续我们会结合着微信进行,应该可以极大地完善蘑菇街的数据积累。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT