【架构笔记1】剃刀思维-如无必要,勿增实体

欢迎来到文思源想的架构空间,前段时间博主做了一个工作经历复盘,10年开发路,走了不少弯路,也算积累了不少软件开发、架构设计的经验和心得,确实有必要好好盘一盘,作为个人的总结,同时也留给有缘读过的人,带给一丝启发或者少走一点坑,都是好事。于是有了这个文思架构笔记这个专题的想法,未来会陆陆续续梳理一些自己总结的东西和正在发生的事情,作为留存,也作为纪念。今天是第一篇——关于剃刀思维!

“如无必要,勿增实体” ,这句话来自奥卡姆剃刀原理的核心说明,针对云服务架构它也是非常必要。老子说大道至简,亚里士多德说自然界选择最短的道路,产品交互设计也有个理念叫less is more -- 少即是多。它不只是告诉人们要做减法,而是更多去思考我们实现功能外引入新的复杂度和问题,充分考虑和权衡。

在云服务架构演进中我们看到了许多演进共同的现象,为了多活我们引入了多活控制器,为了一个新增业务避免老功能受到影响,采用新增服务的方式隔离变化,为了调用尽量少的改动,我们将一个请求扩充到五六跳甚至更多。但是做法却同时也带了一些新的影响:

  • 首先服务调用链路更长了,这引入了更高的服务治理复杂度,我们不再是简单几跳解决一个请求,而是更多的中转也带了更多定位问题的复杂性,功能实现或许改动小了,但是未来压测、定位复杂问题更多了。
  • 其次引入新服务和模块,拆分微服务,更多的其实应该考虑的是业务的解耦,功能的复用,而不是站在小组的角度,考虑什么好做把几个功能聚合在一起,微服务架构设计虽然必然走向康威定律的方向(组织结构决定代码架构),但是实际上是需要有人做好评审和管控的。新增服务并不一定是好事,这个事情是需要评审和确定的,或者做一做减法,常常问一些新的问题:
    • 如果不要新增,是否能完成功能;
    • 如果新增服务带来哪些运维架构、安全、服务治理的隐患;
    • 是否还有其他更好的解决思路。

接着还有多活这个话题,通常多活在云服务架构里面有多种拆分方式,集群方案和多活控制器,当然采用上游负载均衡hash或者一致性hash找到下游服务的方式,这无疑是最常用的解决思路,但是他的问题也同样多:

  • 服务实体增多,部署复杂度、部署规格要求逐步放大,以前可能一个服务搞定的事情现在可能需要两个或者三个,这里是实打实的成本上升,私有云环境下以前可以四五十核搞定一个环境,而如今不下数百核一个最小系统都不能完备。诚然我们功能在增多、业务在复杂,但是我们每套云的用户数、规模并没有增大到数量翻倍的情况,这里的问题就是引入实体,但是没有做减法,没有定期回顾,看看哪里不合理。
  • 服务发现、服务间通信问题变得更加紧密,定位问题也成为了一个难点,再加上某些开源软件在调用链上的特殊性,导致治理和灰度成为了很棘手的问题。

最后我想到的则是设计和建模中的抽象,通常通过业务场景分析、用户动作行为拆解,我们会在概要设计中产生许多概念,但是落地的时候实际上是需要区分什么是视图层什么是核心层模型的,把变化留在视图层,而核心层模型的定义,我认为是要经过头脑风暴和反复核对的:

  • 把多余属性拆解到极致,去除掉一切冗余字段
  • 反思如何把业务用几句话说清楚,弄清楚关键模型和关键动作,然后还能看到未来的变化,以及未来我们怎么应对变化

虽然他们不全是领域驱动设计,但是也包含了领域驱动的一些思想。分析业务场景时候由少到多,遍历细节,建模归纳时候由多到少,用核心模型、动作,充分裁剪,最后通过考虑特殊情况,补充场景。最后的最后就是问一问能不能少一些实体,少一些不一样的接口,能否复用。

总之,接口、模型、字段、调用、服务、业务他们都是所谓的实体,如无必要勿增实体,我们设计时候就需要考虑这些实体存在的必要性,同时反思是否会带来影响其他必要实体的问题。功能实现简单性只是一个新增的理由,我们更多想想未来治理的代码,部署的复杂性,额外新增的机器和研发消耗更多的精力,以及冗余引起的争议和误会。我们不仅要实现功能,还需考虑业务的解耦,更要考虑实体的熵增。人熵增需要断舍离,软件系统熵增则需要重构,盘点、分析、归纳合并、设计、重构,这个事情是需要持续进行,是需要自上而下倡导,最终最下而上显现。

当然剃刀思维还有一个关键,就是我们有他,但是最好不需要它当一个不需要的实体存在,这个实体就会开始证明自己存在的必要,其他原来必要存在的实体也会因为他的存在而容易自发建立一套与它有关的新协作或者新习惯。老业务会通过新部门形成砍不掉的冗余流程,豆浆机也会在你买菜时候提醒你多买一些吃不完的豆子,这个时候在用剃刀就很难了,剃了就会很疼很受伤,然后就需要权衡有了犹豫。勿增实体而不是剃掉实体,是因为剃刀思维的关键是一开始就找到这些不需要的实体,防患于未然,所以需求评审、架构设计、模型设计、调用流程设计都需要有这样的思考和审核,从一开始就找到这些没有必要存在的实体。

剃刀的真意在于止“繁”存"简" ----心存一刀,只留必要,心中有刀无需用刀,才是最好的状态,或许这是必字的另一种解释,也是我们设计架构的一个需要重视的要诀。

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

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

相关文章

对抗生成网络

作用 手底有一堆数据,告诉它要生成什么东西,它就这么去做。 超分辨率重构 告诉模型什么样的东西是一个低分辨率图像,什么样的东西是高分辨率图像,再设计一个损失函数。让计算机学习两者之间的关系,怎样由一个低分辨率…

2.6基本算法之动态规划1944:吃糖果

名名的妈妈从外地出差回来,带了一盒好吃又精美的巧克力给名名(盒内共有 N 块巧克力,20 > N >0)。妈妈告诉名名每天可以吃一块或者两块巧克力。假设名名每天都吃巧克力,问名名共有多少种不同的吃完巧克力的方案。…

Nginx一网打尽:动静分离、压缩、缓存、黑白名单、跨域、高可用、防盗链、SSL、性能优化

引言 一、性能怪兽-Nginx概念深入浅出 二、Nginx环境搭建 三、Nginx反向代理-负载均衡 四、Nginx动静分离 五、Nginx资源压缩 六、Nginx缓冲区 七、Nginx缓存机制 八、Nginx实现IP黑白名单 九、Nginx跨域配置 十、Nginx防盗链设计 十一、Nginx大文件传输配置 十二、Nginx配置SL…

redis真实使用

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,对相关api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下: ValueOperations:string数据操作 SetOperations:set类型数据操作 …

Flink SQL 中的流式概念:状态算子

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…

动态规划-01背包问题新解(c)

动态规划-01背包问题新解 概述动态规划01背包问题传统思路算法官方递推关系算法2种算法比较 概述 本文将从一个新的角度来描述和实现01背包问题,以协助对01背包问题以及教材上的算法的彻底理解。 新的角度为:传统思路算法,“新”是新在与绝…

【Python】Ubuntu创建虚拟环境运行Python

虚拟环境让项目之间的依赖关系更加清晰,同时也可以避免全局安装的包的版本冲突问题。 在Ubuntu系统上,可以使用Python的内置工具venv来创建虚拟环境。以下是在Ubuntu上创建Python虚拟环境的步骤: 安装Python虚拟环境工具:首先确保…

Maven配置文件忘记更新阿里云的Mavne镜像的最新地址

最近更新最新版的IDEA,打开旧的工作空间,发现以前Spring相关项目全部报错并无法运行。 单元测试发现无法识别XML配置文件路径,同时提示各种异常 异常一 org.springframework.beans.factory.BeanDefinitionStoreException: IOException par…

10W 音频功率放大电路芯片TDA2003,可用于汽车收音机及收录机中作音频功率放大器,内部具有短路保护和过热保护等功能

TDA2003 用于汽车收音机及收录机中作音频功率放大器。 采用 TO220B5 封装形式。 主要特点: ⚫ 内部具有短路保护和过热保护。内部具有地线开路、电源极性接 反和负载泄放电压反冲等保护电路。 ⚫ 输出电流大。 ⚫ 负载电阻可低至 1.6 。 …

[C++]C/C++ Socket设置非阻塞模式接收超时时间的多种方法

网络编程中经常需要处理的一个问题就是如何正确地处理Socket超时,对于C/C,有几种常用的技术可以用来设置Socket接收超时时间,在这篇文章中,我们将详细介绍如何在C/C中设置Socket的非阻塞模式以及如何配置接收超时时间,需要的朋友可以参考下 C/C Socket设置非阻塞模式接收超时时…

LeetCode 刷题 [C++] 第141题.环形链表

题目描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&a…

STC-ISP原厂代码研究之 V3.7d汇编版本

最近在研究STC的ISP程序,用来做一个上位机烧录软件,逆向了上位机软件,有些地方始终没看明白,因此尝试读取它的ISP代码,但是没有读取成功。应该是目前的芯片架构已经将引导代码放入在了单独的存储块中,而这存储块有硬件级的使能线,在面包板社区-宏晶STC单片机的ISP的BIN文…

uniapp的动态表单实现

目录 1.说明 2.示例 3.总结 1.说明 ①在 formData 中定义个数组变量用来接受同一个字段的多个结果。 dynamicFormData: {email: ,// domains 字段下会有多个结果domains: [] }②使用 uni-forms-item 的 rules 属性定义单个表单域的校验规则。 <uni-forms-item :label&qu…

matlab绘制雷达图和二维FFT变换图

1、内容简介 略 49-可以交流、咨询、答疑 matlab绘制雷达图和二维FFT变换图 NMO组及NORMAL组 RNFL层、GCL层、IPL层、GCC层、ORL层做雷达图&#xff08;共10张&#xff09; 2、内容说明 略 NMO组及NORMAL组 RNFL层、GCL层、IPL层、GCC层、ORL层请分别做雷达图&#xff08…

每日OJ题_分治快排③_力扣215. 数组中的第K个最大元素

目录 力扣215. 数组中的第K个最大元素 解析代码 力扣215. 数组中的第K个最大元素 215. 数组中的第K个最大元素 难度 中等 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xf…

【学习笔记】SOA服务设计原则(二)举例说明

以银行系统为例 背景 在线银行系统允许用户进行各种银行业务,如查看账户余额、转账、支付账单等。为了支持这些功能,系统需要与账户管理、交易处理、账单支付等多个不同的服务进行交互。 应用SOA设计基本原则 标准化服务合约(Standardized Service Contract) 例子:所有服…

VAST Data步步攀升,整合AI堆栈,打造一体化AI平台:从存储根基走向全方位数据处理与分析

VAST Data公司正逐步从其商品化存储基础出发&#xff0c;构建一套统一的AI堆栈系统&#xff0c;致力于提供一站式AI解决方案。最近&#xff0c;VAST公司的现场CTO安迪珀斯坦纳在一次简报中传达了这一战略方向。 VAST提供了分散式QLC单层闪存架构的并行、横向扩展文件型存储系统…

kotlin与java的相互转换

Kotlin转java 将kotlin代码反编译成java Tools -> Kotlin -> Show Kotlin Bytecode 然后点击 【Decompile】 生成java代码 java转kotlin Code -> Convert Java File To Kotlin File

Docker数据管理及网络通信

目录 ------------------Docker 的数据管理--------------------- 1&#xff0e;数据卷 2&#xff0e;数据卷容器 -----------------端口映射----------------------------------- ------------------容器互联&#xff08;使用centos镜像&#xff09;---------------------…

科技论文编写思路

科技论文编写思路 1.基本框架2.课题可行性评估1.研究目标和意义2.研究方法和技术3.可行性和可操作性4.风险和不确定性5.经济性和资源投入6.成果预期和评估 3.写作思路4.利用AI读论文5.实验流程 1.基本框架 IntroductionRelated worksMethodExperiment and analysisDiscussionC…