互联网系统架构演化
1. 程序三高
1. 程序三高
1)高并发
高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时(并行)正确处理多个请求。 高并发相关常用的一些指标如下:
- 响应时间:系统对请求做出响应的时间。例如系统处理一个 HTTP 请求需要 200ms,这个 200ms 就是系统的响应时间。
- 吞吐量:单位时间内处理的请求数量。
- TPS:每秒响应事务数。
- 并发用户数:同时承载能正常使用系统功能的用户数量。
2)高性能
简单地说,高性能(High Performance)就是指程序处理速度快,所占内存少,CPU 占用率低。
- 高并发和高性能是紧密相关的,提高应用的性能,是肯定可以提高系统的并发能力的。
- 应用性能优化的时候,对于计算密集型和 I/O 密集型还是有很大差别,需要分开来考虑。
- 增加服务器资源(CPU、内存、服务器数量),绝大部分时候是可以提高应用的并发能力和性能 (前提是应用能够支持多任务并行计算,多服务器分布式计算才行),但也是要避免其中的一些问题,才可以更好的更有效率的利用服务器资源。
3)高可用
高可用性(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,保证其服务的高度可用性(一直都能用)。
2. 传统架构
2.1 提高服务器性能(单机)
硬件/系统级别的解决方案:
- 增强单机硬件性能(优先):如增加 CPU 核数如 32 核;升级更好的网卡如万兆;升级更好的硬盘如 SSD;扩充硬盘容量如 2T;扩充系统内存如 128G。
- 换掉免费的 Tomcat,使用商用 weblogic(Oracle 公司出品)。
- 聘请系统架构师优化 Linux 内核。
- 甚至花高价直接购买高性能服务器。
应用级别的解决方案:
- 网页 HTML 静态化。
- 图片服务器分离。
- 缓存: 提高响应速度;减少 I/O 次数。
- 使用异步来增加单服务吞吐量。
- 使用无锁数据结构来减少响应时间。
随着业务的不断增加,服务器性能很快又到达瓶颈。不管是提升单机硬件性能,还是提升单机架构性能,都有一个致命的不足:单机性能总是有极限的。所以互联网系统架构对高并发的终极解决方案还是水平扩展。
水平扩展(Scale Out):只要增加服务器数量,就能线性扩充系统性能。水平扩展对系统架构设计是有要求的,难点在于:如何在架构各层进行可水平扩展的设计。
2.2 增加服务器数量(DNS)
DNS(Domain Name System,域名系统),因特网上作为域名和 IP 地址相互映射的一个分布式数据库,能够使用户更方便地访问互联网,而不用去记住能够被机器直接读取的 IP 数串。通过主机域名得到该域名对应的 IP 地址的过程叫做域名解析。DNS 协议运行在 UDP 协议之上,使用端口号 53。
循环复用 DNS 是一个普遍使用的在 Web 服务器上负载平衡的解决方案。
http://www.company.cn : 192.168.1.100
192.168.1.101
192.168.1.102
弊端:循环复用 DNS 将传入的 IP 请求映射到定义的一系列循环形式的服务器。一旦其中的服务器发生故障,循环复用 DNS 会继续把请求发送到这个故障服务器,直到把该服务器从 DNS 中移走为止。在这之前,许多用户必须等到 DNS 连接超时以后才能成功地访问目标网站(正常运行的服务器)。
2.3 负载均衡
由于现有系统的各个核心部分随着业务量、访问量和数据流量的快速增长,其处理能力和计算强度也需要相应地增大,使得单一的服务器设备根本无法承担。在此情况下,如果扔掉现有设备去做大量的硬件升级,这样将造成现有资源的浪费,而且如果再面临下一次业务量的提升时,这又将导致再一次硬件升级的高额成本投入,甚至性能再卓越的设备也不能满足当前业务量增长的需求。
针对此情况而衍生出来的一种廉价、有效、透明的方法以扩展现有网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性的技术就是负载均衡(Load Balance)。
负载均衡的功能总结
- 转发请求
- 故障移除
- 恢复添加
负载均衡种类
- 一种是通过硬件来解决,常见的硬件有 NetScaler、F5、Radware 和 Array 等商用的负载均衡器,但是它们是比较昂贵的。
- 一种是通过软件来解决,常见的软件有 LVS、Nginx、apache 等,它们是基于 Linux 系统并且开源的负载均衡策略。
负载均衡——主流的软件解决方案
- apache + JK
- nginx + keepalived
- lvs + keepalived
Apache + JK
Apache 是世界使用排名第一的 Web 服务器软件。它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的 Web 服务器端软件。
JK 则是 apache 提供的一款为解决大量请求而分流处理的开源插件。
Keepalived
Keepalived 是一个基于 VRRP 协议来实现的 WEB 服务高可用方案,可以利用其来避免单点故障。Keepalived 的作用是检测 Web 服务器的状态,如果有一台 Web 服务器死机或工作出现故障,Keepalived 会检测到并将有故障的 Web 服务器从系统中剔除,当 Web 服务器工作正常后 Keepalived 会自动将 Web 服务器恢复加入到服务器群中。这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的 Web 服务器。
一个 Web 服务至少会有 2 台服务器运行 Keepalived,一台为主服务器(Master),一台为备份服务器(Backup),但是对外表现为一个虚拟 IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机时,备份服务器就会接管虚拟 IP,继续提供服务,从而保证了高可用性。
Nginx
Nginx 是一款轻量级的反向代理服务器,由俄罗斯的程序设计师 Igor Sysoev(伊戈尔·西索夫)所开发,供俄国大型的入口网站及搜索引擎 Rambler(漫步者)使用。
Nginx 特点是占有内存少,并发能力强,事实上 Nginx 的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用 Nginx 的网站用户有腾讯、新浪、网易等。
优点
- 可运行在 Linux 上,并有 Windows 移植版。
- 在高连接并发的情况下,Nginx 是 Apache 服务器不错的替代品。Nginx 在美国是做虚拟主机生意的老板们经常选择的软件平台之一。能够支持高达 50,000 个并发连接数(顶级服务器的基础上)。
LVS
LVS 的英文全称是 Linux Virtual Server,即 Linux 虚拟服务器,它是我国的章文嵩博士的一个开源项目。在 Linux 内核 2.6 中,它已经成为内核的一部分,在此之前的内核版本则需要重新编译内核。
优点:
- 抗负载能力强:因为 LVS 工作方式的逻辑非常简单,而且工作在网络 4 层仅做请求分发之用(四层面向的是网络连接而不是数据包),几乎没有流量,保证了均衡器的 I/O 性能不会受到大流量的影响,所以在效率上基本不需要过多考虑。在我手里的 LVS,仅仅出过一次问题:在并发最高的一小段时间内均衡器出现丢包现象,据分析为网络问题,即网卡或 Linux 2.4 内核的承载能力已到上限,内存和 CPU 方面基本无消耗(对机器性能要求不高,因此可运行在廉价机器上)。
- 配置性低:这通常是一大劣势,但同时也是一大优势,因为没有太多可配置的选项,所以除了增减服务器,并不需要经常去触碰它,大大减少了人为出错的几率。
- 工作稳定:因为其本身抗负载能力很强,所以稳定性高也是顺理成章,另外各种 LVS 自身都有完整的双机热备方案(如 LVS + Keepalived 和 LVS + Heartbeat),所以一点不用担心均衡器本身会出什么问题,节点出现故障的话,LVS 会自动判别,所以系统整体是非常稳定的。
- 基本上能支持所有应用:因为 LVS 工作在网络 4 层,所以它可以对几乎所有应用做负载均衡,包括 HTTP、数据库、聊天室等。
缺点:
- 软件本身不支持正则处理,不能做动静分离,这就凸显了 Nginx/HAProxy + Keepalived 的优势。
- 如果网站应用比较庞大,LVS/DR + Keepalived 就比较复杂了,特别是后面有 Windows 机器的话,实施及配置还有维护过程就比较麻烦,相对而言 Nginx/HAProxy+Keepalived 更简单。
LVS 对比 Nginx:
- 负载度:LVS > Nginx
- 功能多少:Nginx > LVS
- 稳定性:LVS > Nginx
- 服务器性能要求:LVS > Nginx
为什么说 LVS 几乎无流量产生?
LVS 总共有三种代理方式:
- NAT(网络地址映射):请求和响应产生流量
- IP Tunnelling(IP 隧道):请求产生流量
- Direct Routing(直接路由):请求产生流量
NAT(网络地址映射)工作原理图
所有的连接都要经过 LVS,所以这种负载方式是有流量限制的,具体能撑起多大的流量跟机器有关。
IP Tunneling(IP 隧道)
Direct Routing(直接路由)
我们发现它的工作原理图和 IP Tunneling 很像:Request 通过 LVS 进行转发,然后 Real Server 直接将 Response 发送给 Client。
只是有一点不同,图中说了 LVS 和 Real Server 需要在同一个网段上(Must be in a physical segment)。
总结
- 对于 NAT(网络地址映射):因为 Request 和 Response 都要经过 LVS,所以这种负载策略是产生流量的,具体能够撑起多大的流量更硬件配置有关(如网卡)。
- 对于 IP Tunneling(IP 隧道)和 Direct Routing(直接路由):这两种负载策略几乎是不产生流量的(Client 发送的第一个数据包需要经过 LVS,所以会产生少量的流量),而后 Client 就直接与 Real Server 通信了,不会再经过 LVS,所以后面这两种负载策略能够扛住更大的连接。也就是说,后面这两种负载策略会在 Client 和 Real Server 之间直接建立起连接而不需要经过 LVS,所以除了前面几个数据包会产生流量意外,后面的数据包根本不经过 LVS 了也就没有产生流量了。
负载均衡解决方案示意图
注意上图中的三角链路:由 LVS 转发的用户请求,再经 Nginx 转发 Real Server 处理完请求后,直接通过 Nginx 将响应返回给用户。
CDN:全称是 Content Delivery Network,即内容分发网络,也称为内容传送网络。CDN 是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。
CDN 的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
CDN 的基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN 系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息,将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet 网络拥挤的状况,提高用户访问网站的响应速度。
2.4 数据库解决方案
1)主从复制、读写分离
Mysql
- 缓存:Memcached(纯内存)、Redis(纯内存、纯内存+持久化)
- 消息队列:MQ、Kafka
- 主从复制(针对高可用问题;双主解决备份问题)+ 读写分离(针对高并发问题):此方案的每台数据库仍是全量数据
- 分库分表
- 分布式
Oracle
- 读写分离 + 主从复制
- Oracle Partition(分区)
- 分库分表
- Oracle RAC 集群(终级解决方案):此方案成本非常昂贵,即使是淘宝,京东这样的大公司,也是很难受的
示例图
2)分库分表
在代码层面实现分库分表逻辑:
使用分布式/分库分表的中间件:
使用分布式数据库:
3. 云计算架构
传统方式:On-Premise(本地部署)
采购硬件、装系统、组网、安装 Java、安装数据库、安装软件、配置软件、使用软件。
IaaS(Infrastructure as a Service):基础设施即服务
安装 Java、安装数据库、安装软件、配置软件、使用软件。
PaaS(Platform as a Service):平台即服务
安装软件、配置软件、使用软件。
SaaS(Software as a Service):软件即服务
配置软件使用或者直接使用软件。
3. 微服务架构
模块化
将单个大型系统,解耦拆分成各子模块系统。
服务化
- 左图:各子模块系统之间的调用仍通过负载均衡。
- 右图:传统的网关可以认为就是负载均衡,而注册中心可以理解为存储了各系统/服务的调用信息。如交易系统从注册中心获取到调用财务系统的方式是 RPC,而无需再走负载均衡。
数据拆分/分布式事务化
- 左图:数据库跟随业务系统的模块拆分而拆分。
- 右图:各业务模块中的数据库再实现分库分表分布式。
单元化
继续将系统架构进行分层,且下图中每一列数据链路分别代表各地的数据中心,假如此时用户从 A 地(如北京市)跑到了 B 地(如深圳市)使用服务,那么两地间的用户数据同步及跨地访问服务将出现效率问题。
策略:如下图所示,用户每一次访问服务仅使用所在地的数据/网络链路。这样虽然牺牲了用户在短暂逗留地区的访问效率,但保证了用户在主要居住地的服务/数据访问效率。
如某用户主要居住在北京市,平时在查看个人历史数据时访问效率快,而在其他区域(如在深圳市)查看个人历史数据时则可能需要等待多转几个圈的加载时间。