14 互联网架构模板

互联网的标准技术架构如下图所示:

image

0.1. 存储层技术

0.1.1. SQL

SQL 即通常所说的关系数据,关系数据不可能完全被抛弃,NoSQL是Not Only SQL,即 NoSQL 是 SQL 的补充。

一般情况下互联网行业都是用 MySQL、PostgreSQL ,这类开源数据库的特点是开源免费;缺点是性能比商业数据库要差一些。随着业务发展,性能要求越来越高,必然要将数据拆分到多个数据库实例才能满足业务的性能需求。

数据库拆分满足了性能的要求,但带来了复杂度的问题:数据如何拆分、数据如何组合?这个复杂度的问题解决起来并不容易,所以流行的做法是将这部分功能独立成中间件,将分库分表做到自动化和平台化,如MySQL官方推荐的MySQL Router。

业务继续发展,规模继续扩大,SQL 服务器越来越多,导致新的复杂度问题:数据库资源使用率不高,各 SQL 集群分开维护成本越来越高。因此,一般都会在 SQL 集群上构建 SQL 存储平台,以对业务透明的形式提供资源分配、数据备份、迁移、容灾、读写分离、分库分表等一系列服务。

0.1.2. NoSQL

  • NoSQL 在数据结构上与传统的 SQL 的不同,例如:
    • Memcache 的 key-value 结构
    • Redis 的复杂数据结构
    • MongoDB 的文档数据结构
  • NoSQL 将性能作为自己的一大卖点。

NoSQL 的这两个特点很好地弥补了关系数据库的不足,因此在互联网行业 NoSQL 的应用基本上是基础要求。

NoSQL 方案一般自身就提供集群的功能,因此在刚开始应用时很方便。

一般不会在开始时就考虑将 NoSQL 包装成存储平台,但如果公司发展很快,例如 Memcache 的节点有上千甚至几千时,NoSQL 存储平台就很有意义了。

  1. 存储平台通过集中管理能够大大提升运维效率
  2. 存储平台可以大大提升资源利用效率

NoSQL 发展到一定规模后,在集群的基础之上再实现统一存储平台,主要实现如下功能:

  • 资源动态按需动态分配
  • 资源自动化管理
  • 故障自动化处理

一般几十台 NoSQL 服务器,做存储平台收益不大;有几千台 NoSQL 服务器,NoSQL 存储平台就能够产生很大的收益。

0.1.3. 小文件存储

除了关系型的业务数据,还有很多用于展示的数据。这些数据具有三个典型特征:

  1. 数据小,一般在 1MB 以下
  2. 数量巨大
  3. 访问量巨大

基本上业务在起步阶段就可以考虑做小文件统一存储,通常将小文件存储做成统一的和业务无关的平台,避免重复造轮子。

在开源方案的基础上封装一个小文件存储平台并不是太难的事情。例如,HBase、Hadoop、Hypertable、FastDFS 等都可以作为小文件存储的底层平台,只需要将这些开源方案再包装一下基本上就可以用了。

0.1.4. 大文件存储

大文件主要分为两类:

  • 业务大数据,例如 Youtube 的视频、电影网站的电影;
  • 海量日志数据,例如各种访问日志、操作日志、用户轨迹日志等。

在存储上和小文件有较大差别,不能直接将小文件存储系统拿来存储大文件。开源方案现在很成熟了,所以大数据存储和处理相对简单,在几个流行的开源方案中选择,例如,Hadoop、HBase、Storm、Hive 等。

0.2. 开发层技术

0.2.1. 开发框架

随着业务发展,复杂度越来越高,系统拆分的越来越多,不同的系统由不同的小组开发。如果每个小组用不同的开发框架和技术,则会带来很多问题:

  • 技术人员之间没有共同的技术语言,交流合作少。
  • 每类技术都需要投入大量的人力和资源并熟练精通。
  • 不同团队之间人员无法快速流动,人力资源不能高效的利用。

对于框架的选择,有一个总的原则:优选成熟的框架,避免盲目追逐新技术

  1. 成熟的框架资料文档齐备,遇到问题很容易通过搜索来解决。
  2. 成熟的框架受众更广,招聘时更加容易招到合适的人才。
  3. 成熟的框架更加稳定,不会出现大的变动,适合长期发展。

0.2.2. Web服务器

开发框架只是负责完成业务功能的开发,真正能够运行起来给用户提供服务,还需要服务器配合。

选择一个服务器主要和开发语言相关,例如:

  • Java 的有 Tomcat、JBoss、Resin 等
  • PHP/Python 的用 Nginx
  • Apache什么语言都支持

0.2.3. 容器

  • 传统的虚拟化技术是虚拟机,解决了跨平台的问题,但由于虚拟机太庞大,启动又慢,运行时太占资源,在互联网行业并没有大规模应用;
  • Docker 的容器技术,虽然没有跨平台,但启动快,几乎不占资源,Docker 类的容器技术将是技术发展的主流方向。

Docker 不只是一个虚拟化或者容器技术,它将在很大程度上改变目前的技术形势:

  1. 运维方式会发生革命性的变化:基于 Docker 打造自动化运维、智能化运维将成为主流方式。
  2. 设计模式会发生本质上的变化:设计思路朝“微服务”的方向发展。

0.3. 服务层技术

服务层的主要目标是降低系统间相互关联的复杂度

0.3.1. 配置中心

当系统数量不多的时候,一般是各系统自己管理自己的配置,但系统数量多了以后,这样的处理方式会有问题:

  • 某个功能上线时,需要多个系统配合一起上线,分散配置时,配置检查、沟通协调需要耗费较多时间。
  • 处理线上问题时,需要多个系统配合查询相关信息,分散配置时,操作效率很低,沟通协调也需要耗费较多时间。
  • 各系统自己管理配置时,一般是通过文本编辑的方式修改的,没有自动的校验机制,容易配置错误,而且很难发现。

实现配置中心主要就是为了解决上面这些问题,将配置中心做成通用系统的好处:

  1. 集中配置多个系统,操作效率高。
  2. 所有配置都在一个集中的地方,检查方便,协作效率高。
  3. 配置中心可以实现程序化的规则检查(正则表达式),避免常见的错误。
  4. 配置中心相当于备份了系统的配置,当某些情况下需要搭建新的环境时,能够快速搭建环境和恢复业务。

0.3.2. 服务中心

当系统数量不多的时候,系统间的调用一般都是直接通过配置文件记录在各系统内部的,但当系统数量多了以后,这种方式就存在问题了。

服务中心就是为了解决跨系统依赖的“配置”和“调度”问题。服务中心的实现一般来说有两种方式:服务名字系统和服务总线系统。

0.3.2.1. 服务名字系统

  • DNS 的作用将域名解析为 IP 地址
  • 服务名字系统是为了将 Service 名称解析为“host + port + 接口名称”,真正发起请求的还是请求方

image

0.3.2.2. 服务总线系统

相比服务名字系统,服务总线系统更进一步了:由总线系统完成调用,服务请求方都不需要直接和服务提供方交互了。

image

0.3.3. 消息队列

互联网业务的一个特点是“快”,这就要求很多业务处理采用异步的方式。

  • 传统的异步通知方式是由消息生产者直接调用消息消费者提供的接口进行通知的,但当业务变得庞大,子系统数量增多时,这样做会导致系统间交互非常复杂和难以管理,因为系统间互相依赖和调用,整个系统的结构就像一张蜘蛛网。
  • 消息队列就是为了实现这种跨系统异步通知的中间件系统。消息队列既可以“一对一”通知,也可以“一对多”广播。

对比蜘蛛网架构,可以清晰地看出引入消息队列系统后的效果:

  1. 整体结构从网状结构变为线性结构,结构清晰。
  2. 消息生产和消息消费解耦,实现简单。
  3. 增加新的消息消费者,消息生产者完全不需要任何改动,扩展方便。
  4. 消息队列系统可以做高可用、高性能,避免各业务子系统各自独立做一套,减轻工作量。
  5. 业务子系统只需要聚焦业务即可,实现简单。

消息队列系统基本功能的实现比较简单,但要做到高性能、高可用、消息时序性、消息事务性则比较难。

业界已经有很多成熟的开源实现方案:

  • 如果要求不高,基本上拿来用即可,例如,RocketMQ、Kafka、ActiveMQ 等。
  • 如果业务对消息的可靠性、时序、事务性要求较高时,则要深入研究这些开源方案,否则很容易踩坑。

开源的用起来方便,但要改就很麻烦了。由于其相对比较简单,花费人力和时间重复造一个轮子,这样可以根据自己的业务特点做快速的适配开发。

0.4. 网络层技术

除了复杂度,互联网业务发展的另外两个关键特点是“高性能”和“高可用”。设计高可用和高性能系统的时候,主要关注点在系统本身的复杂度,但是,单个系统的高可用和高性能并不等于整体业务的高可用和高性能,要从更高的角度去设计,这就是“网络”,这里强调的是站在网络层的角度整体设计架构,而不是某个具体网络的搭建。

0.4.1. 负载均衡

将请求均衡地分配到多个系统上,使用负载均衡的原因:每个系统的处理能力是有限的,为了应对大容量的访问,必须使用多个系统。

例如,一台 32 核 64GB 内存的机器,性能测试数据显示每秒处理 Hello World 的 HTTP 请求不超过 2 万,实际业务机器处理 HTTP 请求每秒可能才几百 QPS,而互联网业务并发超过 1 万是比较常见的,遇到双十一、过年发红包这些极端场景,每秒可以达到几十万的请求。

0.4.1.1. DNS

DNS 是最简单也是最常见的负载均衡方式,一般用来实现地理级别的均衡。一般不会使用 DNS 来做机器级别的负载均衡,因为太耗费 IP 资源了。

DNS 负载均衡:

  • 优点:通用(全球通用)、成本低(申请域名,注册 DNS 即可)
  • 缺点:
    1. DNS 缓存的时间比较长,即使将某台业务机器从 DNS 服务器上删除,由于缓存的原因,还是有很多用户会继续访问已经被删除的机器。
    2. DNS 不够灵活。DNS 不能感知后端服务器的状态,只能根据配置策略进行负载均衡,无法做到更加灵活的负载均衡策略。

所以对于时延和故障敏感的业务,可以尝试实现 HTTP-DNS 的功能,即使用 HTTP 协议实现一个私有的 DNS 系统。

HTTP-DNS 主要应用在通过 App 提供服务的业务上,因为在 App 端可以实现灵活的服务器访问策略,如果是 Web 业务,实现起来就比较麻烦一些,因为 URL 的解析是由浏览器来完成的,只有 Javascript 的访问可以像 App 那样实现比较灵活的控制。

HTTP-DNS 的优缺点有:

  • 灵活:可以根据业务需求灵活的设置各种策略。
  • 可控:自己开发的系统,IP 更新、策略更新等无需依赖外部服务商。
  • 及时:不受传统 DNS 缓存的影响,可以非常快地更新数据、隔离故障。
  • 开发成本高:没有通用的解决方案,需要自己开发。
  • 侵入性:需要 App 基于 HTTP-DNS 进行改造。

0.4.1.2. Nginx、LVS、F5

Nginx、LVS、F5 用于同一地点内机器级别的负载均衡。

  • Nginx 是软件的 7 层负载均衡,性能是万级;一般的 Linux 服务器上装个 Nginx 大概能到 5万/秒;支持 HTTP、E-mail 协议
  • LVS 是内核的 4 层负载均衡,性能是十万级;达到 80万/秒;和协议无关
  • F5 是硬件的 4 层负载均衡,性能是百万级;从 200万/秒到 800万/秒都有;和协议无关

软件和硬件的区别就在于性能,硬件远远高于软件。

如果按照同等请求量级来计算成本的话,实际上硬件负载均衡设备可能会更便宜,例如假设每秒处理 100 万请求,用一台 F5 就够了,但用 Nginx,可能要 20 台,这样折算下来用 F5 的成本反而低。

4 层和 7 层的区别就在于协议灵活性

0.4.2. CDN

为了解决用户网络访问时的“最后一公里”效应,本质上是一种“以空间换时间”的加速策略,即将内容缓存在离用户最近的地方,用户访问的是缓存的内容,而不是站点实时的内容。

image

CDN 经过多年的发展,已经变成了一个很庞大的体系:分布式存储、全局负载均衡、网络重定向、流量控制等都属于 CDN 的范畴,尤其是在视频、直播等领域,如果没有 CDN,用户是不可能实现流畅观看内容的。CDN 作为网络的基础服务,独立搭建的成本巨大。

0.4.3. 多机房

从架构上来说,单机房就是一个全局的网络单点,在发生比较大的故障或者灾害时,单机房难以保证业务的高可用。

多机房设计最核心的因素就是如何处理时延带来的影响,常见的策略有:

  1. 同城多机房:搭建私有的高速网络,基本上能够做到和同机房一样的效果。
  2. 跨城多机房:机房间通过网络进行数据复制,但由于网络时延的问题,业务上需要做一定的妥协和兼容,且与业务有很强的关联性。
  3. 跨国多机房:一般仅用于备份和服务本国用户。

0.4.4. 多中心

多中心必须以多机房为前提,但从设计的角度来看,多中心相比多机房是本质上的飞越,难度也高出一个等级。

多机房的主要目标是灾备,多中心要求每个中心都同时对外提供服务,且业务能够自动在多中心之间切换,故障后不需人工干预或者很少的人工干预就能自动恢复。

多中心设计的关键就在于“数据一致性”和“数据事务性”,这两个难点都和业务紧密相关。

0.5. 用户层技术

0.5.1. 用户管理

互联网业务的一个典型特征就是通过互联网将众多分散的用户连接起来,因此用户管理是互联网业务必不可少的一部分。

互联网业务拆分为多个子系统,管理用户时需要要实现单点登录(SSO),实现手段较多,例如 cookie、JSONP、token 等,目前最成熟的开源方案是 CAS,架构如下:

image

当业务做大后,开放成为了促进业务进一步发展的手段,需要允许第三方应用接入:授权登录。现在最流行的授权登录就是 OAuth 2.0 协议,基本上已经成为了事实上的标准。

0.5.2. 消息推送

消息推送根据不同的途径,分为:

  • 短信:运营商的短信接口
  • 邮件:邮件服务商的邮件接口
  • 站内信:系统提供的消息通知功能
  • App 推送:iOS(APNS) 和 Android(国外GCM,国内各家自己定制或阿里云移动推送、腾讯信鸽推送、百度云推送或第三方友盟推送、极光推送) 推送

通常情况下:

  • 如果不涉及敏感数据,Android 系统上推荐使用第三方推送服务,毕竟专业,消息到达率是有一定保证的。
  • 如果涉及敏感数据,需要自己实现消息推送,主要包含 3 个功能:
    • 设备管理(唯一标识、注册、注销)
    • 连接管理
    • 消息管理

主要挑战:

  1. 海量设备和用户管理:消息推送的设备数量众多,存储和管理这些设备是比较复杂的;同时,为了针对不同用户进行不同的业务推广,还需要收集用户的一些信息,简单来说就是将用户和设备关联起来,需要提取用户特征对用户进行分类或者打标签等。
  2. 连接保活:要想推送消息必须有连接通道,但是应用又不可能一直在前台运行,大部分设备为了省电省流量等原因都会限制应用后台运行,限制应用后台运行后连接通道可能就被中断了,导致消息无法及时的送达。连接保活是整个消息推送设计中细节和黑科技最多的地方,例如应用互相拉起、找手机厂商开白名单等。
  3. 消息管理:实际业务运营过程中,并不是每个消息都需要发送给每个用户,而是可能根据用户的特征,选择一些用户进行消息推送。由于用户特征变化很大,各种排列组合都有可能,将消息推送给哪些用户这部分的逻辑要设计得非常灵活,才能支撑花样繁多的业务需求,可以采取规则引擎之类的微内核架构技术。

0.5.3. 存储云、图片云

互联网业务场景中,用户会上传多种类型的文件数据:

  1. 数据量大
  2. 文件体积小
  3. 访问有时效性

为了满足用户的文件上传和存储需求,需要对用户提供文件存储和访问功能,简单来说,存储云和图片云通常的实现都是“CDN + 小文件存储”,现在有了“云”之后,直接买云服务可能是最快也是最经济的方式。

  • 普通的文件基本上提供存储和访问就够了
  • 图片涉及裁剪、压缩、美化、审核、水印等处理,通常图片云会拆分为独立的系统对用户提供服务

0.6. 业务层技术

业务层面对的主要技术挑战是“复杂度”,复杂度越来越高的一个主要原因就是系统越来越庞大,业务越来越多。通过分,化整为零,分而治之,将整体复杂性分散到多个子业务或子系统中。

子系统太多出现另一个问题,业务的调用流程复杂,出了问题排查也会特别复杂。通过并,高内据低耦原则,将职责关联比较强的子系统合成一个虚拟业务域,然后通过网关对外统一呈现。

0.7. 平台技术

0.7.1. 运维平台

运维平台核心的职责分为四大块:配置、部署、监控、应急,每个职责对应系统生命周期的一个阶段。

  • 配置:主要负责资源的管理。例如,机器管理、IP 地址管理、虚拟机管理等。
  • 部署:主要负责将系统发布到线上。例如,包管理、灰度发布管理、回滚等。
  • 监控:主要负责收集系统上线运行后的相关数据并进行监控,以便及时发现问题。
  • 应急:主要负责系统出故障后的处理。例如,停止程序、下线故障机器、切换 IP 等。

运维平台的核心设计要素是“四化”:标准化、平台化、自动化、可视化。

0.7.1.1. 标准化

需要制定运维标准,规范配置管理、部署流程、监控指标、应急能力等,各系统按照运维标准来实现,避免不同的系统不同的处理方式。标准化是运维平台的基础,没有标准化就没有运维平台

如果某个系统就是无法改造自己来满足运维标准,常见的做法是不改造系统,由中间方来完成规范适配。

例如,某个系统对外提供了 RESTful 接口的方式来查询当前的性能指标,而运维标准是性能数据通过日志定时上报,那么就可以写一个定时程序访问 RESTful 接口获取性能数据,然后转换为日志上报到运维平台。

0.7.1.2. 平台化

传统的手工运维方式需要投入大量人力,效率低,容易出错,因此需要在运维标准化的基础上,将运维的相关操作都集成到运维平台中,通过运维平台来完成运维工作。

运维平台的好处有:

  1. 将运维标准固化到平台中,无须运维人员死记硬背运维标准。
  2. 提供简单方便的操作,相比之下人工操作低效且容易出错。
  3. 可复用,一套运维平台可以支撑几百上千个业务系统。

0.7.2. 自动化

传统手工运维方式效率低下的一个主要原因就是要执行大量重复的操作,运维平台可以将这些重复操作固化下来,由系统自动完成。

例如,一次手工部署需要登录机器、上传包、解压包、备份旧系统、覆盖旧系统、启动新系统,这个过程中需要执行大量的重复或者类似的操作。

有了运维平台后,平台需要提供自动化的能力,完成上述操作,部署人员只需要在最开始单击“开始部署”按钮,系统部署完成后通知部署人员即可。

有了运维平台后,运维平台可以实时收集数据并进行初步分析,当发现数据异常时自动发出告警,无须运维人员盯着数据看,或者写一大堆“grep + awk + sed”来分析日志才能发现问题。

0.7.3. 可视化

运维平台有非常多的数据,如果全部通过人工去查询数据再来判断,则效率很低。

尤其是在故障应急时,时间就是生命,处理问题都是争分夺秒,能减少 1 分钟的时间就可能挽回几十万元的损失,可视化的主要目的就是为了提升数据查看效率

可视化相比简单的数据罗列,具备下面这些优点:

  1. 能够直观地看到数据的相关属性
  2. 能够将数据的含义展示出来
  3. 能够将关联数据整合一起展示

0.7.4. 测试平台

测试平台核心的职责就是测试,包括单元测试、集成测试、接口测试、性能测试等,都可以在测试平台完成。

测试平台的核心目的是提升测试效率,从而提升产品质量,其设计关键就是自动化

传统的测试方式是测试人员手工执行测试用例,测试效率低,重复的工作多。通过测试平台提供的自动化能力,测试用例能够重复执行,无须人工参与,大大提升了测试效率。

为了达到“自动化”的目标,测试平台的基本架构如下图所示。

image

  1. 用例管理:测试自动化的主要手段是通过脚本或者代码来进行测试。为了能够重复执行这些测试用例,测试平台需要将用例管理起来,管理的维度包括业务、系统、测试类型、用例代码。
  2. 资源管理:测试用例要放到具体的运行环境中才能真正执行,运行环境包括硬件(服务器、手机、平板电脑等)、软件(操作系统、数据库、Java 虚拟机等)、业务系统(被测试的系统)。除了性能测试,一般的自动化测试对性能要求不高,所以为了提升资源利用率,大部分的测试平台都会使用虚拟技术来充分利用硬件资源,如虚拟机、Docker 等技术。
  3. 任务管理:将测试用例分配到具体的资源上执行,跟踪任务的执行情况。任务管理是测试平台设计的核心,它将测试平台的各个部分串联起来从而完成自动化测试。
  4. 数据管理:测试任务执行完成后,需要记录各种相关的数据(例如,执行时间、执行结果、用例执行期间的 CPU、内存占用情况等),这些数据具备下面这些作用:
    1. 展现当前用例的执行情况。
    2. 作为历史数据,方便后续的测试与历史数据进行对比,从而发现明显的变化趋势。
    3. 作为大数据的一部分,可以基于测试的任务数据进行一些数据挖掘。

0.7.5. 数据平台

数据平台的核心职责主要包括三部分:数据管理、数据分析和数据应用。每一部分又包含更多的细分领域,详细的数据平台架构如下图所示。

image

0.7.5.1. 数据管理

数据管理包含数据采集、数据存储、数据访问和数据安全四个核心职责,是数据平台的基础功能。

  • 数据采集:从业务系统搜集各类数据。例如,日志、用户行为、业务数据等,将这些数据传送到数据平台。
  • 数据存储:从业务系统采集的数据存储到数据平台,用于后续数据分析。
  • 数据访问:对外提供各种协议用于读写数据。例如,SQL、Hive、Key-Value 等读写协议。
  • 数据安全:通常数据平台都是多个业务共享的,部分业务敏感数据需要加以保护,防止被其他业务读取甚至修改,因此需要设计数据安全策略来保护数据。

0.7.5.2. 数据分析

数据分析包括数据统计、数据挖掘、机器学习、深度学习等几个细分领域。

  • 数据统计:根据原始数据统计出相关的总览数据。例如,PV、UV、交易额等。
  • 数据挖掘:为了与机器学习和深度学习区分开,这里的数据挖掘主要是指传统的数据挖掘方式。例如,有经验的数据分析人员基于数据仓库构建一系列规则来对数据进行分析从而发现一些隐含的规律、现象、问题等。
  • 机器学习、深度学习:属于数据挖掘的一种具体实现方式,其实现方式与传统的数据挖掘方式差异较大,因此数据平台在实现机器学习和深度学习时,需要针对机器学习和深度学习独立进行设计。

0.7.5.3. 数据应用

数据应用很广泛,既包括在线业务,也包括离线业务。例如,推荐、广告等属于在线应用,报表、欺诈检测、异常检测等属于离线应用。

数据应用能够发挥价值的前提是需要有“大数据”,只有当数据的规模达到一定程度,基于数据的分析、挖掘才能发现有价值的规律、现象、问题等。如果数据没有达到一定规模,通常情况下做好数据统计就足够了。

0.7.6. 管理平台

管理平台的核心职责就是权限管理,无论是业务系统(例如,淘宝网)、中间件系统(例如,消息队列 Kafka),还是平台系统(例如,运维平台),都需要进行管理。如果每个系统都自己来实现权限管理,效率太低,重复工作很多,因此需要统一的管理平台来管理所有的系统的权限。

权限管理主要分为两部分:身份认证权限控制,其基本架构如下图所示。

image

  • 身份认证:确定当前的操作人员身份,防止非法人员进入系统。为了避免每个系统都自己来管理用户,通常情况下都会使用企业账号来做统一认证和登录。
  • 权限控制:根据操作人员的身份确定操作权限,防止未经授权的人员进行操作。
上次修改: 10 June 2020