全球直播的罗胖跨年演讲背后技术支撑故事——首席架构师方圆访谈
导读:最近几年,知识付费型产品纷纷登上舞台,大家可能了解过最近的罗辑思维的跨年活动,或者也用过得到 app 来进行新知识学习。对于得到这样的产品,背后的技术挑战及经验外界了解不太多,恰逢罗辑思维首席架构师方圆作为中间件论坛的出品人参加 2017 年 12 月的 GIAC 大会,高可用架构对其进行了采访。
方圆,罗辑思维首席架构师,曾先后在 Cisco,新浪微博从事基础架构研发工作。十多年一直专注于后端技术的研发,在消息通信,分布式存储等方向有着丰富的经验。个人技术兴趣广泛,主要专注 Go/Java/Python 等编程语言的发展,尤其是在云计算等前沿领域的应用。
身边很多朋友都在使用得到 app,但是对于背后的技术团队大家可能还了解不多,能简单介绍一下你们技术团队吗?作为得到的首席架构师,您的日常主要职责是什么?
方圆:得到的技术团队主要包括前端(Web,iOS,Android),得到后端,商城团队,基础服务团队,大数据团队和运维团队。我的工作主要是带领得到后端团队负责得到 app 后端研发。其中包括业务系统功能日常研发,还有内部使用的服务框架和工具的研发。
您在 2017 年 12 月的 GIAC 大会担当了中间件专题的出品人,能否给广大读者介绍一下什么是中间件?对于一个架构师,如何看待中间件的价值?方圆:中间件是非业务的技术组件。个人以为广义上来说,除操作系统之外,其他都是中间件。当然一般意义上来说,中间件主要是消息中间件,框架,配置服务,缓存等等。
中间件对于应用系统来说最重要的价值是,减少应用系统控制逻辑的复杂性从而让工程师尽量多的关注应用的业务逻辑,举例来说比如服务框架可以降低我们拆分服务的复杂度,类似 DRDS 这样的框架可以让程序员尽量少的关心分库分表,通过消息中间件可以对一些应用系统解耦。
而对于工程师来说,学习中间件可以迅速提高自己的抽象能力和代码能力,最好是能够在熟悉之后,尝试自己实现一个小的 demo 从而加深理解。大部分团队在项目中采用开源的中间件,也有一些团队比较青睐自研,对于引入和自研中间件有什么建议?方圆:在业务初期试错阶段,建议采用成熟的开源的中间件,这样避免踩坑,也能够加快开发进度,但在中间件的选型上要根据自己团队的熟悉程度来确定,不能盲目跟风,降低团队整体的学习成本。
而业务发展稳定阶段,可以根据自己的业务特性来自研,同时也要考虑公司的资源投入情况,以及兼容主流的数据格式或者通讯协议。自研的周期一般较长,需要拆解成阶段性目标,这样利于落地,同时也要兼顾旧系统,充分考虑将来上线数据迁移,业务平滑过渡。
阿里在 2017 年重新成立了 Dubbo 开发团队,本次 GIAC 中间件专题也有相关的分享,从大会现场的了解的情况来看,Dubbo 有哪些新的变化?方圆:参会人员对于 Dubbo 的关注点主要在以下两点:第一,阿里对于 Dubbo 的支持到底如何?第二,第三方团队如何给 Dubbo 贡献代码?
阿里这次重拾 Dubbo,官方很有信心让 Dubbo 成为 Apache 项目,前段时间也看到 Dubbo 3.0 的消息,新的 Dubbo 内核与 Dubbo 2.0 完全不同,但它兼容 2.0。Dubbo 3.0 将以 Streaming 为内核,而不再是 2.0 时代的 RPC,但是 RPC 会在 3.0 中变成远程 Streaming 对接的一种可选形态。具体的变化还需要等 Dubbo 新版本 release。Kafka 最近几年在大数据领域得到了广泛应用,能介绍下 Kafka 领域发展的一些动态吗?相比于前几年,Kafka 的使用场景和关注点是否发生了一些变化?方圆:近几年 Kafka 关键版本升级:
0.8 支持副本模式,增强容灾能力
0.9 增加了 groupcoordinator,彻底解决 partition 和 consume 的动态调
0.10 支持流处理功能,同时将 consume 的 offset 移到默认 topic 里
1.0.0 stream 能力增强
2017 年 8 月 5 日 Kafka 发布 0.11 版本支持 exactly-once,增强了事务处理能力
2017 年 8 月 LinkedIn 开源 Kafka Cruise Control,提供自动化运维功能
2017 年 8 月 28 日 Confluent 宣布开源 KSQL,用于 Kafka 的流数据 SQL 引擎
2017 年 11 月 3 日 Kafka 宣布 1.0.0 发布
Kafka 使用场景最大的变化:最早大家主要用 Kafka 做些日志处理系统,后来主要应用在消息队列系统,近两年随着 Kafka stream 方面处理能力增强,逐渐转变成轻量级的流处理平台。
另外 LinkedIn 团队最近也在 Kafka 自动化运维方面作出了很多工作,本次大会来自 LinkedIn 团队的秦江杰介绍了他们实现的自动化运维工具 Cruise Control,之前也看到高可用架构有文章介绍该工具。去哪儿的余昭辉老师在 GIAC 大会上分享了消息队列(MQ)的主题,能给大家简短介绍下他的分享主题?对于使用 MQ 的场景有哪些启发?方圆:去哪儿的 MQ 分享的内容对落地分布式事务来说很有帮助。讲师的分享主要分两个部分,一个是分布式事务的简单模型,另一个是因为需要支持分布式事务,去哪儿自研中间件都做了哪些优化,并且还跟流行的消息中间件做了对比(比如 Kafka 和 rocketmq)。对于我们公司来说,正好也要落地分布式事务,跟讲师交流了不少细节,避免我们踩坑。让我们把话题再转回到你们团队,得到最近的跨年演讲受到了广泛关注,为了应对这次跨年,你们做了哪些准备?方圆:我们从 2017 年 10 月份正式开始准备,实际上最早的准备工作从 9 月就开始。工作主要集中在以下几个方面:
业务架构梳理我们梳理出了很多潜在的问题,比如早期的系统里有很多双向调用,也有很多随意使用资源,还有很多引起读放大或者写放大的代码,还有很多不合理的调用关系栈,对业务系统有个比较清晰的架构。同时也在调用链路上发现一些问题。
服务/资源拆分早期主要业务系统是一个整体式架构,核心业务调用链上只使用了一个数据库,缓存使用也是集中在几个主要的缓存集群中,因此我们做了很多资源和服务拆分,分散压力
重要服务代码重构相应的主要业务模块拆分成单独服务,做好对资源的抽象,为了应对较大的压力,我们实现了一个简单的多级缓存框架,所有代码重构项目都使用了这个多级缓存框架,保证业务系统的处理能力
压力测试压力测试分两部分,一部分是功能上线前由开发工程师进行相应的压力测试,如果有问题通过 Go 语言相应工具进行分析,提高到一定标准后才能上线发布。另一部分是由阿里云 PTS 团队提供的全链路压力测试,我们在 3 个月时间内进行了 18 轮全链路压力测试,覆盖到得到主要接口(接近 200 个接口,覆盖率接近 50%)。通过单个服务的压力测试,我们解决了单个服务的性能问题,通过全链路压力测试,我们解决了调用链路引起的问题。经过 18 轮压力测试后,系统负载能力提升 25 倍以上,为跨年作好准备。
API 网关即使我们做了前面所述的业务拆分,服务拆分和重构,我们也不能保证系统 100% 不出问题,特别是那些没重构的系统。毕竟系统的负载能力取决于最短板。我们解决这个问题的方法是引入 API 网关。我们在 9 月份的时候,引入 API 网关,跨年前对一些可能出问题的接口做了对应的限流策略。
提问:据了解得到在跨年前夕做了重要的重构,简单介绍下这次重构的背景及成效吗?方圆:重构背景其实也比较简单,去年 8 月 31 日,得到第二次产品发布会在深圳卫视和多个视频网站播出,带来的流量是平时早晚高峰的 4 倍左右,导致一次大故障。因此从 9 月份开始,我们集中一部分开发力量重构了 10 多个重要的业务模块。在重构的过程中,主要考虑以下几点来优化性能问题:
严格控制资源(数据库,缓存)使用早期服务对资源使用很随意,有很多引起读/写放大的代码,因此新系统严格控制对资源的使用
保证非核心业务数据可以自动降级对非核心业务进行自动调用降级,但是因为我们使用 Go 语言的原因,尚未做熔断机制,这也是我们 18 年确定的落地目标之一。
保证核心链路稳定对于跨年的核心链路来说,比如收听,购买,拉新,兑换,我们保证核心链路不被非核心链路影响。
对写入进行削峰处理和异步化对于购买流程来说,我们部分做了异步化,对于非购买相关的业务流程,我们通过 MQ 进行了削峰和处理。效果还是很明显,削峰和合并写入之后,相关数据库 IOPS 降低一个数量级。
提问:得到在跨年活动期间,应对情况怎样?有没有一些意料之外的问题,当时怎么应对的?方圆:跨年活动期间,状况基本在意料之中,核心系统最高峰时期的流量也只是我们准备的 1/8 上下,因此核心系统压力不大。夸张一点讲,核心系统可以应付 8 个罗胖一起跨年而没有太大压力。但是一些遗留系统依然有很大压力。比如我们有一个遗留系统,在流量高峰时期数据库压力很大,当时我们通过监控系统发现该系统有很大压力,迅速通过网关对该系统的 API 进行限流,保证该系统不会宕机。提问:通过这次跨年活动,团队想必有很多收获,能介绍一下这次应对的一些经验?
方圆:个人总结下来,以下三点是比较重要的:
全链路压力测试得到后端的服务化刚开始做,还没有 tracing 系统。虽然我们可以保证单个系统的处理能力,但是当多个系统组合起来的时候,系统的整体表现就难以把握了。阿里 PTS 帮助我们发现了很多调用链路上的问题,每次压测都能发现一些新问题,压测后迅速解决,因此可以看到我们每次压测的系统负载能力都有很大提高。
API 网关如上所述,使用 API 网关对 API 进行限流,保证即使有问题的情况下,保护后端系统,以让部分用户可以正常访问。
核心业务链路重构对于有坑的老系统来说,一定不能手软。进行代码重构可以一方面提升系统处理能力,另一方面也保证后续功能开发可以轻装上阵。
作为一个首席架构师,请问您每天还写代码吗?如果有的话,您的代码主要是在哪个领域,对团队有哪些贡献?您觉得首席架构师对团队的价值主要提现在哪些方面?方圆:我不是每天都会写代码,但是还是坚持定期有代码产出。我的代码主要集中在一些公有库/框架/工具上,因为这些代码对于整个团队的开发效率和代码质量很关键。
举个例子来说,我们有个服务上线前进行了压测,发现单台机器最主要的接口 QPS 只有 300 多,通过火焰图发现问题之后,对公有库进行了少量代码改造,一天之后再次进行压测单台机器 QPS 就可以到 12000 左右,并且由于是在公有代码库方面的改动,其他使用该库的业务模块也都获得了数倍性能提升。我个人认为首席架构师应该有以下几方面的工作:
公司架构团队的管理工作;
技术方向的确定,架构分析,设计和部分实现;
公司技术平台和业务线之间的相互促进;
业务架构和实现的把控。
很多团队的架构师并不带人,因此不能直接要求工程师按照自己的想法去执行,这种情况下,架构师如何更好提现自己价值?而避免仅仅成为 CTO 或者技术总监下面一个执行者?方圆:我个人认为如果架构师不能带人的情况下,是很难影响工程师的执行方案的。工程师在执行的时候,可能会有各种因素影响他选择执行方案,架构师只是其中之一。另外大家在不同的位置,不同的时候,不同的背景,对一个技术问题的看法,对一个技术方案的选型,都可能有不同的看法,本身也是很正常的事情,架构师具体要靠什么方式来落地也很难有固定的模式。
举例来说,我刚到公司的时候就在强调读写放大的问题,但是没有人当回事,各种原因都有,大部分人都觉得功能开发太紧了,顾不上,直到我负责得到后端的具体工作,才能强制大家落地解决。最终大家发现其实不会增加多少工作,就可以让系统处理能力提升一个数量级,在后续的工作中,不需要再进行强调,大家也会这么做。
我个人认为架构师和 CTO 及技术总监的角色还是不同的,CTO 以及技术总监管理的身份更重一些,而架构师更多是一个技术身份。对于 CTO 以及技术总监,他们需要放手让架构师去做设计和实现,对于架构师,除了做好架构工作之外,也需要辅助 CTO 技术总监,做一些管理工作。
小编:感谢方圆的访谈,大家对于得到架构以及中间件技术方面任何问题,欢迎加群 561614305 同时也免费给大家提供一些视频
大家对于得到架构以及中间件技术方面任何问题,欢迎通过留言与方圆进一步讨论