架构--以及喷人
最近看了一个比较贴合我心意的言论。
复杂度不会消失,复杂度只会转移。
有人会产生一种错觉,就是仿佛通过“技术”手段,可以让一些功能实现变得简单,让一些风险变得“可控”。
之所以我说这是错觉,在业务逻辑没有问题的前提下,类似看起来很厉害的操作其实是在某种程度上逃避了项目环节里自己本应面对的细节。
这种很厉害的人,选择了做一个咸鱼。
所以为什么微服务是好的
之所以微服务给人一种积极向上的感觉,是因为这个东西从本质上承认了一个事情:一整套服务环境的开发者,就是需要去关心每个节点的交互逻辑/负载设计/整体效果等等内容。并主动分担了运维部门的职责。
- 对API效果负责,引入限流和熔断
- 对整个网络出口和业务组织方式负责,Gateway注册中心
- 对持久的监控和治理负责,各种monitor
- etc.
以上这些东西,的确一些事传统运维的范畴。但是当复杂度和开发内容不再可分,那就没有必要再强行拆分,直面问题找到最合适的解决方案才是正途。
所以某种程度上,微服务架构下测试部门再也没法对全流程的测试效果负责。也就是说测试结果其实也就是对当前这个测试环境的效果负责。测试环境五个节点的压测结果和线上五十个节点的同样一份代码,面对的问题完全不一样。
BTW这也是为什么我觉得某些“QA全权负责test环境”的傻逼言论完全不值得一辩,因为复杂度放在了开发部门,那么QA本就无须对复杂度负责,对交付的环境以及可行性负责即可。
所以什么叫架构
所以架构——我的理解——本质上就是处理复杂度和易变性交杂的问题。我们需要把不变的和易变的模块拆开以便于迭代,同时不能让复杂度变形(把复杂度归属在不合理的位置)。
例如一个交易的模块,订单结算流水这些就属于是不易变的东西,折扣规则,以及折扣对应的一众业务就是复杂度高且易变的模块。把计算折扣的逻辑放进结算的模块就是一个不能说是傻逼吧也差不多的操作。因为订单原本很稳定的整个流程因为介入了折扣的逻辑变得需要经常迭代了。
所以,为什么Lambda(仅仅说的是aws的server)是好的。因为它从某种程度上制造了让开发人员思考复杂度和易变性的空间,以及进行拆分实践的可能性,并在此基础上隐没了改造的复杂度(变成了服务费)。
所以functional programming而且强制module-oriented,这不美好么,没有什么比这更美好了。
当然也有睿智写Lambda也能写成一坨屎,不做讨论。
同时,隐没和暴露也是一门经验科学。本质上来说设计模式就是研究如何暴露易变形并且隐匿复杂度的经验科学。但这并不意味着复杂度转移,设计模式告诉了你如何把复杂的逻辑变为不易变的,并让易变的代码逻辑以接口的形式暴露出来。由此良好的接口暴露可以让后续的迭代更加的稳定,因为根本不会触及复杂度更高的那部分的代码改动。
回到交易模块的设计,理想状态下coupon模块就应该给结算暴露一个万年不变的API,返回归置好的计算结果。
那么反例或者说我想喷的是什么呢,是所谓的低代码平台。
喷
以之前的论断,如果有人反着来,把复杂度高的逻辑暴露,把复杂度低的程序固化,理论上就是放任何人没法忍受的事情,然后还真的有人做了,让人在网页上写代码,仅仅是无法或者懒得去抽象流程拆分复杂度。
这就是明显前文提到的,用一些高级的说辞,假装用技术手段抹消了复杂度,并且逃避了程序员最基本的职责:抽象,把人的职责给UI并把计算存储的职责给CPU或storage。只是自顾自的选择了做自己喜欢做的事情,不喜欢的推脱掉了。
低代码的东西并不是一个新的东西,比如excel里的公式,也许在哪里excel也是集成了什么语言的编译器可以写点什么脚本。但是恕我想象力有限,在web上放个textarea让用户自己写代码这种操作有什么值得吹嘘的点我是真的想象不出来。怎么,哪天ms把excel砍掉直接让对接access是很好吹是吗,是什么很伟大的发明么。
所以为什么我讨厌 Triggers or stored procedure or materialized view
总会有一些trigger的逻辑需要面对的。比如我需要做一些轻量级的汇总,或者轻量级的事物。但是本质上,这种操作是把易变的业务复杂度置于了本应不那么易变的DB上。
DB提供了各个处理阶段的触发器,我并不反对用类似的功能做一些小的数据上的修补。但是在面对一些整体的,流程性的项目中,把业务逻辑一股脑的放进trigger在我看来也是一种不负责的态度。
仅仅就ETL的流程来说,流程关注触发的时间以及每个JOB的触发时机或者先后顺序,以及每个JOB里的计算逻辑,他们即复杂又易变。把整个流程绑上DB的trigger chain或者说 materialized view chain 就必然遇到调度不再符合需求,并在无尽的迭代中流程失控。
这个结论也不是我的臆想,早在2015年左右,我知道有大批的公司执用着 mySQL stored procedure,在后续迭代中,也许是分库分表,也许是业务演进,痛苦的剥离掉stored procedure的逻辑转向了纯代码实现,而stored procedure引入只是在某个可做可不做的时候不那么严谨的就引入了。
然而在我做数据开发了之后 clickhouse的使用者无节制的使用materialized view 并自豪的称之为materialized view chain,我不明白有什么好自鸣得意。不论是流式的看待还是批量的看待,我都不觉得这是个好方案。
当然这部分也未可知,我只是在看着我司用各种视图串起来ETL的架构图前,看到了历史相似的部分。发一下牢骚。也许最终,这就是最好的方案了呢?呵呵。
