一、架构基础
- 架构定义:有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计
- 常见软件架构
- 单机:所有功能都实现在一个进程里,进程部署在单台机器上,运维时需要停服
- C10K问题(Concurrent 10,000 Connection):服务器如何支持10K个并发连接,进行高性能网络编程。解决方式:采用IO复用模型epoll方法,在调用返回时,只给应用提供发生了状态变化的文件句柄,不需要轮询fd(文件描述符)
- 单机架构瓶颈:
- 需要大量进程 / 线程作为处理单元,需要占用大量内存空间
- 进程 / 线程切换,系统调度代价高
- 解决方案:采用协程(Routine),一个线程中,存在多个协程。协程实现如Go语言的轻量级线程Goroutine。协程由程序控制,在用户态中执行,在线程的基础上通过分时复用的方式运行多个协程
- 协程适用场景:IO密集型任务,异步IO型任务(异步IO型任务包括:主动查询是否有数据;被动监听是否有数据状态)
- 单体:分布式部署,进程部署在多台机器上,具备水平扩容能力(添加更多服务器),运维不需要停服
- CAP理论:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)三项中的两项
- 一致性:所有节点同时看到相同的数据
- 可用性:读写总是成功的
- 分区容错性:尽管任意消息存在丢失或部分系统存在故障,系统继续运行
- CAP理论:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)三项中的两项
- 垂直应用:单体架构基础上,将进程按照应用垂直切分开的单体,在一定程度上减少了后端进程职责
- 面向服务型架构(SOA,Service Oriented Architecture):将进程按照不同的功能单元进行抽象,拆分为服务。SOA为服务间通信提供标准,采用重量级协议,如SOAP及其他WS标准
- 微服务(Micro-Service):SOA的去中心化的演进,每个服务都有自己的数据模型和数据库
- 注意事项:
- 数据一致性
- 高可用
- 治理、容灾
- 解耦 vs. 过微
- 权衡运维成本
- 注意事项:
- 单机:所有功能都实现在一个进程里,进程部署在单台机器上,运维时需要停服
- 架构演进方式:业务需求量逐渐增大、系统逐渐复杂
- 水平切分:分层 / 模块化
- 垂直切分:分布式
二、企业级后端架构
- 云计算:通过软件自动化管理,提供计算资源的服务网络,是现代互联网大规模数据分析和存储的基石
- 虚拟化技术:对计算机资源的抽象,实现资源隔离与共享,资源异构性屏蔽,资源池化
- 硬件层:VMware
- 操作系统层:Docker
- 网络层:Open V Switch(OVS),基于软件实现的开源虚拟交换机
- 编排方案
- VM:OpenStack(一款开源虚拟化平台) / VMWare Workstation
- OpenStack各组件:
- Horizon,Web前端服务
- Nova,计算服务
- Neutron,网络服务
- Swift,对象存储服务
- Cinder,块存储服务
- Keystone,认证服务
- Glance,镜像服务
- Ceilometer,监控服务
- Heat,集群服务
- Trove,数据库服务
- OpenStack各组件:
- Container:Kubernetes、Docker Swarm
- VM:OpenStack(一款开源虚拟化平台) / VMWare Workstation
- 虚拟化技术:对计算机资源的抽象,实现资源隔离与共享,资源异构性屏蔽,资源池化
- 云架构
- IaaS:Infrastructure as a Service,基础设施即服务,对底层硬件资源池的抽象。消费者在其中的角色是开发者或系统管理员。如阿里云的ECS云主机、Amazon EC2(2006年推出)
- PaaS:Platform as a Service,平台即服务,基于资源池抽象,云中有完整开发和部署环境。消费者在其中的角色是开发者。如Google App Engine、Windows Azure Platform
- SaaS:Software as a Service,软件即服务,基于弹性资源平台,一切不需要本地化部署的云服务软件产品。消费者在其中的角色是终端用户。如OA、CRM、E-mail服务
- FaaS:Function as a Service,函数即服务,更轻量级的函数服务。开发者只需要编写业务代码,无需关注服务器,并且代码的执行由事件触发。如LeetCode的Online Judge系统、AWS Lambda
- 云原生(Cloud Native):构建和运行可弹性拓展的应用
- 弹性资源
- 弹性计算资源:虚拟化容器、快速扩缩容
- 服务资源调度
- 微服务
- 大服务:调用量多
- 计算资源调度
- 在线计算:互联网后端服务,如热销榜单
- 离线计算:大数据分析,MapR / Spark / Flink,如热销榜单更新
- 消息队列
- 在线队列:削峰、解耦
- 离线队列:结合数据分析的一整套方案,如ELK
- 服务资源调度
- 弹性存储资源:将存储资源当成服务一样
- 经典存储
- 对象存储:视频、图片等
- 大数据存储:应用日志、用户数据等
- 关系型数据库
- 元数据:
- 服务发现:程序如何通过一个标志来获取服务列表,并且这个服务列表能够随着服务的状态而动态变更
- NoSQL
- KV存储:Redis
- 文档存储:MongoDB
- 经典存储
- 弹性计算资源:虚拟化容器、快速扩缩容
- 微服务架构:提供业务功能单元解耦,提供统一的通信标准。微服务将单一应用程序划分成一组小的服务,每个服务域进行在独立的进程中。云原生场景下,微服务不必在业务逻辑中实现符合通信标准的交互逻辑,而是交给框架来做
- 通信协议:轻量级的通信机制
- HTTP(RESTful API)
- RPC(Thrift,gRPC)
- 微服务中间件RPC和HTTP:选用时从性能(RPC提供大量压缩方案)、服务治理、协议可解释性(HTTP的JSON格式)来考虑
- 微服务的部署方式
- 虚拟机
- 容器
- 解决了应用程序运行环境依赖
- 实现计算资源、网络、存储的隔离
- 提高部署密度和计算资源的利用率
- 无服务器模式(Serverless):由开发者实现的服务端逻辑运行在无状态的计算容器中,由事件触发,完全被第三方管理
- 无需管理基础设施
- 事件驱动
- 自动化构建部署
- 无服务器计算 = FaaS + BaaS(Function as a Service + Backend as a Service)
- 通信协议:轻量级的通信机制
- DevOps:贯穿整个软件开发周期
- 敏捷开发
- CI / CD(Continuous Integration / Continuous Delivery,持续集成 / 持续交付):实现应用开发中高度持续自动化和持续监控
- 服务网格(Service Mesh):微服务之间通信的中间层,一个高性能的四层网络代理,数据平面代理与业务进程采取进程间通信的模式,将流量层面的逻辑(包含治理)与业务进程解耦
- 业务与治理解耦,生命周期易于管理
- 异构系统的治理统一化
- 具有复杂治理能力
- 弹性资源
三、后端架构的挑战
- 基础设施层面
- 存在问题:
- 离线任务(主要为CPU密集型,非实时性)和在线任务(主要为IO密集型,潮汐性、实时性)的物理资源用量峰期不同。
- 物理资源有限、带宽有限,资源利用率受限于部署服务
- 解决思路:
- 离在线资源并池:采用混合资源池,按时间段划分离线资源池和在线资源池,提高物理资源利用率
- 同一个机器上的离在线隔离:使用容器对CPU核心做隔离,使用cgroup统一对离在线进程进行分组
- 利用在线业务潮汐性自动扩缩容,扩缩容的依据指标:如CPU使用率的P50数值(中位数值)、内存利用率等
- 存在问题:
- 用户层面
- 存在问题:
- 网络抖动导致运维成本提高
- 异构环境中,不同实例间的算力差异(CPU型号差异、网络请求差异)
- 目标:打平异构环境算力差异,为自动扩缩容提供正向输入
- 解决思路:如何屏蔽异构环境的算力差异?CPU水位负载均衡
- IaaS:提供资源探针(Probe)
- 服务网格:动态负载均衡
- 存在问题:
- 微服务层面
- 存在问题1:微服务间的高通信成本
- 目标:降低业务成本,提高服务可用性
- 解决思路:微服务亲和性部署,满足亲和性条件的容器微服务中间件采用IPC(Inter-Process Communication)通信,不满足亲和性条件的容器通过服务网格RPC(Remote Procedure Call),从而减少网络通信。
- 将满足亲和性条件(调用关系紧密、通信量大的服务)的容器部署到一台宿主机
- 微服务中间件与服务网格通过共享内存通信
- 服务网格控制面实施灵活、动态的流量调度
- 存在问题2:流量治理问题
- 目标:提高微服务调用容错性、提供容灾、DevOps提高开发效率
- 解决思路:基于微服务中间件和服务网格的流量治理
- 熔断、重试
- 单元化
- 复杂环境(功能、预览)的流量调度
四、后端架构实战
- 如何做架构设计
- 需求先行:问题定义
- 业界调研:可参考的业界解决方案
- 技术选型:内部 / 社区中的基础组件
- 考虑异常情况:考虑某服务不行了怎么办
- 基本概念
- 负载均衡(Load Balancing):将工作负载分布到多个服务器来提高服务的性能和可靠性
- 服务发现(Service Discovery):容器部署在集群时,服务地址(IP和端口)是集群动态分配的。服务发现解决了在微服务中如何精确的定位需要调用的服务IP及端口
- 服务注册(Service Registry):服务提供者将自己的服务地址等信息登记到服务注册中心
- 注册中心:服务提供者和服务消费者之间的桥梁,提供管理和查询服务注册信息的API。当服务提供者的实例发生变更时,服务注册表更新最新的状态列表,并通知服务消费者
- 如Zookeeper、Netflix Eureka
- 宿主机(Host):可以是物理机或虚拟机
- 容器(Container):包含了完整的运行时环境,基于内核的轻量级虚拟化技术。容器允许同一物理或虚拟服务器上毫不冲突地运行多项工作负载
- 时序数据(Times Series):与时间序列相关的数据,如哨兵监控的指标数据、业务数据(JVM GC、时延)
- 一致性哈希(Consistent Hash):由于HTTP协议的无状态,服务器可能选择存储会话日志来记住用户,从而减少身份验证。因此,在添加或删除服务器时,需要尽可能减少对其他服务器的影响
- 一致性哈希算法的步骤:
- 将服务器节点哈希映射到[0, 2^32-1]的整数圆环上
- 将请求哈希映射到圆环上
- 从请求哈希映射的顺时针方向找到其右侧最近的服务器
- 作用:增加 / 删除服务器时,最多只有一台服务器会受到服务器数量变化的影响
- 一致性哈希算法的步骤:
- 问题:如何设计一个根据主机层面的资源信息,实时进行流量调度的系统,屏蔽不同宿主机异构环境的算力差异?
- 输入
- 服务网格数据面:支持带权重的负载均衡策略,服务发现,流量调度
- 注册中心:存储所有容器的权重信息
- 宿主机:提供容器的资源使用情况、物理资源信息(如CPU型号)
- 关键点
- 紧急回滚能力
- 大规模场景中使用:主要考虑系统稳定性和计算瓶颈
- 极端场景
- 输入
- 架构演进方向
- 方案一:自适应静态权重。采集宿主机物理资源信息,调权代理调整容器注册的权重,缺少紧急回滚能力
- 方案二:自适应动态权重。动态权重决策中心从注册中心获取和更新服务注册信息,从配置中心获取服务在注册中心的名字,通过计算赋予服务运行时自适应动态权重,具备紧急回滚能力
- 方案三:在服务网格层面上报RPC指标(e.g. 实例:X:9090,延迟P50:10ms,延迟P99:100ms),防止权重调节过于偏颇。动态权重中心除了方案二的作用以外,还采集所有服务容器指标,使得极端场景处理成为可能,但时序数据库压力较大
- 方案四:构建更复杂的动态权重决策中心
- 微服务化进行拆分(如分为入口层、离线分析层、在线分析层等)
- 引入消息队列削峰、解耦
- 离在线链路切分
- 梳理强弱依赖
参考文献
[1]兰新宇. 架构初探-谁动了我的蛋糕. 参考链接文章来源地址https://www.toymoban.com/news/detail-801420.html
文章来源:https://www.toymoban.com/news/detail-801420.html
到了这里,关于第三届字节跳动青训营——架构学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!