分布式软件架构——单体架构

news2024/11/25 2:26:02

序言

当一项大工程需要大量人员共同开发,并保证它们分布在网络中的大量服务器节点能够同时运行,那么随着项目规模的增大、运行时间变长,它必然会受到墨菲定律的无情打击。

Murphy’s Law:Anything that can go wrong will go wrong.
墨菲定律:凡事只要又可能出错,那就一定会出错。

为了得到高质量的软件产品,我们应该把精力更多地集中在提升开发人员能力,还是放在整体流程和架构上。
两者都重要,前者重术,后者重道。前者是开发者个体水平决定,后者由技术决策者水平决定。

架构并不是被“发明”出来的,而是持续进化的结果。

springboot中的单体分层架构可以下载gitclone中的项目参考
git clone https://gitclone.com/github.com/fenixsoft/monolithic_arch_springboot

在这里插入图片描述
下载好后可以用docker启动该项目或者直接运行BookStoreApplication,然后在浏览器访问:http://localhost:8080,系统预置了一个用户(user:icyfenix,pw:123456),也可以注册新用户来测试了。注意我这次运行是由于jekenis占用了8080端口,可以修改jekenis的端口或者该项目端口。

运行docker时,输入命令docker version默认输出docker版本信息,包含客户端和服务端两个部分,下面是客户端部分,参考Docker version 命令
在这里插入图片描述

大型单体系统

单体架构是绝大部分软件开发者都学习和实践过的一种软件架构,许多介绍微服务的书籍和技术资料中也常把这种架构风格的应用称作“巨石系统”(Monolithic Application)。
“单体架构”在整个软件架构演进的历史进程里,是出现时间最早、应用范围最广、使用人数最多、统治历史最长的一种架构风格,但“单体”这个名称,却是在微服务开始流行之后才“事后追认”所形成的概念。此前,并没有多少人将“单体”视作一种架构来看待,如果你去查找软件架构的开发资料,可以轻而易举地找出大量以微服务为主题的书籍和文章,却很难找出专门教你如何开发单体系统的任何形式的材料,这一方面体现了单体架构本身的简单性,另一方面,也体现出在相当长的时间尺度里,大家都已经习惯了软件架构就应该是单体这种样子。

剖析单体架构之前,我们有必要先厘清一个概念误区,许多微服务的资料里,单体系统往往是以“反派角色”的身份登场的,譬如著名的微服务入门书《微服务架构设计模式》,第一章的名字就是“逃离单体的地狱”。这些材料所讲的单体系统,其实都是有一个没有明说的隐含定语:“大型的单体系统”。对于小型系统——即由单台机器就足以支撑其良好运行的系统,单体不仅易于开发、易于测试、易于部署,且由于系统中各个功能、模块、方法的调用过程都是进程内调用,不会发生进程间通信(Inter-Process Communication,IPC。广义上讲,可以认为 RPC 属于 IPC 的一种特例,但请注意这里两个“PC”不是同个单词的缩写),因此也是运行效率最高的一种架构风格,完全不应该被贴上“反派角色”的标签,反倒是那些爱赶技术潮流却不顾需求现状的微服务吹捧者更像是个反派。

进程间通讯:Inter-Process Communication,IPC。RPC(Remote Procedure Call,远程过程调用) 属于 IPC 的一种特例。

单体系统的不足,必须基于软件的性能需求超过了单机,软件的开发人员规模明显超过了“2 Pizza Team”范畴的前提下才有讨论的价值,因此,本文后续讨论中所说的单体,均应该是特指“大型的单体系统”,也正因如此,本节中说到“单体是出现最早的架构风格”,与上一节介绍原始分布式时代开篇提到的“使用多个独立的分布式服务共同构建一个更大型系统的设想与实际尝试,反而要比今天大家所了解的大型单体系统出现的时间更早”实际并无矛盾。

可拆分的单体系统

单体系统
Monolith means composed all in one piece. The Monolithic application describes a single-tiered software application in which different components combined into a single program from a single platform.
—— Monolithic Application, Wikipedia
“单体”只是表明系统中主要的过程调用都是进程内调用,不会发生进程间通信,仅此而已。

单体系统在维基百科的定义是“All in One Piece”,翻译成“铁板一块”,其实更接近于自给自足(Self-Contained)的含义。

  • 纵向角度
    分层架构(Layered Architecture)已经是现在几乎所有的信息系统建设中,都普遍认可、普遍采用的软件设计方法了。无论是单体还是微服务,或者是其他架构风格,都会对代码进行纵向拆分,收到的外部请求会在各层之间,以不同形式的数据结构进行流转传递,在触及到最末端的数据库后依次返回响应。
    Software Architecture Patterns

  • 横向角度
    单体架构也可以支持按照技术、功能、职责等角度,把软件拆分为各种模块,以便重用和团队管理。
    负载均衡器之后,同时部署若干个单体系统的副本,以达到分摊流量压力的效果,那么基于单体架构,也是轻而易举就可以实现的。

非独立的单体

不过,在“拆分”这方面,单体系统的真正缺陷实际上并不在于要如何拆分,而在于拆分之后,它会存在隔离与自治能力上的欠缺。

在单体架构中,所有的代码都运行在同一个进程空间之内,所有模块、方法的调用也都不需要考虑网络分区、对象复制这些麻烦事儿,也不担心因为数据交换而造成性能的损失。可是,在获得了进程内调用的简单、高效这些好处的同时,也就意味着,如果在单体架构中,有任何一部分的代码出现了缺陷,过度消耗进程空间内的公共资源,那所造成的影响就是全局性的、难以隔离的。

一旦架构中出现了内存泄漏、线程爆炸、阻塞、死循环等问题,就都将会影响到整个程序的运行,而不仅仅是某一个功能、模块本身的正常运作;而如果消耗的是某些更高层次的公共资源,比如端口占用过多或者数据库连接池泄漏,还将会波及到整台机器,甚至是集群中其他单体副本的正常工作。

因为所有代码都共享着同一个进程空间,如果代码无法隔离,那也就意味着,我们无法做到单独停止、更新、升级某一部分代码,因为不可能有“停掉半个进程,重启 1/4 个进程”这样不合逻辑的操作。所以,从动态可维护性的角度来说,单体系统也是有所不足的,对于程序升级、修改缺陷这样的工作,我们往往需要制定专门的停机更新计划,而且做灰度发布也相对会更加复杂。

由于隔离能力的缺失,除了会带来难以阻断错误传播、不便于动态更新程序的问题,还会给带来难以技术异构等困难。

技术异构
马丁 · 福勒(Martin Fowler)提出微服务的9 个特征,技术异构就是其中之一。它的意思是说允许系统的每个模块,自由选择不一样的程序语言、不一样的编程框架等技术栈去实现。单体系统的技术栈异构不是一定做不到,比如 JNI 就可以让 Java 混用 C/C++,但是这也是很麻烦的事,是迫不得已下的选择。

从根本上看,单体这种架构风格,潜在的观念是希望系统的每一个部件,甚至每一处代码都尽量可靠,不出、少出错误,致力于构筑一个 7×24 小时不间断的可靠系统。 这种观念在小规模软件上能运作良好,但当系统越来越大的时候,交付一个可靠的单体系统就会变得越来越有挑战性。记得一句话,随着代码量越来越庞大,系统的腐化是必然的。

总的来说单体架构的发展以及其优缺点如下图,
在这里插入图片描述

参考链接:
1、https://zhuanlan.zhihu.com/p/575500324
2、《周志明的软件架构课》——极客学院

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/552499.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt文件系统源码分析—第四篇QLockFile

深度 本文主要分析Windows平台,Mac、Linux暂不涉及 本文只分析到Win32 API/Windows Com组件/STL库函数层次,再下层代码不做探究 本文QT版本5.15.2 类关系图 QTemporaryFile继承QFile QFile、QSaveFile继承QFileDevice QFileDevice继承QIODevice Q…

法规标准-ISO 17361标准解读

ISO 17361是做什么的? ISO 17361全称为智能交通系统-车道偏离警告系统性能要求和测试程序,其中主要描述了LDWS系统的功能要求及测试要求 系统功能 车道偏离警告系统的功能元件应符合图中的要求,抑制请求、车速检测、驾驶员偏好和其他附加功…

[CTF/网络安全] 攻防世界 simple_js 解题详析

[CTF/网络安全] 攻防世界 simple_js 解题详析 代码分析代码漏洞姿势String[fromCharCode]总结 题目描述:小宁发现了一个网页,但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} ) 页面源代码: 代码分析 function dechiffre(pass_enc){…

StarRocks 集群模式搭建

一、StarRocks 集群模型搭建 上篇文章对 StarRocks 进行了简单的介绍及使用 Docker 进行了快速体验,本篇文章进行StarRocks 集群模型的搭建,下面是上篇文章的地址: StarRocks 极速全场景 MPP 数据库介绍及使用 部署规划 host主机名角色192.…

求解包含约束的最优化问题:拉格朗日乘子法和KKT条件

文章目录 无约束等式约束不等式约束KKT条件 无约束 之前梯度类算法中介绍的最速下降法、牛顿法和拟牛顿法,可以直接使用的条件之一为:决策变量都是无约束的。 用数学语言描述的话,可以表达为:决策变量为 x ( x 1 , x 2 , ⋅ ⋅…

LeetCode104. 二叉树的最大深度(递归非递归)

写在前面: 题目链接:LeetCode104.二叉树的最大深度 编程语言:C 题目难度:简单 一、题目描述 给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子…

You Only Look Once:Unified,Real-Time Object Detection总结笔记

一、论文思想 1.将一个图像分成S*S个网格(grid cell),如果某个object的中心落在这个网格中,则这个网络就负责预测这个object。 2.每个网格要预测B个bounding box,每个bounding box除了要预测位置之外,还要…

微服务技术(SpringCloud、Docker、RabbitMQ)

目录 一、微服务技术简介 二、服务拆分及远程调用 1.Eureka注册中心 2.Nacos注册中心 3.Nacos配置管理 4.http客户端Feign 三、统一网关Gateway 四、Docker 五、异步通信技术 六、ElasticSearch 一、微服务技术简介 微服务是分布式架构(分布式&#xff…

Lesson14---卷积神经网络

14.1 深度学习基础 14.1.1 深度学习的基本思想 特征工程:尽可能选择和构建出好的特征,使得机器学习算法能够达到最佳性能。是机器学习的上限,而算法就是逼近这个上限传统的机器学习特证工程 依靠人工方式提取和设计特征需要大量的专业知识…

低代码系统前端实践之vue-element-admin运行demo

文章目录 1、简介2、实践功能3、实践过程3.0 下载运行demo3.1.1 解决执行npm install或出现以下报错(删掉组件tui-editor相关即可)3.1.2 解决执行npm run dev或出现no module body-parser(安装body-parser即可)3.1.3 解决执行npm run dev或出现error:0308010C:digital envelope…

RK3568平台开发系列讲解(驱动基础篇)RK平台I2C的使用

🚀返回专栏总目录 文章目录 一、I2C 使用情况二、定义和注册 I2C 设备三、定义和注册 I2C 驱动3.1 I2C 驱动定义3.2 I2C 驱动注册3.3 通过 I2C 收发数据沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将对RK I2C 的使用进行学习。 配置 I2C 可分为两大步骤: 定…

【Linux C】GCC编译 GDB调试 从入门到放弃 (gcc调试选项详解、gdb调试、条件断点、远程调试、脚本化调试)

阅读本文可能需要一些基础,比如:C语言基础、Linux基础操作、vim、防火墙等。篇幅有限,本文讲的“比较浅显”。 通过本文你将学会: gcc编译gdb调试 少年你渴望力量吗👇👇👇 一、使用GCC编译C程序…

Antd 下拉面板的位置计算错误

项目场景: 公司使用无界微前端集成ERP项目应用(可惜没跟着走一边无界,难受),某些子应用使用时,发现antd的弹窗弹出的位置不对。如下图: 问题描述 无界微前端嵌入的子应用中的antd的下拉框位置…

【谷粒商城笔记】基于docker的mysql、redis环境配置

0.系统 宝塔 v7.5.1 Centos v8.2 1. 安装Docker 直接yum install docker会提示找不到 > docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine Loaded plugins: fastestmirror No Match for argument: …

Prometheus如何优化远程读写的性能

Prometheus如何优化远程读写的性能 场景 为了解决prometheus本地存储带来的单点问题,我们一般在高可用监控架构中会使用远程存储,并通过配置prometheus的remote_write和remote_read来对接 远程写优化:remote_write 用户可以在Prometheus配…

码上行动:零基础学会Python编程(文末送书)

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

Day3 字符串中找出连续最长的数字串、数组中出现次数超过一半的数字

✨个人主页: 北 海 🎉所属专栏: C/C相关题解 🎃操作环境: Visual Studio 2019 版本 16.11.17 文章目录 选择题1、进程管理2、计算机组成原理 编程题1、字符串中找出连续最长的数字串2、数组中出现次数超过一半的数字 选…

和数组处理有关的一些OJ题;ArrayList 实现简单的洗牌算法(JAVA)(ArrayList)

接上次博客:数据结构初阶(2)(ArrayList简介、ArrayList()的构造方法、ArrayList的扩容、方法和三种遍历方法、ArrayList实现杨辉三角、ArrayList 的优缺点)_di-Dora的博客-CSDN博客 1、给你一个数组 nums 和一个值 va…

FreeRTOS(6)----软件定时器

一,软件定时器概述 软件定时器允许设置一段时间,当设定的时间到达之后就会执行指定的功能函数,被定时器调用的这个函数叫做定时器的回调函数。回调函数的两次执行间隔叫做定时器的定时周期。 二,回调函数的注意事项 回调函数是…

Linux文件权限管理

1、Linux权限介绍 权限管理,其实就是指对不同的用户,设置不同的文件访问权限。 Linux 系统,最常见的文件权限有 3 种,即对文件的读(用 r 表示)、写(用 w 表示)和执行(用…