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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

相关文章

Django项目使用vue打包前端页面使用教程

一、vue打包: 一般使用 npm run build 进行打包,打包完成后会生成一个dist文件夹 二、修改vue.config.js配置 vue.config..js配置里面增加: assetsDir: static 三、修改Django项目 将Django的static文件夹删除,移动di…

【Go 快速入门】协程 | 通道 | select 多路复用 | sync 包

文章目录 前言协程goroutine 调度使用 goroutine 通道无缓冲通道有缓冲通道单向通道 select 多路复用syncsync.WaitGroupsync.Mutexsync.RWMutexsync.Oncesync.Map 项目代码地址:05-GoroutineChannelSync 前言 Go 1.22 版本于不久前推出,更新的新特性可…

雾锁王国服务器配置怎么选择?阿里云和腾讯云

雾锁王国/Enshrouded服务器CPU内存配置如何选择?阿里云服务器网aliyunfuwuqi.com建议选择8核32G配置,支持4人玩家畅玩,自带10M公网带宽,1个月90元,3个月271元,幻兽帕鲁服务器申请页面 https://t.aliyun.com…

Firefox Focus,一个 “专注“ 的浏览器

近期才开始使用 Firefox Focus,虽然使用频率其实并不高,基本上只有想到了才去用,但每次使用的体验都很不错。 Firefox Focus 这款浏览器大约在 2015 年首次发布,不同于一般版本的 Firefox,它主打“自动删除浏览记录”…

Python请求示例获取淘宝商品详情数据API接口,item_get-获得淘宝商品详情(按关键词搜索商品列表)

请求示例,API接口接入Anzexi58 item_get-获得淘宝商品详情 公共参数 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥WeChat18305163218api_nameString是API接口名称(包括在请求地址中&am…

阅读笔记——《GANFuzz: A GAN-based industrial network protocol fuzzing framework》

【参考文献】Hu Z, Shi J, Huang Y H, et al. GANFuzz: a GAN-based industrial network protocol fuzzing framework[C]//Proceedings of the 15th ACM International Conference on Computing Frontiers. 2018: 138-145.【注】本文仅为作者个人学习笔记,如有冒犯&…

66-ES6:var,let,const,函数的声明方式,函数参数,剩余函数,延展操作符,严格模式

1.JavaScript语言的执行流程 编译阶段:构建执行函数;执行阶段:代码依次执行 2.代码块:{ } 3.变量声明方式var 有声明提升,允许重复声明,声明函数级作用域 访问:声明后访问都是正常的&…

ElasticSearch之找到乔丹的空中大灌篮电影

写在前面 本文看一个搜索的实际例子,找到篮球之神乔丹的电影Space Jam,即空中大灌篮。 正式开始之前先来看下要查询的目标文档,以及查询的text: 要查询的目标文档 {..."title": "Space Jam",..."ove…

密码学系列(四)——对称密码2

一、RC4 RC4(Rivest Cipher 4)是一种对称流密码算法,由Ron Rivest于1987年设计。它以其简单性和高速性而闻名,并广泛应用于网络通信和安全协议中。下面是对RC4的详细介绍: 密钥长度: RC4的密钥长度可变&am…

数据结构:栈和队列与栈实现队列(C语言版)

目录 前言 1.栈 1.1 栈的概念及结构 1.2 栈的底层数据结构选择 1.2 数据结构设计代码(栈的实现) 1.3 接口函数实现代码 (1)初始化栈 (2)销毁栈 (3)压栈 (4&…

Unity(第九部)物体类

拿到物体的某些数据 using System.Collections; using System.Collections.Generic; using UnityEngine;public class game : MonoBehaviour {// Start is called before the first frame updatevoid Start(){//拿到当前脚本所挂载的游戏物体//GameObject go this.gameObject;…

踩坑wow.js 和animate.css一起使用没有效果

踩坑wow.js 和animate.css一起使用没有效果 问题及解决方法一、电脑系统配置问题二、版本问题 问题及解决方法 一、电脑系统配置问题 在系统属性里面把窗口内的动画和元素勾选 二、版本问题 使用wow加animate4.4.1也就是最新本,打开网页没有任何动画效果 但是把…

CSS——PostCSS简介

文章目录 PostCSS是什么postCSS的优点补充:polyfill补充:Stylelint PostCSS架构概述工作流程PostCSS解析方法PostCSS解析流程 PostCSS插件插件的使用控制类插件包类插件未来的CSS语法相关插件后备措施相关插件语言扩展相关插件颜色相关组件图片和字体相关…

45、上海大学:轻量级多特征神经网络M-FANet,用于MI-BCI解码

本文由上海大学机电工程与自动化学院于2024.1.9日发表于《IEEE Transactions on Neural Systems and Rehabilitation Engineering》(SCI中科院分区二区,IF:4.9) 论文链接:M-FANet: Multi-Feature Attention Convolutional Neural Network fo…

数据结构--二叉排序树(Binary Search Tree,简称BST)

这里写自定义目录标题 二叉排序树二叉排序树与排序数组没有排序数组,链式存储链表的对比二叉排序树概念对于搜索操作,对于插入操作,对于删除操作, 分析删除节点代码运行结果 二叉排序树 二叉排序树与排序数组没有排序数组&#x…

【React源码 - 调度任务循环EventLoop】

我们知道在React中有4个核心包、2个关键循环。而React正是在这4个核心包中运行,从输入到输出渲染到web端,主要流程可简单分为一下4步:如下图,本文主要是介绍两大循环中的任务调度循环。 4个核心包: react:…

SpringMVC了解

1.springMVC概述 Spring MVC(Model-View-Controller)是基于 Java 的 Web 应用程序框架,用于开发 Web 应用程序。它通过将应用程序分为模型(Model)、视图(View)和控制器(Controller&a…

SpringMVC 学习(八)之文件上传与下载

目录 1 文件上传 2 文件下载 1 文件上传 SpringMVC 对文件的上传做了很好的封装,提供了两种解析器。 CommonsMultipartResolver:兼容性较好,可以兼容 Servlet3.0 之前的版本,但是它依赖了 commons-fileupload …

kubectl 命令行管理K8S(上)

目录 陈述式资源管理方式 介绍 命令 项目的生命周期 创建 kubectl create命令 发布 kubectl expose命令 更新 kubectl set 回滚 kubectl rollout 删除 kubectl delete 应用发布策略 金丝雀发布 陈述式资源管理方式 介绍 1.kubernetes 集群管理集群资源…

python 基础知识点(蓝桥杯python科目个人复习计划53)

今日复习内容:做题 例题1:最大的卡牌价值 问题描述: 给定n副卡牌,每张卡牌具有正反面,正面朝上数字为ai,背面朝上数字为bi。一副卡牌的价值为正面朝上数字之和,一开始所有卡牌都是正面朝上的…