专栏名称: 狗厂
目录
相关文章推荐
51好读  ›  专栏  ›  狗厂

爱奇艺社交泡泡后台微服务实施 ── 6千万日活+双周发版的系统如何快速迭代

狗厂  · 掘金  ·  · 2018-04-11 02:15

正文

作者|wdn626、orange_zjl、thomas、rayzhao

作者介绍

wdn626,爱奇艺移动客户端泡泡后台组开发经理,自2016年底开始接手泡泡后台及几个互动后台系统的研发工作,对中间件、后台系统优化、以及复杂系统架构梳理等具有一定的经验。

orange_zjl,爱奇艺移动客户端泡泡后台组开发人员,自2015年加入泡泡团队,负责泡泡后台版本需求开发、后台系统优化以及微服务拆分等工作。

thomas,爱奇艺移动客户端泡泡后台组开发人员,自2016年加入泡泡团队,负责泡泡后台需求、微服务拆分以及系统优化工作。

rayzhao,爱奇艺移动客户端泡泡后台组开发人员,自2016年加入泡泡团队,负责泡泡后台需求开发以及微服务拆分工作。

请输入标题     abcdefg

导 读

微服务不是万能的,也不要为了微服务而微服务。能够支持业务在各个阶段的成长是第一位的,就好比泡泡平台从最开始定位的的社交(聊天、发帖),到目前的明星、兴趣社区和运营推广,再到未来的不同业务的基础平台,每一步的业务成长都是促使我们技术演进的最强动力。

对于一个6千万日活的系统,任何架构改变都务求谨慎,本文讲述了爱奇艺泡泡系统微服务实施过程中的思考和经验。

1

泡泡业务系统介绍

爱奇艺移动App的右下角常驻着一个泡泡的图标,点击即可进入一个精彩的世界。 泡泡定位的发展战略是融合内容、播出、宣发、粉丝四大平台为一体,目前更通用的产品的说法是娱乐粉丝社区 ,在此平台上可以聚拢相似爱好的用户群体,并组织内容。熟悉微博和贴吧等产品的读者相信对此一定不会陌生。该系统目前高峰DAU超过6千万 ,算是一个体量比较大的平台。在一些大咖位的明星来线上做互动(明星翻牌)活动时,单单一条Feed(可以理解成是一条微博)内容一小时内评论楼数超过60万。系统整体QPS超过100K/s。

每一个社区在泡泡产品形态中就是一个”圈子”,圈子的类型有多种 (明星圈、视频圈、兴趣圈、游戏圈、漫画圈、图书圈、等等) ,不同类型的圈子也有不同的玩法,比如明星圈可以做积分任务、为喜欢的爱豆打榜、发起对应明星的应援活动(众筹)、追踪明星的行程信息等等;视频圈里面可以直接看视频等。每个圈子下面汇集了用户自发、编辑运营的相关内容(我们叫做Feed流),以及相关圈子的周边信息(比如明星圈可以查明星资料,视频圈可以查同一个导演的相关视频等)。

技术上与一般的页面服务不同的是, 泡泡系统的读写操作同样重要,对于明星圈甚至是写操作更重要,用户非常在意自己做任务的积分、打榜贡献是否正确的加上了 所以写操作要有一定程度的事务支持。

2

实施微服务前的系统情况

由于历史原因,最初时候,泡泡后台、运营后台和feed系统,这三个系统代码在一个工程当中,共用底层的存储资源,只是在代码层面通过不同的model来区分。每当有一个模块有改动的时候,很容易相互干扰。

随着用户量的增长和业务的发展,这种结构远远不能满足需求。在这种矛盾的情况下,我们进行了拆分,由单一项目拆分成了泡泡后台、运营后台、feed后台三个项目。 同时,将存储也剥离开来。大大降低代码改动和上线的风险。这种方式,也带来了其他的问题,资源占用集中(db、cb、redis等),运维成本增加。

运营层面,最开始的重点是明星圈子,泡泡平台的定位即是明星业务,打造粉丝社区,这是一个单一的平台,业务也相对单一。后续,运营层面增加了视频、游戏、漫画等业务。未来,将向着平台化的方向发展。

综合这些问题,加上分析和调研的结果,我们打算引入微服务。

3

微服务化的原则

首先说拆分的目的:永远都是为业务服务,实现公司业务的不断增长和演进是我们的终极目标。

泡泡后台从2016年上半年上线初始的几百万日活,到现在的接近7千万日活,后台系统的技术栈也需要不断地迭代。形象点的例子是最初的泡泡系统是一棵小树,不断长大到一定程度就需要不断的剪枝,栽培更多的小树。在当初几百万日活的情况下完全没有微服务化的必要,当时一切都是以功能快速上线为目标的;但是经过一年多的发展,以现在的视角来看,之前的架构慢慢显得臃肿,开发效率逐渐降低,维护的成本却在不断攀高,微服务化能够给我们带来未来一段时间更好的发展。

另外一个方面是泡泡后台的定位也从最初的明星圈+视频圈,演进到了未来平台级的系统,可以更好地支持细分的各类兴趣圈以及公司其他的垂直业务。 所以泡泡要做面向业务到面向平台+业务的转变。

从技术角度讲,泡泡系统的微服务化主要为了达到几个目的:

1

系统和人员可以分而治之,获得更高的开发和维护效率(DevOps)

2

持续优化(ownership)、更专业的人员做更专业的事情

接下来讲泡泡后台微服务化的原则:

01

松耦合和高内聚

松耦合很好理解,服务彼此独立,修改一个服务不要影响其使用方。比如用户相关的功能全部由用户微服务实现、圈子相关的功能全部由圈子微服务实现,彼此之间如需交互则通过通用(最好还是统一的)接口来实现。 内聚性还包括数据的内聚,用户的信息只存在用户微服务中,其他服务需要的时候通过接口去获取。

那么问题来了,使用方是否需要缓存用户信息呢?——我们的答案是, 唯一需要缓存的场景是使用方不信任服务提供方的服务级别 (万一服务宕机了怎么办,万一网络故障了怎么办)。这种情况在公司内部普遍存在,如果大家自由发挥那么到最后一定变成了调用链上每一步都加一道缓存,对资源是一定的浪费,且容易引起数据不一致的情况。

那么我们的原则是: 关键数据 (获取不到会较大范围地影响用户体验或数据异常) 和使用量大的数据 (使用方不缓存的话就会对服务提供方带来超高的QPS) 需要缓存,其余的数据尽量通过微服务层面直接获取。 松耦合和内聚性还有另外一点,就是服务之间大家建立好契约(往往是接口规范),只要接口不改内部实现随你去折腾吧,结果就是接口层面的更改大家会更加谨慎,减少了很多联调成本。

考虑性能

02

服务化相比组件化,由进程内部的调用改为了服务间的调用,引入了网络IO等额外的性能损耗,所以拆分服务的过程中通常会遇到的一个难题就是如何保证性能。

目前市面上实现起来比较灵活的方案是以RESTful风格的的接口来界定各个子系统的切面,但是这种基于http的协议牺牲了性能来达到这个灵活,每次请求的http握手无形中浪费了大量的系统资源。与之对比的是各种RPC方案,采用长连接+压缩过的序列化数据传输,可以一定程度地减少网络开销,也就提高了性能。对比一下单机http服务和RPC服务的压测结果就可以看出来,两种协议至少在能够支撑的QPS上相差了10倍以上。但是RPC的缺点也比较明显,对客户端是有侵入的,增加了系统耦合性,且排除故障时也相对困难。

最终鉴于泡泡系统较高的QPS要求,我们在多数对内服务的微服务系统上使用了RPC框架、少量QPS要求不高的系统保留http服务,对App端统一由mixer层实现http服务。以用户RPC服务为例,高峰时段整体QPS为40K,单台QPS保持在2500左右(压测单台QPS可支撑10K+)。接口响应时间在5ms以下。同http服务对比RPC性能优势明显。

03

使用合理的技术栈

这里拿RPC框架选型为例:市面上存在大量的RPC框架 (Solar、gRPC、Dubbo、甚至Spring Cloud等) ,但是我们最终选择了爱奇艺移动后端团队基于thrift实现的RPCHUB框架。

原因就是这个框架在移动后台线上运行超过1年的时间,泡泡期望可以少踩些坑,并且在出现问题时可以直接找到最熟悉框架代码的开发人员来支持。而使用开源框架的话,虽然团队中的过半数成员在之前其他公司的工作经历中都或多或少地使用过一两种开源框架,但是统计了一下真正读过框架源码的同学并不多,即使读过源代码万一遇到冷门点的问题也很可能抓瞎。

两相权衡我们最后还是选择了内部使用经验丰富的框架RPCHUB,即使这样我们在使用的过程中也遇到了一些问题,花了些时间来解决(框架升级了2个小版本来解决这些bug)。

围绕业务功能组织微服务拆分

04

我们的理论是只要拆分合理,各自为战是可以的。目前泡泡系统已经做到了谁构建、谁运行,我们发现大家的主人翁意识(内部我们通常说ownership)更强了,上线前开发自己把关更严格了,线上问题处理也更加积极。但架构以及服务实现的编程语言,还是尽量做到统一,主要也是为了少踩坑。

我们团队目前都是java背景,即使需要实现一个多线程的微服务听起来用Go比java简单很多,但是把大部门第一个Go语言的服务推上线,需要做的相关测试工作听听就头大。

那么多小的服务算微服务呢? ——没有拆分的动力就可以了!说明没有痛点了,也就没有拆分的必要了,目前我们根据自身的业务情况选择了以业务实体和业务功能两种拆分方式。

按业务实体拆分

在泡泡业务上,我们把实体划分为圈子、用户、事件、资源位等。 在拆分前,泡泡API和运营后台会共同维护这些实体,经常会出现数据不一致的情况,所以我们决定对这些实体进行拆分,按照实体类型拆分出多个微服务,每个微服务只负责该实体的功能,并在泡泡API和运营后台及其他使用方中接入对应的微服务。

当然,拆分是一个缓慢的过程,在拆分时,我们优先选择了业务较为单一的事件实体进行了拆分,为该实体申请了独立的存储资源,并采用统一的RPCHUP框架完成了事件微服务的拆分。之后针对事件实体相关的新需求,在不需要修改RPC接口协议的情况下,我们只需要在事件微服务中增加功能即可。

同时,别的业务系统若需要获取某种实体信息,直接接入对应的微服务即可。基于此思路,我们后续又完成了圈子、用户、资源位等其它单独实体的拆分。

按业务功能拆分

在业务功能上,我们从泡泡API中优先选择了签到和圈友关系两个模块作为微服务,用于服务各种类型的圈子。以签到模块为例,在拆分前,经常会有用户报障说签到不成功,在定位问题时发现,缓存的写操作偶尔会出现操作成功,但是数据未更新的情况,怀疑是缓存QPS太高导致(当然还有其他问题,包括数据库压力大、表结构设计缺陷、缓存结构的设计缺陷等)。刚开始我们打算通过拆资源的方式解决,但又鉴于签到功能的相对独立以及泡泡后期的平台化,我们最终决定申请新资源并将签到功能拆分为一个独立的服务。

从实施效果来看,拆分出的微服务功能还是非常稳定的,未再出现过类似报障。

05

去中心化地治理服务







请到「今天看啥」查看全文