我也曾对架构师的力量一无所知
本文源于一本书《我也曾对那种力量一无所知》有感。没错,就是致敬韩寒的那篇《我也曾对那种力量一无所知》。全文主旨就是业余玩家自嗨可以,但千万别狂妄到企图挑衅专业选手。否则,下场就和当初的 松江新区·奥沙利文·韩寒 一样,在潘晓婷面前只有开球的份儿。韩寒成名于新概念作文,而后不断开挂,在作家、赛车手、导演等多个角色上都游刃有余且扮演的相当成功,如此色彩斑斓的人生一直让我艳羡不已。
而我,一介码农,初时随波逐流,醒时已亦步亦趋在架构之路上,艰苦非常。
因为,架构师的力量,我也曾一无所知。
— 1—代码执念
每个程序员对美的代码的认知不尽相同,但大多有个共识,那就是,架构师设定的各种条条框框简直是对美的亵渎!
其实,你可能对架构师的执念一无所知!
表面看到的:架构师成天没事找事,发布代码规范,设定评审标准。
执着于代码的洁癖,分层的固化、API的标准化、中间件的抽象化…
实际发生的:光秃秃(没注释)的形似被混淆过(儿戏的命名|对不齐的段落…)的千行代码,事务的注解可能在每一层都出现过。
逻辑代码散落在Business/Service/Dao各层,只是因为不喜欢Hibernate所以选择MyBatis,只是因为谷歌脑残粉所以选择Gson/Guava…
随心所欲的代码会带来维护的困难和各种技术债,不统一的技术框架会引入更多的学习切换成本和升级优化成本,评审口径不一致会导致团队聚焦散乱各自为战…
架构师作为团队的一个高攻厚血型英雄,就是尽最大努力,在低位面减少技术熵增,高位面寻求技术突破。
通过规范指定的标准都是低位面,不需要你在低位面上浪费任何时间扯犊子。而高位面一定是无法给出规范标准的,任你创新和发挥。
同样是打印Hello World,就是有人会多渲染个ASCII字符画,让控制台输出不那么冷冰冰。
第一次看到架构师写出下面这种条件表达式的非常规写法时,
if ( 1 == iCount ) {}
if ( null != response && “SUCC”.equals(response.getCode()) {}
年幼无知的我曾经“嗤”出了声:“写个等式都要颠三倒四,整噱头博眼球么?” 直到我写出了如下错误,
if ( iCount = 1 ) {}
//漏了等号,永远为真
if ( response != null && response.getCode().equals(“SUCC”)) {}
//少写判空导致的空指针异常
这种代码的反差犹如龙门客栈的老板娘金镶玉,看似风骚泼辣杀人越货,实则纯粹坦荡至情至性。
当你傻傻的写乘/除2的N次方时可还记得骚气的位运算…骚气的try-with-resource…骚气的Lambda…骚气的动态字节码…比比皆是。
这么些年我总结下来,对代码的执念就是八个字:稳中带骚,骚中求稳。
— 2—造物主思维
某个风和日丽的下午,公司里一个小伙伴跟我说:他申请在一个月内重写消息网关系统(承载短信、微信、邮件、App推送四大渠道),原因是目前的系统太难用了。
我的第一反应是 “WOC,我一直盼望的那个救世主终于出现了么?!”
其实吧,那个消息网关系统曾经是我和架构组兄弟花不少力气设计的,本身并没有什么大问题,最多就是随着消息数量的指数级上升,需要做一些性能优化。
比如 分库分表 和 数据归档 就能解决大部分问题,而这些升级所需的扩展性在设计初期就考虑过。
我生怕表现出对这位“救世主”的质疑而显得不礼貌,就小心翼翼的试探了两个问题:
1)“如何平衡上游业务的洪峰和下游消息通道的最大承载,最大化单位时间内的吞吐量?”——微服务体系的流量控制
2)“个人交易消息和全局活动消息,如何存储和查询?”——时间和空间的抉择
结果我得到的回复只是线程池、异步化和缓存的泛泛之谈,离真正的落地还差的很远。
除了上面2个问题,还有同步异步、时效、延迟、通道隔离、信息补偿、环境开关等的实现同样很重要。
造物思维就是从0到1需要的思维,这个1可不简单,它必须包含进化到100所需要的一切基础铺垫。
女娲抟土造人只存在于神话中, 而架构师就是可以从0到1创造系统的“上帝”,只是翻船事故时有发生而已。
不要轻视任何从0到1的创造性活动,这里所包含的知识或技能体量远超你的想象。
为了解释这个过程,请你单从数学的角度,告诉我 (0, 1) 这个开区间之中到底有多少个数?
如果是无穷,那么二进制的计算机如何运算这无穷的数字呢?有同学回答,计算机是使用离散的浮点数来表示这些小数的。是没错,而本质上,浮点数在坐标轴上也就只是很密集的点而已,根本就不是连续的线。
既然全是点,更加疑惑了,计算机怎么画线呢?到这里就可以结束了,因为显示器的像素本就是人肉眼无法识别的小格子,足够密集的点足以呈现出线的效果。
继续刨根问底,那得了解下什么是定点数了,才可以让密集的那些点更加的密集。
希望你能静下心来读读这篇浮点数,
读完你至少可以了解“取值范围”和“可表示的个数”之间、浮点数和定点数之间的区别等等。
《格物致知-Floating Point》
我想我应该从一个理科男的角度,说明白了创造需要的是什么:足够密集的知识点和它们之间的连接。
也有人把它包装成了“知识体系”,说到底,一个意思。
创造本身已然不容易,如何创造更加五花八门。架构选型其实就是选择如何创造。
同样是索引化的数据存储,Kafka是索引文件和数据文件分离,MySQL InnoDB却是索引和数据在同一个ibd文件里。
都说多线程吞吐量高响应快,Redis却选择了单线程模型(Redis6已经加入了多线程实现,主要用于处理网络IO上。命令的执行依然是主线程串行执行)。孰对孰错?
所以创造从来都不是千篇一律,也不是一成不变,而是量体裁衣。
高明的架构师心里藏有无数的架构设计方案,但对于不同的场景,他会选择最合适的那个来实现。
因为架构更像一种艺术而不是科学。
你只看结论的话,或许最终方案并不怎么出色,甚至很普通。
但是它是经过N个方案PK胜出的The One,对其他你以为更好的方案所面临的未知,你可能一无所知。
— 3—面对未知的勇气
我有深海恐惧症,许多人都有。因为面对黑不见底的海水,我们充满了对未知的恐惧。
IT行业的未知每天都在发生着,经常让我们手忙脚乱。
何谓"未知"?它可以是诡异的生产故障,可以是全新的技术,也可以是模糊的未来业务形态。
许多诡异的生产问题有重启大法,但让习惯了SSH编程的你,使用Reactive来实现一套响应式服务端系统,这种未知领域你会如何应对?
更别谈连产品经理都看不清的未来业务形态,你又会如何设计系统的扩展性呢?
那么,我们如何对抗未知?谈以下两点:
1.草木皆兵
问:你这一生碰到过的最严重的生产事故是什么?
答:抱歉,从未碰到过。
海恩法则指出:每一起严重事故的背后,必然有 29 起轻微事故和 300 起未遂先兆以及 1000 起事故隐患。
几年前有段时间我开车总觉得方向盘有点松动,一直没当回事,觉得可能车老了或者自己平时方向打太紧了。
某天预约做保养,车店老板小马哥把我车开走没10分钟,就给我来一电话:
“你的转向柱可能出问题了,方向盘有点松,你之前有发现么?”
“我知道的,可能车老了吧,也没当回事。”
“你小子,转向问题很吓人的,我都不敢开了,到店里马上帮你检查看看。”
后来结果你们也想得到,真的是转向柱断裂!幸好在事态严重之前,小马哥凭借专业素养发觉了这个隐患。
所以这到底是是我的无知无畏还是小马哥的小题大做?
其实,架构师在评审会上表现出的“草木皆兵”亦是一种执念,他所看到的“尸横遍野”,你可能一无所知。
2.知道自己不知道
给你100W让你实现一个数据库,这活敢接么?就说这活本身,先别忙嫌钱多钱少。
把你所有的与数据库相关的知识拿出来,你看看能凑出下面哪些模块出来?
先搞清楚“知道自己不知道”的是什么,才有办法将未知变已知。解决未知就是不断的转化已知的过程。
这也是为什么竞品软件都在造轮子,但是侧重点迥然不同,就是已知不同。
这个“已知”可以是商业产品、开源产品,也可以是论文报告,还可以是业务、技术痛点,不一而足。
RocketMQ当初参照了Kafka,在牺牲了部分性能的情况下优化了投递时效、消息顺序、消息轨迹等;
TiDB 是基于 Google Spanner / F1 论文实现的开源分布式 NewSQL 数据库;
开源调用链如Skywalking、Pinpoint都是基于 Google Dapper 论文实现的;
界面简洁、容量大、搜索强的 Gmail 横空出世,面对众多传统邮箱的狙击,依然成为人们最爱的邮箱品牌,顺便激活了半死不活的 javascript …未知? 不过尔尔。
— 4—架构师的天赋
只有天才的程序员,没有天才的架构师。
架构师靠的不是天赋,而是勤勉,要靠大量时间进行实战操练和经验积累。
热门吵架题目“架构师要不要写代码”,若没有对业务浸淫多年的历练(编码只是一个历练维度),如何能设计出合理的业务架构来?
所以别再问这种傻X问题了,何苦给自己的偷懒找借口还如此冠冕堂皇?宁愿换个题目讨论,“架构师的门槛是写多少行代码”。
所以,架构师并没有天赋一说,倒是要通过艰苦卓绝的奋斗逐步成长起来。
最后
谁也不敢妄言自己掌握了终极力量,因为:架构之路越走越无知,一如人生路。尊重架构的力量,一如尊重未来的你。