1、Docker之技术架构演进之路
- 概述
- 常见概念
-
- 基本概念
-
- [应用(Application)/ 系统(System)](#应用(Application)/ 系统(System))
- [模块(Module)/ 组件(Component)](#模块(Module)/ 组件(Component))
- 分布式(Distributed)
- 集群(Cluster)
- [主(Master)/ 从(Slave)](#主(Master)/ 从(Slave))
- 中间件(Middleware)
- 容器(Docker)
- 容器编排(K8S)
- 评价指标(Metric)
-
- 可用性(Availability)
- [响应时长(Response Time RT)](#响应时长(Response Time RT))
- [吞吐(Throughput)vs 并发(Concurrent)](#吞吐(Throughput)vs 并发(Concurrent))
- 架构演进
-
- 单机架构
- 应用数据分离架构
- 应用服务集群架构
- [读写分离 / 主从分离架构](#读写分离 / 主从分离架构)
- [引入缓存 ------ 冷热分离架构](#引入缓存 —— 冷热分离架构)
- 垂直分库
- [业务拆分 ------ 微服务](#业务拆分 —— 微服务)
- 容器化引入------容器编排架构
概述
在进行技术学习过程中,由于大部分读者没有经历过一些中大型系统的实际经验,导致无法从全局理解一些概念,所以本文以一个 "电子商务" 应用为例,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,方便大家对后续知识做深入学习时有一定的整体视野。
常见概念
基本概念
应用(Application)/ 系统(System)
为了完成一整套服务的一个程序或者一组相互配合的程序群。生活例子类比:为了完成一项任务,而搭建的由一个人或者一群相互配的人组成的团队。
模块(Module)/ 组件(Component)
当应用较复杂时,为了分离职责,将其中具有清晰职责的、内聚性强的部分,抽象出概念,便于理解。生活例子类比:军队中为了进行某据点的攻克,将人员分为突击小组、爆破小组、掩护小组、通信小组等。
分布式(Distributed)
系统中的多个模块被部署于不同服务器之上,即可以将该系统称为分布式系统。如 Web 服务器与数据库分别工作在不同的服务器上,或者多台 Web 服务器被分别部署在不同服务器上。生活例子类比:为了更好的满足现实需要,一个在同一个办公场地的工作小组被分散到多个城市的不同工作场地中进行远程配合工作完成目标。跨主机之间的模块之间的通信基本要借助网络支撑完成。
集群(Cluster)
==被部署于多台服务器上的、为了实现特定目标的一个/组特定的组件,整个整体被称为集群。==比如多个 MySQL 工作在不同服务器上,共同提供数据库服务目标,可以被称为一组数据库集群。生活例子类比:为了解决军队攻克防守坚固的大城市的作战目标,指挥部将大批炮兵部队集中起来形成一个炮兵打击集群。
分布式 vs 集群。通常不用太严格区分两者的细微概念,细究的话,分布式强调的是物理形态,即工作在不同服务器上并且通过网络通信配合完成任务;而集群更在意逻辑形态,即是否为了完成特定服务目标。
主(Master)/ 从(Slave)
集群中,通常有一个程序需要承担更多的职责,被称为主;其他承担附属职责的被称为从。比如 MySQL 集群中,只有其中一台服务器上数据库允许进行数据的写入(增/删/改),其他数据库的数据修改全部要从这台数据库同步而来,则把那台数据库称为主库,其他数据库称为从库。
中间件(Middleware)
一类提供不同应用程序用于相互通信的软件,即处于不同技术、工具和数据库之间的桥梁生活例子类比:一家饭店开始时,会每天去市场挑选买菜,但随着饭店业务量变大,成立一个采购部,由采购部专职于采买业务,称为厨房和菜市场之间的桥梁。
容器(Docker)
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 操作系统的机器上,也可以实现虚拟化。可以理解为一个集装箱,集装箱里面是每个用户的货物,整体打包。
容器编排(K8S)
kubernetes,简称 K8s,是用 8 代替名字中间的 8 个字符"ubernete"而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化的应用简单并且高效。可以理解为一个货船,安装集装箱的大小,货物情况合理的来组织集装箱完成整体货物的搬运。
评价指标(Metric)
可用性(Availability)
考察单位时间段内,系统可以正常提供服务的概率/期望。例如: 年化系统可用性= 系统正常提供服务时长 / 一年总时长。这里暗含着一个指标,即如何评价系统提供无法是否正常,我们就不深入了。平时我们常说的 4 个 9 即系统可以提供 99.99% 的可用性,5 个 9 是 99.999% 的可用性,以此类推。我们平时只是用高可用(High Availability HA)这个非量化目标简要表达我们系统的追求。
响应时长(Response Time RT)
指用户完成输入到系统给出用户反应的时长。例如点外卖业务的响应时长 = 拿到外卖的时刻 - 完成点单的时刻。通常我们需要衡量的是最长响应时长、平均响应时长和中位数响应时长。这个指标原则上是越小越好,但很多情况下由于实现的限制,需要根据实际情况具体判断
吞吐(Throughput)vs 并发(Concurrent)
吞吐考察单位时间段内,系统可以成功处理的请求的数量。并发指系统同一时刻支持的请求最高量。例如一条 2 车道高速公路,一分钟可以通过 20 辆车,则并发是 2,一分钟的吞吐量是 20。实践中,并发量往往无法直接获取,很多时候都是用极短的时间段(比如 1 秒)的吞吐量做代替。我们平时用高并发(Hight Concurrnet)这个非量化目标简要表达系统的追求。
架构演进
单机架构
单机架构是指整个系统在单台计算机上运行的架构。在单机架构中,所有的软件组件和服务都部署在同一台计算机上,相互之间通过内部通信进行交互。这种架构通常用于小型应用或者开发环境,因为它的扩展性和可靠性有限。单机架构的优点是部署简单、易于管理,但是在处理大规模数据或高并发请求时会面临性能瓶颈。
应用数据分离架构
应用数据分离架构是一种软件架构模式,旨在将应用程序的用户界面和业务逻辑与数据存储分离开来。这种架构模式的主要目的是提高系统的灵活性、可维护性和可扩展性。
在应用数据分离架构中,用户界面、业务逻辑和数据存储被分别组织成独立的模块或层。通常,用户界面层负责与用户交互,业务逻辑层负责处理应用程序的核心功能,而数据存储层则负责管理和存储数据。这种分离使得各个部分可以独立地进行修改、扩展和维护,而不会对其他部分造成影响。
应用数据分离架构通常可以提高开发效率,降低系统的复杂性,并且使得不同部分可以由不同的团队并行开发。这种架构模式也有助于实现跨平台的数据共享和重用,从而提高系统的整体性能和可靠性。
应用服务集群架构
应用服务集群架构是一种将应用程序部署在多台服务器上,通过负载均衡等技术实现高可用性和扩展性的架构方式。在这种架构中,多台服务器共同提供同一种服务,通过负载均衡器将请求分发到不同的服务器上,从而实现对请求的处理和资源的分配。
举个简单的Java例子来说明应用服务集群架构。假设我们有一个简单的Web应用,提供一个计算两个数字相加的功能。我们可以将这个应用部署在一个应用服务集群架构中,其中有多台服务器提供相同的服务。
首先,我们编写一个简单的Java Servlet来处理请求:
java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class AddServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int num1 = Integer.parseInt(request.getParameter("num1"));
int num2 = Integer.parseInt(request.getParameter("num2"));
int sum = num1 + num2;
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h2>Sum of " + num1 + " and " + num2 + " is " + sum + "</h2>");
out.println("</body></html>");
}
}
然后,我们将这个Servlet部署在多台服务器上,通过负载均衡器将请求分发到不同的服务器上。这样,无论用户访问哪台服务器,都可以得到相同的计算结果,同时也提高了系统的可用性和扩展性。
这就是一个简单的Java例子,说明了应用服务集群架构是如何工作的。
读写分离 / 主从分离架构
读写分离(主从分离)是一种常见的数据库架构设计模式,用于提高数据库系统的性能和可靠性。在这种架构中,数据库被分成主数据库和从数据库。主数据库负责处理写操作(插入、更新、删除),而从数据库则负责处理读操作(查询)。
通过这种架构,可以将读操作和写操作分开处理,从而减轻主数据库的负担,提高系统的并发处理能力和读取性能。同时,当主数据库发生故障时,从数据库可以接管服务,保证系统的可用性。
读写分离架构通常用于高流量的网站和应用程序中,可以通过复制主数据库的数据到从数据库来实现。这种架构需要考虑数据同步的机制,以确保主从数据库之间的数据一致性。常见的数据库产品如MySQL、PostgreSQL和MongoDB都支持读写分离架构。
引入缓存 ------ 冷热分离架构
引入缓存是指在系统架构中引入缓存层,用于存储和提供频繁访问的数据,以提高系统的性能和响应速度。冷热分离架构是一种常见的缓存架构设计模式,它将数据按照访问频率的高低分为热数据和冷数据两类,并将它们存储在不同的缓存层中。
热数据是指经常被访问的数据,它们的访问频率较高,对系统的性能影响较大。为了提高系统的响应速度,热数据通常被存储在高速缓存中,如内存缓存或者分布式缓存,以便快速地响应用户的请求。
冷数据是指访问频率较低的数据,它们的访问对系统的性能影响较小。为了节省资源和成本,冷数据通常被存储在低速缓存中,如磁盘缓存或者对象存储服务中。当需要访问冷数据时,系统可以从低速缓存中获取,虽然相比高速缓存会有一定的延迟,但对于冷数据来说,这种延迟是可以接受的。
通过引入缓存和冷热分离架构,系统可以将热数据存储在高速缓存中,提高系统的响应速度和吞吐量,同时将冷数据存储在低速缓存中,节省资源和成本。这种架构设计可以有效地提升系统的性能和可扩展性,适用于大部分需要处理大量数据的应用场景。
垂直分库
垂直分库是指根据数据表的垂直划分原则,将一个数据库中的表按照其关联性或功能特点分散存储到不同的数据库中。这种分库方式通常用于解决单一数据库负载过重、数据隔离、性能优化等问题。例如,将一个包含用户信息和订单信息的数据库根据功能特点分为两个数据库,一个存储用户信息,另一个存储订单信息,从而降低单一数据库的压力,提高系统的扩展性和性能。
业务拆分 ------ 微服务
业务拆分是指将一个大型的软件系统按照业务功能或领域进行划分,拆分成多个小的独立服务的过程。在微服务架构中,业务拆分是非常重要的一步,通过将系统拆分成多个微服务,可以使得系统更加灵活、可扩展和易于维护。
在业务拆分过程中,通常会根据业务功能的不同将系统拆分成多个微服务,每个微服务负责一个特定的业务功能。这样可以使得每个微服务都相对独立,可以独立部署、扩展和维护,同时也可以更好地实现团队的分工合作。
通过业务拆分,可以使得系统更加灵活,可以根据业务需求快速调整和扩展各个微服务,同时也可以降低系统的复杂性,提高系统的可维护性和可扩展性。
容器化引入------容器编排架构
容器化引入是指将应用程序及其所有依赖项打包到一个独立的容器中,以便在不同的环境中轻松部署和运行。容器编排架构则是一种管理和编排容器化应用程序的技术,它可以自动化应用程序的部署、扩展、管理和监控。常见的容器编排工具包括Docker Swarm、Kubernetes等。通过容器化引入和容器编排架构,开发人员可以更轻松地构建、部署和管理复杂的应用程序,提高开发效率和系统稳定性。