技术演进的动力
1)对于产品类业务,答案看起来很明显:技术创新推动业务发展!
2)对于“服务”类的业务,答案和产品类业务正好相反:业务发展推动技术的发展!
例如,选择 UC 浏览器还是选择 QQ 浏览器,更多的人是根据个人喜好和体验来决定的;而选择微信还是 Whatsapp,就不是根据它们之间的功能差异来选择的,而是根据其规模来选择的,就像我更喜欢 Whatsapp 的简洁,但我的朋友和周边的人都用微信,那我也不得不用微信。
技术演进的模式
明确了技术发展主要的驱动力是业务发展后,我们来看看业务发展究竟是如何驱动技术发展的。
所以,对于架构师来说,判断业务当前和接下来一段时间的主要复杂度是什么就非常关键。判断不准确就会导致投入大量的人力和时间做了对业务没有作用的事情,判断准确就能够做到技术推动业务更加快速发展。那架构师具体应该按照什么标准来判断呢?
答案就是基于业务发展阶段进行判断。
互联网业务千差万别,但由于它们具有“规模决定一切”的相同点,其发展路径也基本上是一致的。互联网业务发展一般分为几个时期:初创期、发展期、竞争期、成熟期。
不同时期的差别主要体现在两个方面:复杂性、用户规模。
业务复杂性
互联网业务发展第一个主要方向就是“业务越来越复杂”,我们来看看不同时期业务的复杂性的表现。
用户规模
互联网业务的发展第二个主要方向就是“用户量越来越大”。互联网业务的发展会经历“初创期、发展期、竞争期、成熟期”几个阶段,不同阶段典型的差别就是用户量的差别,用户量随着业务的发展而越来越大。
用户量增大对技术的影响主要体现在两个方面:性能要求越来越高、可用性要求越来越高。
量变到质变
互联网的标准技术架构如下图所示,这张图基本上涵盖了互联网技术公司的大部分技术点,不同的公司只是在具体的技术实现上稍有差异,但不会跳出这个框架的范畴。
SQL
所以互联网行业也必须依赖关系数据,考虑到 Oracle 太贵,还需要专人维护,一般情况下互联网行业都是用 MySQL、PostgreSQL 这类开源数据库。这类数据库的特点是开源免费,拿来就用;但缺点是性能相比商业数据库要差一些。随着互联网业务的发展,性能要求越来越高,必然要面对一个问题:将数据拆分到多个数据库实例才能满足业务的性能需求(其实 Oracle 也一样,只是时间早晚的问题)。
数据库拆分满足了性能的要求,但带来了复杂度的问题:数据如何拆分、数据如何组合?这个复杂度的问题解决起来并不容易,如果每个业务都去实现一遍,重复造轮子将导致投入浪费、效率降低,业务开发想快都快不起来。
所以互联网公司流行的做法是业务发展到一定阶段后,就会将这部分功能独立成中间件,例如百度的 DBProxy、淘宝的 TDDL。不过这部分的技术要求很高,将分库分表做到自动化和平台化,不是一件容易的事情,所以一般是规模很大的公司才会自己做。中小公司建议使用开源方案,例如 MySQL 官方推荐的 MySQL Router、360 开源的数据库中间件 Atlas。
假如公司业务继续发展,规模继续扩大,SQL 服务器越来越多,如果每个业务都基于统一的数据库中间件独立部署自己的 SQL 集群,就会导致新的复杂度问题,具体表现在:
因此,实力雄厚的大公司此时一般都会在 SQL 集群上构建 SQL 存储平台,以对业务透明的形式提供资源分配、数据备份、迁移、容灾、读写分离、分库分表等一系列服务,例如淘宝的 UMP(Unified MySQL Platform)系统。
NoSQL
首先 NoSQL 在数据结构上与传统的 SQL 的不同,例如典型的 Memcache 的 key-value 结构、Redis 的复杂数据结构、MongoDB 的文档数据结构;其次,NoSQL 无一例外地都会将性能作为自己的一大卖点。NoSQL 的这两个特点很好地弥补了关系数据库的不足,因此在互联网行业 NoSQL 的应用基本上是基础要求。
由于 NoSQL 方案一般自己本身就提供集群的功能,例如 Memcache 的一致性 Hash 集群、Redis 3.0 的集群,因此 NoSQL 在刚开始应用时很方便,不像 SQL 分库分表那么复杂。一般公司也不会在开始时就考虑将 NoSQL 包装成存储平台,但如果公司发展很快,例如 Memcache 的节点有上千甚至几千时,NoSQL 存储平台就很有意义了。首先是存储平台通过集中管理能够大大提升运维效率;其次是存储平台可以大大提升资源利用效率,2000 台机器,如果利用率能提升 10%,就可以减少 200 台机器,一年几十万元就节省出来了。
所以,NoSQL 发展到一定规模后,通常都会在 NoSQL 集群的基础之上再实现统一存储平台,统一存储平台主要实现这几个功能:
当然要发展到这个阶段,一般也是大公司才会这么做,简单来说就是如果只有几十台 NoSQL 服务器,做存储平台收益不大;但如果有几千台 NoSQL 服务器,NoSQL 存储平台就能够产生很大的收益。
小文件存储
除了关系型的业务数据,互联网行业还有很多用于展示的数据。例如,淘宝的商品图片、商品描述;Facebook 的用户图片;新浪微博的一条微博内容等。这些数据具有三个典型特征:一是数据小,一般在 1MB 以下;二是数量巨大,Facebook 在 2013 年每天上传的照片就达到了 3.5 亿张;三是访问量巨大,Facebook 每天的访问量超过 10 亿。
和 SQL 和 NoSQL 不同的是,小文件存储不一定需要公司或者业务规模很大,基本上认为业务在起步阶段就可以考虑做小文件统一存储。得益于开源运动的发展和最近几年大数据的火爆,在开源方案的基础上封装一个小文件存储平台并不是太难的事情。例如,HBase、Hadoop、Hypertable、FastDFS 等都可以作为小文件存储的底层平台,只需要将这些开源方案再包装一下基本上就可以用了。
典型的小文件存储有:淘宝的 TFS、京东 JFS、Facebook 的 Haystack。
大文件存储
互联网行业的大文件主要分为两类:一类是业务上的大数据,例如 Youtube 的视频、电影网站的电影;另一类是海量的日志数据,例如各种访问日志、操作日志、用户轨迹日志等。和小文件的特点正好相反,大文件的数量没有小文件那么多,但每个文件都很大,几百 MB、几个 GB 都是常见的,几十 GB、几 TB 也是有可能的,因此在存储上和小文件有较大差别,不能直接将小文件存储系统拿来存储大文件。
说到大文件,特别要提到 Google 和 Yahoo,Google 的 3 篇大数据论文(Bigtable/Map- Reduce/GFS)开启了一个大数据的时代,而 Yahoo 开源的 Hadoop 系列(HDFS、HBase 等),基本上垄断了开源界的大数据处理。
对照 Google 的论文构建一套完整的大数据处理方案的难度和成本实在太高,而且开源方案现在也很成熟了,所以大数据存储和处理这块反而是最简单的,因为你没有太多选择,只能用这几个流行的开源方案,例如,Hadoop、HBase、Storm、Hive 等。实力雄厚一些的大公司会基于这些开源方案,结合自己的业务特点,封装成大数据平台,例如淘宝的云梯系统、腾讯的 TDW 系统。
下面是 Hadoop 的生态圈:
开发层技术
互联网公司都会指定一个大的技术方向,然后使用统一的开发框架。例如,Java 相关的开发框架 SSH、SpringMVC、Play,Ruby 的 Ruby on Rails,PHP 的 ThinkPHP,Python 的 Django 等。使用统一的开发框架能够解决上面提到的各种问题,大大提升组织和团队的开发效率。
对于框架的选择,有一个总的原则:优选成熟的框架,避免盲目追逐新技术!
选择一个服务器主要和开发语言相关,例如,Java 的有 Tomcat、JBoss、Resin 等,PHP/Python 的用 Nginx,当然最保险的就是用 Apache 了,什么语言都支持。
其中以 Docker 为代表
传统的虚拟化技术是虚拟机,解决了跨平台的问题,但由于虚拟机太庞大,启动又慢,运行时太占资源,在互联网行业并没有大规模应用;而 Docker 的容器技术,虽然没有跨平台,但启动快,几乎不占资源,推出后立刻就火起来了,预计 Docker 类的容器技术将是技术发展的主流方向。
千万不要以为 Docker 只是一个虚拟化或者容器技术,它将在很大程度上改变目前的技术形势:
服务层技术
服务层的主要目标其实就是为了降低系统间相互关联的复杂度。
故名思议,配置中心就是集中管理各个系统的配置。
下面是配置中心简单的设计,其中通过“系统标识 + host + port”来标识唯一一个系统运行实例是常见的设计方法。
服务中心就是为了解决上面提到的跨系统依赖的“配置”和“调度”问题。
服务中心的实现一般来说有两种方式:服务名字系统和服务总线系统。
类似 DNS
类似计算机的总线
“服务名字系统”和“服务总线系统”简单对比如下表所示。
消息队列就是为了实现这种跨系统异步通知的中间件系统。消息队列既可以“一对一”通知,也可以“一对多”广播。以微博为例,可以清晰地看到异步通知的实现和作用,如下图所示。
消息队列系统基本功能的实现比较简单,但要做到高性能、高可用、消息时序性、消息事务性则比较难。业界已经有很多成熟的开源实现方案,如果要求不高,基本上拿来用即可,例如,RocketMQ、Kafka、ActiveMQ 等。但如果业务对消息的可靠性、时序、事务性要求较高时,则要深入研究这些开源方案,否则很容易踩坑。
负载均衡
顾名思议,负载均衡就是将请求均衡地分配到多个系统上。使用负载均衡的原因也很简单:每个系统的处理能力是有限的,为了应对大容量的访问,必须使用多个系统。例如,一台 32 核 64GB 内存的机器,性能测试数据显示每秒处理 Hello World 的 HTTP 请求不超过 2 万,实际业务机器处理 HTTP 请求每秒可能才几百 QPS,而互联网业务并发超过 1 万是比较常见的,遇到双十一、过年发红包这些极端场景,每秒可以达到几十万的请求。
DNS 是最简单也是最常见的负载均衡方式,一般用来实现地理级别的均衡。例如,北方的用户访问北京的机房,南方的用户访问广州的机房。一般不会使用 DNS 来做机器级别的负载均衡,因为太耗费 IP 资源了。例如,百度搜索可能要 10000 台以上机器,不可能将这么多机器全部配置公网 IP,然后用 DNS 来做负载均衡。有兴趣的读者可以在 Linux 用“dig baidu.com”命令看看实际上用了几个 IP 地址。
所以对于时延和故障敏感的业务,有实力的公司可能会尝试实现HTTP-DNS的功能,即使用 HTTP 协议实现一个私有的 DNS 系统。HTTP-DNS 主要应用在通过 App 提供服务的业务上,因为在 App 端可以实现灵活的服务器访问策略,如果是 Web 业务,实现起来就比较麻烦一些,因为 URL 的解析是由浏览器来完成的,只有 Javascript 的访问可以像 App 那样实现比较灵活的控制。
DNS 用于实现地理级别的负载均衡,而 Nginx、LVS、F5 用于同一地点内机器级别的负载均衡。其中 Nginx 是软件的 7 层负载均衡,LVS 是内核的 4 层负载均衡,F5 是硬件的 4 层负载均衡。
软件和硬件的区别就在于性能,硬件远远高于软件,
Ngxin 的性能是万级,一般的 Linux 服务器上装个 Nginx 大概能到 5 万 / 秒;
LVS 的性能是十万级,没有具体测试过,据说可达到 80 万 / 秒;
F5 性能是百万级,从 200 万 / 秒到 800 万 / 秒都有。硬件虽然性能高,但是单台硬件的成本也很高,一台最便宜的 F5 都是几十万,但是如果按照同等请求量级来计算成本的话,实际上硬件负载均衡设备可能会更便宜,例如假设每秒处理 100 万请求,用一台 F5 就够了,但用 Nginx,可能要 20 台,这样折算下来用 F5 的成本反而低。
因此通常情况下,如果性能要求不高,可以用软件负载均衡;如果性能要求很高,推荐用硬件负载均衡。
4 层和 7 层的区别就在于协议和灵活性。Nginx 支持 HTTP、E-mail 协议,而 LVS 和 F5 是 4 层负载均衡,和协议无关,几乎所有应用都可以做,例如聊天、数据库等。
目前很多云服务商都已经提供了负载均衡的产品,例如阿里云的 SLB、UCloud 的 ULB 等,中小公司直接购买即可。
CDN
CDN 是为了解决用户网络访问时的“最后一公里”效应,本质上是一种“以空间换时间”的加速策略,即将内容缓存在离用户最近的地方,用户访问的是缓存的内容,而不是站点实时的内容。
下面是简单的 CDN 请求流程示意图:
CDN 经过多年的发展,已经变成了一个很庞大的体系:分布式存储、全局负载均衡、网络重定向、流量控制等都属于 CDN 的范畴,尤其是在视频、直播等领域,如果没有 CDN,用户是不可能实现流畅观看内容的。
幸运的是,大部分程序员和架构师都不太需要深入理解 CDN 的细节,因为 CDN 作为网络的基础服务,独立搭建的成本巨大,很少有公司自己设计和搭建 CDN 系统,从 CDN 服务商购买 CDN 服务即可,目前有专门的 CDN 服务商,例如网宿和蓝汛;也有云计算厂家提供 CDN 服务,例如阿里云和腾讯云都提供 CDN 的服务。
多机房
从架构上来说,单机房就是一个全局的网络单点,在发生比较大的故障或者灾害时,单机房难以保证业务的高可用。例如,停电、机房网络中断、地震、水灾等都有可能导致一个机房完全瘫痪。
多机房设计最核心的因素就是如何处理时延带来的影响,常见的策略有:
多中心
多中心必须以多机房为前提,但从设计的角度来看,多中心相比多机房是本质上的飞越,难度也高出一个等级。
简单来说,多机房的主要目标是灾备,当机房故障时,可以比较快速地将业务切换到另外一个机房,这种切换操作允许一定时间的中断(例如,10 分钟、1 个小时),而且业务也可能有损失(例如,某些未同步的数据不能马上恢复,或者要等几天才恢复,甚至永远都不能恢复了)。因此相比多机房来说,多中心的要求就高多了,要求每个中心都同时对外提供服务,且业务能够自动在多中心之间切换,故障后不需人工干预或者很少的人工干预就能自动恢复。
多中心设计的关键就在于“数据一致性”和“数据事务性”如何保证,这两个难点都和业务紧密相关,目前没有很成熟的且通用的解决方案,需要基于业务的特性进行详细的分析和设计。
用户层技术
稍微大一点的互联网业务,肯定会涉及多个子系统,这些子系统不可能每个都管理这么庞大的用户,由此引申出用户管理的第一个目标:***单点登录(SSO)***,又叫统一登录。单点登录的技术实现手段较多,例如 cookie、JSONP、token 等,目前最成熟的开源单点登录方案当属 CAS,其架构如下(https://apereo.github.io/cas/4.2.x/planning/Architecture.html )
除此之外,当业务做大成为了平台后,开放成为了促进业务进一步发展的手段,需要允许第三方应用接入,由此引申出用户管理的第二个目标:授权登录。现在最流行的授权登录就是 OAuth 2.0 协议,基本上已经成为了事实上的标准,如果要做开放平台,则最好用这个协议,私有协议漏洞多,第三方接入也麻烦。
用户管理的基本架构如下:
消息推送根据不同的途径,分为短信、邮件、站内信、App 推送。除了 App,不同的途径基本上调用不同的 API 即可完成,技术上没有什么难度。例如,短信需要依赖运营商的短信接口,邮件需要依赖邮件服务商的邮件接口,站内信是系统提供的消息通知功能。
App 目前主要分为 iOS 和 Android 推送,iOS 系统比较规范和封闭,基本上只能使用苹果的 APNS;但 Android 就不一样了,在国外,用 GCM 和 APNS 差别不大;但是在国内,情况就复杂多了:首先是 GCM 不能用;其次是各个手机厂商都有自己的定制的 Android,消息推送实现也不完全一样。因此 Android 的消息推送就五花八门了,大部分有实力的大厂,都会自己实现一套消息推送机制,例如阿里云移动推送、腾讯信鸽推送、百度云推送;也有第三方公司提供商业推送服务,例如友盟推送、极光推送等。
存储云和图片云通常的实现都是“CDN + 小文件存储”
业务层技术
业务层面对的主要技术挑战是“复杂度”。
复杂度越来越高的一个主要原因就是系统越来越庞大,业务越来越多。幸运的是,面对业务层的技术挑战,我们有一把“屠龙宝刀”,不管什么业务难题,用上“屠龙宝刀”问题都能迎刃而解。这把“屠龙宝刀”就是“拆”,化整为零、分而治之,将整体复杂性分散到多个子业务或者子系统里面去。具体拆的方式你可以查看专栏前面可扩展架构模式部分的分层架构、微服务、微内核等。
我以一个简单的电商系统为例,如下图所示。
随着子系统数量越来越多,如果达到几百上千,另外一个复杂度问题又会凸显出来:子系统数量太多,已经没有人能够说清楚业务的调用流程了,出了问题排查也会特别复杂。此时应该怎么处理呢,总不可能又将子系统合成大系统吧?最终答案还是“合”,正所谓“合久必分、分久必合”,但合的方式不一样,此时采取的“合”的方式是按照“高内聚、低耦合”的原则,将职责关联比较强的子系统合成一个***虚拟业务域***,然后通过网关对外统一呈现,类似于设计模式中的 Facade 模式。同样以电商为样例,采用虚拟业务域后,其架构如下:
虚拟业务域划分的粒度需要粗一些还是要细一些?你建议虚拟业务域的数量大概是多少,理由是什么?
粗一些比较好,5±2原则比较合适
运维平台
运维平台核心的职责分为四大块:配置、部署、监控、应急,每个职责对应系统生命周期的一个阶段,如下图所示。
运维平台的核心设计要素是“四化”:标准化、平台化、自动化、可视化。
测试平台
测试平台核心的职责当然就是测试了,包括单元测试、集成测试、接口测试、性能测试等,都可以在测试平台来完成。
测试平台的核心目的是提升测试效率,从而提升产品质量,其设计关键就是自动化。传统的测试方式是测试人员手工执行测试用例,测试效率低,重复的工作多。通过测试平台提供的自动化能力,测试用例能够重复执行,无须人工参与,大大提升了测试效率。
为了达到“自动化”的目标,测试平台的基本架构如下图所示。
数据平台
数据平台的核心职责主要包括三部分:数据管理、数据分析和数据应用。每一部分又包含更多的细分领域,详细的数据平台架构如下图所示。
管理平台
管理平台的核心职责就是权限管理,无论是业务系统(例如,淘宝网)、中间件系统(例如,消息队列 Kafka),还是平台系统(例如,运维平台),都需要进行管理。如果每个系统都自己来实现权限管理,效率太低,重复工作很多,因此需要统一的管理平台来管理所有的系统的权限。
权限管理主要分为两部分:身份认证、权限控制,其基本架构如下图所示。
期望通过架构重构来解决所有问题当然是不现实的,所以架构师的首要任务是从一大堆纷繁复杂的问题中识别出真正要通过架构重构来解决的问题,集中力量快速解决,而不是想着通过架构重构来解决所有的问题。
M 系统是一个后台管理系统,负责管理所有游戏相关的数据,重构的主要原因是因为系统耦合了 P 业务独有的数据和所有业务公用的数据,导致可扩展性比较差。其大概架构如下图所示。
针对 M 系统存在的问题,重构目标就是将游戏数据和业务数据拆分,解开两者的耦合,使得两个系统都能够独立快速发展。重构的方案如下图所示。
S 系统是游戏接入的核心系统,一旦 S 系统故障,大量游戏玩家就不能登录游戏。而 S 系统并不具备多中心的能力,一旦主机房宕机,整个 S 系统业务就不可用了。其大概架构如下图所示,可以看出数据库主库是全局单点,一旦数据库主库不可用,两个集群的写业务都不可用了。
针对 S 系统存在的问题,重构目标就是实现双中心,使得任意一个机房都能够提供完整的服务,在某个机房故障时,另外一个机房能够全部接管所有业务。重构方案如下图所示。
3.X 系统:解决大系统带来的开发效率问题
X 系统是创新业务的主系统,之前在业务快速尝试和快速发展期间,怎么方便怎么操作,怎么快速怎么做,系统设计并未投入太多精力和时间,很多东西都“塞”到同一个系统中,导致到了现在已经改不动了。做一个新功能或者新业务,需要花费大量的时间来讨论和梳理各种业务逻辑,一不小心就踩个大坑。X 系统的架构如下图所示。
针对 X 系统存在的问题,重构目标是将各个功能拆分到不同的子系统中,降低单个系统的复杂度。重构后的架构如下图所示(仅仅是示例,实际架构远比下图复杂)。
小结
架构重构内功心法的第一式:有的放矢,需要架构师透过问题表象看到问题本质,找出真正需要通过架构重构解决的核心问题,而不是想着通过一次重构解决所有问题。
合纵
架构重构是大动作,持续时间比较长,而且会占用一定的研发资源,包括开发和测试,因此不可避免地会影响业务功能的开发。因此,要想真正推动一个架构重构项目启动,需要花费大量的精力进行游说和沟通。
所以在沟通协调时,将技术语言转换为通俗语言,以事实说话,以数据说话,是沟通的关键!
连横
那如何才能有效地推动呢?有效的策略是“换位思考、合作双赢、关注长期”。简单来说就是站在对方的角度思考,重构对他有什么好处,能够帮他解决什么问题,带来什么收益。
架构师在识别系统关键的复杂度问题后,还需要识别为了解决这个问题,需要做哪些准备事项,或者还要先解决哪些问题。这就需要我今天要和你分享的架构重构内功心法第三式:运筹帷幄。
基于这些分析,我们制定了总体的策略,如下图所示。
总结一下重构的做法,其实就是“分段实施”,将要解决的问题根据优先级、重要性、实施难度等划分为不同的阶段,每个阶段聚焦于一个整体的目标,集中精力和资源解决一类问题。
具体如何制定“分段实施”的策略呢?分享一下我的经验。
软件开发领域有一个流行的原则:DRY,Don’t repeat yourself。翻译过来更通俗易懂:不要重复造轮子。开源项目的主要目的是共享,其实就是为了让大家不要重复造轮子,尤其是在互联网这样一个快速发展的领域,速度就是生命,引入开源项目可以节省大量的人力和时间,大大加快业务的发展速度,何乐而不为呢?
选:如何选择一个开源项目
用:如何使用开源项目
改:如何基于开源项目做二次开发
首先,先来复习一下我的专栏所讲述的架构设计理念,可以提炼为下面几个关键点:
Web App
最早的 App 有很多采用这种架构,大多数尝试性的业务,一开始也是这样的架构。Web App 架构又叫包壳架构,简单来说就是在 Web 的业务上包装一个 App 的壳,业务逻辑完全还是 Web 实现,App 壳完成安装的功能,让用户看起来像是在使用 App,实际上和用浏览器访问 PC 网站没有太大差别。
原生 App
因此,随着业务发展和技术演进,移动开发的复杂度从“快速开发”和“低成本”转向了“用户体验”,而要保证用户体验,采用原生 App 的架构是最合适的,这里的架构设计遵循“演化原则”。
Hybrid App
为了解决“快速开发”的复杂度问题,大家自然又想到了 Web 的方式,但 Web 的体验还是远远不如原生,怎么解决这个问题呢?其实没有办法完美解决,但可以根据不同的业务要求选取不同的方案,例如对体验要求高的业务采用原生 App 实现,对体验要求不高的可以采用 Web 的方式实现,这就是 Hybrid App 架构的核心设计思想,主要遵循架构设计的“合适原则”。
组件化 & 容器化
在这种业务背景下,组件化和容器化架构应运而生,其基本思想都是将超级 App 拆分为众多组件,这些组件遵循预先制定好的规范,独立开发、独立测试、独立上线。如果某个组件依赖其他组件,组件之间通过消息系统进行通信,通过这种方式来实现组件隔离,从而避免各个团队之间的互相依赖和影响,以提升团队开发效率和整个系统的可扩展性。组件化和容器化的架构出现遵循架构设计的“演化原则”,只有当业务复杂度发展到一定规模后才适应,因此我们会看到大厂应用这个架构的比较多,而中小公司的 App,业务没那么复杂,其实并不一定需要采用组件化和容器化架构。
对于组件化和容器化并没有非常严格的定义,我理解两者在规范、拆分、团队协作方面都是一样的,区别在于发布方式,组件化采用的是静态发布,即所有的组件各自独自开发测试,然后跟随 App 的某个版本统一上线;容器化采用的是动态发布,即容器可以动态加载组件,组件准备好了直接发布,容器会动态更新组件,无需等待某个版本才能上线。
关于手机淘宝 App 更详细的架构演进可以参考《Atlas:手淘 Native 容器化框架和思考》,微信 App 的架构演进可以参考《微信 Android 客户端架构演进之路》
跨平台 App
Facebook 的 React Native、阿里的 Weex、Google 的 Flutter。
前端的情况也是类似的,有兴趣的同学可以看看玉伯的文章《Web 研发模式演变》,专栏里我就不在赘述了。