软件架构:从传统单体到现代微服务的技术演变
1.引言
在软件开发中,架构设计不仅仅是程序员的技术任务,它更是一个项目成功的关键。无论是小型应用还是大型分布式系统,软件架构都直接影响着系统的可维护性、可扩展性、性能和稳定性。理解软件架构的必要性,能够帮助开发人员做出正确的技术决策,从而避免后期出现技术债务、性能瓶颈或是开发效率低下等问题。
对于程序开发人员来说,了解架构模式能够:
- 优化开发效率:合理的架构模式能够规范开发流程,提高团队协作效率。
- 降低系统复杂性:随着项目的规模扩大,系统的复杂性也会增加。架构设计的核心就是分解复杂性,使系统更易于维护和扩展。
- 提高系统灵活性:架构设计可以帮助团队应对需求变化。通过模块化、分层架构等设计,可以确保系统在面对新需求时能够灵活应变。
- 减少风险:在系统设计初期做出正确的架构决策,能够避免项目后期技术上的重构和返工,降低开发成本。
2.架构类型概述
在现代软件开发中,不同的架构模式适用于不同规模和业务需求的项目。以下是六种常见的架构模式:
1. 单体架构 (Monolithic Architecture)
单体架构是指将所有功能和模块集中在一个应用中运行,通常作为一个单独的进程部署。
特点:
- 所有模块紧密耦合,通常共享数据库。
- 开发简单,适合初期小型项目。
- 随着功能增加,代码会变得难以维护。
2. 垂直架构 (Vertical Architecture)
垂直架构将大型应用按照业务拆分成多个相对独立的小型应用,但每个应用仍然是单体架构,且不直接通信。
特点:
- 各模块之间没有明确的通信协议。
- 每个模块可以独立部署,但不具备微服务的灵活性。
- 适用于快速拆分已有单体架构,减少冗余。
3. SOA架构 (Service-Oriented Architecture)
SOA架构将应用划分为多个独立服务,每个服务负责独立的业务功能,并通过企业服务总线(ESB)进行集成。
特点:
- 服务之间通过ESB进行通信。
- 模块化拆分,但可能引入性能瓶颈。
- 通常适用于较大的企业级系统。
4. 微服务架构 (Microservices Architecture)
微服务架构将应用拆分为多个小型、独立部署的服务,每个服务负责单一业务功能,服务之间通过轻量级协议(如REST、RPC)进行通信。
特点:
- 每个服务独立部署和扩展。
- 服务之间的通信相对轻量级。
- 可以使用不同技术栈,灵活性高。
5. 服务网格架构 (Service Mesh Architecture)
服务网格架构是一种用于微服务架构的解决方案,用于管理和优化服务间的通信、流量控制、监控和安全等。
特点:
- 通过独立的网格层(如Istio)管理服务间的流量。
- 支持细粒度的流量控制、熔断和负载均衡。
- 增强了微服务的可观测性和安全性。
6. 云原生架构 (Cloud-Native Architecture)
云原生架构采用容器化、微服务、服务网格等技术,通过自动化和弹性扩展来管理应用。它专门为云环境优化,支持快速部署和弹性伸缩。
特点:
- 强调容器化和微服务。
- 使用持续集成和交付(CI/CD)提高开发效率。
- 完全依赖云平台,具有自动扩展能力。
3.单体架构概述
在计算机软件工程的早期阶段,单体架构模式普遍应用于应用程序的开发实践中。此模式的特点是将应用程序的各个功能模块集中整合至一个统一的代码库中,并在同一进程环境下进行部署。这种设计理念的根源在于,在技术和业务需求较为简单的背景下,通过减少模块间的复杂交互,旨在简化开发和部署流程。
单体架构意味着代码被部署并作为单个节点上的单个进程运行,即all in one。
接下来以一个电商项目为例,将分析单体架构下系统的组成。
在单体架构中,电商系统会被设计为一个单独的应用,所有的功能模块(如用户管理、商品管理、订单管理以及支付管理)都集中在一起,作为一个单一的进程运行,具体如下图所示:

4.垂直架构概述
单体架构随着业务越来越复杂、团队规模越来越大,Git上提交的代码也越来越多,搞到最后,代码集成十分困难,没办法只能将不同分支上的代码独立运行,因此逐渐出现了业务分化,在时间的推动下,一个大的系统就变成了多个子系统共同运行,系统架构就变成了下图样貌。

在垂直架构下,电商应用将每个业务模块(例如,用户、商品、订单)拆分为独立的服务,每个模块仍然是单体架构。各模块可以独立部署和扩展,减轻单体架构的压力。
通过这种方式,能够让团队分工更加明确,并且多个子系统之间互不影响,提升了系统的分区容错性,而且使得系统吞吐量进一步身高。
5.SOA架构概述
经过子系统的演变后,整个系统就变成了分布式系统了,每个子系统负责不同的职责,但是这种子系统拆分存在致命的缺陷。即,在多个子系统之间,就好似一个项目里的多个模块,产生了强耦合性,系统之间的配合和通信,完全靠写死对方子系统的IP来完成调用,一旦某个子系统出现故障,依旧存在整个系统全面瘫痪的风险。
而在SOA架构中,将电商系统拆分为多个业务服务,每个服务通过ESB进行通信,具体如下图所示:

6.微服务架构
虽然ESB可以解决多个子系统之间的通信问题,但是ESB存在性能瓶颈,且服务之间的通信较为复杂,后面就诞生了微服务。
微服务架构通过将单体应用拆分为多个独立的服务,针对不同的业务领域进行划分和优化,可以更加灵活地应对不同服务的并发需求。这种方式不仅提升了系统的可扩展性,还使得各个服务的资源得到了更加合理的利用。
此外,微服务架构还带来了更高的灵活性和可维护性。每个服务独立开发、测试、部署和维护,可以大大降低单个服务出现故障时对整个系统的影响。而且,服务之间的解耦使得在未来的业务发展中,可以根据不同的业务需求和并发量动态调整各个服务的部署和资源分配,进而实现更高效的性能优化和负载均衡。具体针对电商系统的微服务架构图如下所示:

7.服务网格架构
在微服务架构中,随着服务的增加,服务间的通信变得越来越复杂,服务发现与注册、负载均衡、服务熔断和降级、安全与故障恢复等代码和业务逻辑耦合在一起,并且每个微服务都要实现相同的服务注册与发现,熔断等基础设施层代码,同时也增加了维护的成本。因此便出现了服务网格架构。
服务网格是一种基础设施层,用于管理和优化微服务之间的通信、流量控制、负载均衡、监控、安全和故障恢复。它通过在微服务和它们之间的通信渠道上增加一层抽象,帮助开发者专注于业务逻辑,而将通信和基础设施相关的复杂问题交给服务网格来处理。具体如下图所示:

服务网格的基本组成包括两个重要组件:
-
数据面(Data Plane):
数据面是服务网格的核心,它通过“Sidecar”代理的形式部署在每个微服务实例旁边,用于处理服务间的流量。每个微服务实例都会有一个 sidecar 代理,负责拦截进出服务的所有流量,并在代理中执行如负载均衡、流量管理、熔断、日志记录、指标收集等任务。- Sidecar Proxy:它是数据面的核心组成部分,作为每个服务的代理,处理所有网络通信。典型的 sidecar 代理是 Envoy,它能够拦截和处理服务之间的所有请求。
-
控制面(Control Plane):
控制面负责管理和配置服务网格的数据面。它提供了对流量管理、服务发现、配置和策略执行的控制。控制面协调 sidecar 代理的配置,通常包括健康检查、流量路由、熔断策略等。
相关文章:
软件架构:从传统单体到现代微服务的技术演变
1.引言 在软件开发中,架构设计不仅仅是程序员的技术任务,它更是一个项目成功的关键。无论是小型应用还是大型分布式系统,软件架构都直接影响着系统的可维护性、可扩展性、性能和稳定性。理解软件架构的必要性,能够帮助开发人员做…...
git新建远程分支后,无法切换
git remote # 列出所有远程主机 git remote update origin --prune # 更新远程主机origin 整理分支 git branch -r # 列出远程分支 git branch -vv # 查看本地分支和远程分支对应关系 git checkout -b gpf origin/gpf # 新建本地分支gpf与远程gpf分支相关…...
【SpringBoot】31 Session + Redis 实战
Gitee https://gitee.com/Lin_DH/system 介绍 【SpringBoot】30 Cookie、Session、Token https://blog.csdn.net/weixin_44088274/article/details/144241595 背景 Spring Session 是 Spring 的一个子项目,它提供了一种管理用户会话信息的方法,无论…...
在Windows环境下的rknn-toolkit环境搭建
首先安装好conda,我是用的是anaconda,miniconda也可以。 下载rknn_toolkit的轮子。可以直接在瑞芯微的git仓库中下载,地址为:github.com/rockchip-linux/rknn-toolkit/releases。我这里下载的是1.7.5版本的。选择rknn-toolkit-v1.…...
Facebook广告突然无消耗?原因解析与解决方案。
在Facebook广告投放中,广告突然无消耗是很多广告主都会遇到的难题。这种情况不仅浪费时间,还可能导致营销活动停滞,影响业务发展。那么,广告无消耗的原因是什么?又该如何解决呢? 一、Facebook广告无消耗的…...
Rabbitmq 镜像队列
RabbitMQ 支持高可用性队列(HA Queues),可以在多个节点之间复制队列,确保即使某个节点失败,消息仍然可用。将 RabbitMQ 部署为集群,确保高可用性和负载均衡。 RabbitMQ 的镜像队列集群(Mirrore…...
TensorBoard
1、TensorFlow的TensorBoard TensorBoard是TensorFlow的一个组件,它提供了一个交互式的界面,用于可视化TensorFlow程序的训练过程和模型结构。 使用TensorBoard,你可以: 可视化训练过程中的各种指标,如损失函数、准…...
运维实战:K8s 上的 Doris 高可用集群最佳实践
今天我们将深入探讨::如何在 K8s 集群上部署 Compute storage coupled(存算耦合) 模式的 Doris 高可用集群? 本文,我将为您提供一份全面的实战指南,逐步引导您完成以下关键任务: 配…...
2024.12.5——攻防世界Training-WWW-Robots攻防世界baby_web
2024.12.5—攻防世界Training-WWW-Robots 知识点:robots协议 dirsearch工具 本题与第一道Robots协议十分类似,不做wp解析 大致步骤: step 1 打开靶机,发现是robots协议相关 step 2 用dirsearch进行扫描目录 step 3 url传参r…...
当 Nginx 出现连接超时问题,如何排查?
文章目录 当 Nginx 出现连接超时问题,如何排查? 一、了解 Nginx 连接超时的基本概念二、可能导致 Nginx 连接超时的原因 (一)服务器负载过高(二)上游服务响应缓慢(三)网络问题&…...
vue2 项目中实现动态代理,服务器上通过nginx部署 实现动态代理
一、前言&&原理 前言:vue2 项目中,请求接口是从表格的当前获取的,也就是接口ip:端口号:路经不确定,要实现点击表格当前行请求对应的接口 实现原理:将实际要请求的ip等信息存在请求头中,用的时候再…...
基于SpringBoot+Vue的民宿山庄农家乐管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
【数据分享】1901-2023年我国省市县三级逐年最低气温数据(Shp/Excel格式)
之前我们分享过1901-2023年1km分辨率逐月最低气温栅格数据和Excel和Shp格式的省市县三级逐月最低气温数据,原始的逐月最低气温栅格数据来源于彭守璋学者在国家青藏高原科学数据中心平台上分享的数据!基于逐月栅格数据我们采用求年平均值的方法得到逐年最…...
后端API接口设计标准(Java)
Controller 层(API接口) 无论是传统的三层架构还是现在的COLA架构,Controller 层依旧有一席之地,说明他的必要性;说它是配角是因为 Controller 层的代码一般是不负责具体的逻辑业务逻辑实现,但是它负责接收…...
网络安全法 -网络信息安全
第四章 网络信息安全 第四十条 网络运营者应当对其收集的用户信息严格保密,并建立健全用户信息保护制度。 第四十一条 网络运营者收集、使用个人信息,应当遵循合法、正当、必要的原则,公开收集、使用规则,明示收集、使用信息的…...
matlab figure函数 single 数据类型
1.matlab figure函数详细介绍 在MATLAB中,figure函数用于创建新的图形窗口或激活现有的图形窗口。以下是figure函数的详细介绍和用法: 基本用法 创建新图形窗口:不带任何参数调用figure会创建一个新的图形窗口,并将其设为当前活…...
endroid/qr-code生成二维码,中文乱码的解决方案
endroid/qr-code version:6.0.3 默认不支持中文; 1、https://fonts.google.com/noto/fonts,从这里下载字体; 2、下载简体中文:Noto Sans Simplified Chinese 3、下载后,把压缩包解压,把NotoSansSC-Regul…...
深度和法线纹理
屏幕后期处理效果的基本原理就是当游戏画面渲染完毕后通过获取到该画面的信息进行额外的效果处理 之前的边缘检测、高斯模糊、Bloom、运动模糊等效果都是基于获取当前屏幕图像中的像素信息进行后期处理的 如果仅仅根据像素信息来进行一些效果处理,存在以下问题&…...
监听H5页面在微信浏览器异常退出
参考文章 onBeforeUnmount(() > {unNormalExit(); });//---------------------------异常退出---------------------- function unNormalExit() {enterOrExitRoom({type: 37,roomId: roomId.value,userId: userId.value,nickName: name.value,loginUserType: 2, //0 专家 1…...
Linux 串口编程
目录 前言一、tty体系二、串口硬件基础知识三、Linux下的串口编程3.1 打开串口3.2 从串口读写数据,问题1、2的诞生3.3 关闭串口3.4 串口配置3.4.1 获取/设置串口的参数3.4.2 设置波特率3.4.3 设置控制模式标志3.4.4 设置本地模式标志3.4.5 设置输入模式标志3.4.6 设置输出模式标…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
