没有架构师的命,却得了架构师的病!
而架构师也可以分为初级、中级、高级三档,江湖上真正高水平的软件架构师就更少了。
所以,大部分(超过九成的)码农干上许多年,还是做不了架构师,这是什么原因造成的呢?
什么是架构师?
写代码和做架构是两个不同的事情。什么是架构师,架构师要做什么事情,为什么 Java 的领域里,会更注重架构师?
很早很早之前,我对于架构的概念一点都不理解,依稀记得,架构( architecture)这个词,来自于建筑领域。
这对于我这个没写过几行代码的人来说,瞬间就有了一种“不明觉厉”的崇拜感。
架构,感觉好厉害的样子,从名称上来说,好像是设计根骨,设计底层,设计最核心的东西的人。
架构师,一定很 NB,我什么时候能成为架构师呢?
后来懂了一点点代码,去写增删改查,更是体会不出来架构的概念,不就是 SQL 语句吗?
明明 DBA 更厉害啊,做各种的慢 SQL 优化,所有的 SQL 都要让 DBA 审核,DBA 对于 MySQL,或者是 Oracle 的各种性能调忧很厉害,而熟悉业务的开发人员又常常能写出几万行的 SQL 语句。
我看到这些头都要炸了好么?所以,到底什么是架构?
整个系统只有一个 Web,Spring MVC+Spring+Hibernate 搞定一切,开始做需求分析,实际上就是设计表结构而已,剩下的就是查查查,改改改,删删删。
直到某天,我知道一个词,缓存。
缓存这玩意儿,在很早之前学习各种基础课程的时候,了解过一些,一级缓存,二级缓存什么的,LRU 我好像也懂一点点,但是,在系统里,缓存算是什么?
在公司里,那个架构师,画了一张图,告诉我们,这台机器上,放了一个 Memcache,然而我们都不懂,他只解释了一句,这个 Memcache 是缓存。
我的第一个困惑就是,所有的请求都要再次转发到另一台机器上,把数据取出来,单个请求可能不算什么,每天有几十万次请求,这中间的损耗不大么,为什么不把 Memcache 放到本地机器上呢?
他没解释,只告诉我说,不大,Memcache 就是要放在另一台机器。
在当时,我不清楚内网和外网的差别,也不清楚访问 Memcache 的请求倒底是需要多少 MS,更不理解,把 Memcache 放在和业务层一台机器,或者是分开放的差别倒底是什么。
但这个问题一直困惑着我,简单来说,这其实算是一点点架构师要做的事情的萌芽,一个系统中,如果拆解出来了很多模块,倒底应该部署在哪些机器上?架构师会解决这些问题。
后来,到了搜狐之后,我突然间发现了我之前学到的东西,在搜狐的技术大神面前,直接被轰成渣。
负载均衡是什么?热备又是什么?穿透 DB 是什么意思?怎么我取数据库里取一个值,数据库里没有,这种空数据的请求会把 DB 打垮?我还要把这些为 Null 的请求单独缓存起来?本地缓存做为一级缓存,Memcache 做二级缓存?
“对缓存来说,最关键的设计就在于失效策略是什么。”大神镇定的看着我。我很惶恐,感觉能把失效策略设计出来,很不容易。
不同的应用场景,对于缓存的要求不一样,对实时性的要求也不一样。榜单这种一天更新一次的,每天晚上定时生成一次就好了。
后台更新,但是要注意,一定要直接生成,直接切换,不能让前端用户访问的时候,再去生成。
对于名字这种东西,用户改完之后,必须立刻更新缓存,包括本地缓存和远程缓存。
这算不算架构中的一部分,根据不同的应用需要,去设计不同的策略,同时把这些场景规范化,成为一整个团队都要去遵循的标准?
我不知道,我只知道,能 Hold 住团队里所有人的那个人,技术一定非常 NB,团队里的每一个人,都会质疑,如果你 Hold 不住全场,怎么能推行下去?
当时近 30 的技术团队里,每一个都是神一样的存在啊,谁能 Hold 住 30 多个神。
而且,原来不应该把所有的代码放到一个 Web 里,原来分布式是这么回事儿,原来一个系统,是由多个子系统构成的,原来还要分层,原来封装和抽象是这么个意思。
Web 层是一层,通常可以通过 LVS 部署两台到三台,或者是更多的,Service 一层用来处理业务逻辑,缓存层用来扛并发,一定要藏在 Service 里面。
Controller 调用 Service 的时候,并不需要知道数据到底从哪来的,每一个 Service 使用什么样的缓存策略,完全不需要 Controller 层知道。
对于大型应用来讲,MySQL 只能用做是持久化,MySQL 的单条访问速度并不查,只是在并发能力太差,扛不住。但是,有可能数据量过亿啊?
过亿怎么办?是用分库,还是分表?读写分离要不要做?一台服务挂一台数据库,哪些数据库应该放在一个实例里,哪些应该单独拆出去?每台服务器的配置是什么?
我大概知道一点点,架构师要做哪些事情,他就是要把这些大的骨架定好,然后我们去填充里面的内容。如果骨架定歪了,其余团队必然跟着歪。
这时候有了一系列的问题,第一个,Controller 和 Service 之间,Service 和 Service 之间,应该通过什么调用?
RMI,这是惟一的选择。用 Thrift,或者是 ProtocolBuffer,或者是 Rest 实现的 RPC?
这是架构师要考虑的事情,如果是用 RMI,我们是要自己实现,还是要找找是否有好用的开源的框架,在其他的系统里被证明了是有用的?
大神们花了两周的时间,对当时流行的开源框架过了一遍,最终选定了 Tuscany,到现在我都觉得设计精美,完暴 Dubbo 的东西,真的是一点都不想切到 Dubbo 上去,毕竟“曾经沧海难为水,除却巫山不是云”。
直到最近几年微服务兴起的时候,我还是同样的目瞪口呆,这跟 2009 年搜狐当时做白社会的架构比起来,优势倒底在哪里?
差别好像没有那么大啊,而且 Tuscany 实现的更完美,只是使用的时候要有更强的约束,因为 Tuscany 太强大了,强大到有一点点重,必须要做简化。
而且,Tuscany 的开发团队不怎么维护了,白社会当时做的东西,还是大神花了两周的业余时间写了一个 Scallop,增加了 Tuscany 的负载均衡的功能。
但是,到底用什么,不用什么呢?除了 Tuscany,还讨论过要不要用 Hadoop,要不要用 ActiveMQ,要不要用 Erlang。
这是否也是架构师的职责?这个架构师太厉害了,他需要从前到后都要懂,他需要制定关键的技术细节,他需要给出最佳实践,他需要了解业界所有流行的解决方案。
他需要去猜测 Facebook 怎么解决问题的,Twitter 怎么解决问题的,Google 怎么解决问题的,这些解决方案可不可以拿过来,也同样适用于我们自己的场景。
他需要精通分布式,Nginx 或者是 F5,微服务,缓存,持久化,消息队列,他需要熟悉所有这些技术细节里的最常用的解决方案,不能有遗漏,也不可以过度设计。
他决定的不是他一个人喜欢的风格,他决定的就是整个团队,在项目死亡之前都必须遵循的规范,现在的团队成员,和未来的团队成员,都必须遵循的体系,而且,如果在未来,这些架构体系有不合理的地方,那就麻烦大了。
这样的架构师,还要肩负着一个重大的使命,修复开源软件的 Bug。
在很早之前,我一直误以为开源软件是很厉害的很 NB 的东西,我一直以为这是完美的,很久很久之后,才明白,所谓的完美,都是用血和泪塑造而来的。
不经过各种各样的验证,环境,使用的测试,很难达到一个上线标准的稳定,即便是上线了,也有可能会出现之前完全预料不到的问题。
可是,如果你选择了这个框架,出了问题,谁去解决?
架构师,他要开源码,理解这些开源框架的思路,然后去找有可能产生问题的地方,再去修复他。
我一直都觉得,能看懂别人写的代码的人,都是神。某段时间我去看一个 Heritrix,看的我神清气爽,各种层出不穷的继承,各种抽象类,连着三天我欲仙欲死,更加坚定了我死也不要,也不允许其他人在项目里使用继承的决心。
但是 Heritrix 从外表看起来特别牛,他的抓取策略也很 NB,用的分布式抓取的解决方案非常轻巧。可是我我实在是不想再去读一次了,在当时不读不行,资料太少。
那么,一个架构师,要对这些源码都了解么?又或者是,他必须具备,需要他去读源码,他就必须读源码,而且去优化的能力?这大概比提前懂源码,更神奇。
因为是有时间要求的啊,简单来讲,他需要在一个有效的时间内,去弄懂所有的底层的东西,说句实在话,当有同事嘲笑我都没有完整的看过 TCP/IP 协议详解的时候,我真的是无话可说的。
架构师需要懂业务么?
有了这些,就可以称之为架构师了么?架构师需要懂业务么?
是不是就可以每天看技术,写底层框架(比如我们原来在搜狐用到的 DAL,数据访问层,用起来简直是神器的东西)。
没有不懂业务的架构师,所有的架构,都依赖于业务。所有的架构师,也必须要去写业务代码,不把自己设计的东西,用在真正的项目里,恐怕他们自己都不会知道,这种架构设计的合理性在哪里。
在某团购公司上市之前,他们的 CTO 拿出来了他们的架构图给我看,在给我看之前,所有的技术术语都一样,但是当我认真看了架构图之后,我的困惑......
为什么 Memcache 要放在 Controller 层被调用?不应该是放到 Service 层吗?
怎么会出现你说的,一个 Serivce 负责维护的数据,也有可能被另外的 Service 去更改的情况?
每一个 Service 对数据的操作,必须是独立的啊,除了这个 Service,其他的任何服务都决不允许直接更改 DB 啊。
而且,怎么 Service 拆分了,DB 不拆分呢?这样的话,压力大的 DB 会把全站拖跨的啊。
那张架构图我看到之后,感觉自己的认知被突破了,原来可以这么做,原来同样的,类似的技术选型,可以做出来如此艰难的东西?
就在我以为这其实就差不多是架构师的全部的时候。在最近一段时间,我突然间发现了一个问题。
为什么有的人代码写的这么烂,很多写死的代码,一点儿灵活性都没有,更没有规范,完全就是堆压。
为什么有的人根本不知道怎么去抽象,并不清楚怎么样积累成公共组件,为什么他们改一个问题,通常会引出更多的问题?
为什么他们的代码里的实现方案,让人看完之后恨的牙痒痒,想改又完全不能改,毕竟,正常工作的代码才是好代码?
怎么叫做面向未来编程?
一个好的工程师,在听到需求的时候,可以根据自己的业务能力,判断出来这些需求中,哪些是有可能变化的,哪些是不太可能变化的。
针对这些变化的内容,在编写的过程中,不会写死,而反复确认不可能会变化的需求,会写的简单一些,防止过度设计引起的复杂度。
简单说,当他拿到需求时,并不单纯是考虑这个需求怎么实现,还会考虑,自己设计的架构体系,扩展性在哪里,在他的眼里,看到的需求会被分解,折分,然后自己的技术方案,会挨个分解,分配。
在完成设计之后,他会很清楚的知道 ,自己设计的系统里,哪些变化是支持的,随便你改,我只需要改动一个很简单的内容,哪些是你绝对不能改的,你要改,我就必须花很大的代价,特别是在已经有线上数据的时候。
而且会拿着自己的架构体系跟 PM 沟通,讲清楚。
什么样的变化是支持的?短信通道是有可能变化的,而调用短信通道的地方可能会有点多,所以我必须把短信通道抽象,并封装在一个公共接口,如果需要更换短信通道,我可能只需要更改一个配置文件就好了。
那么什么样的变化是不支持的?我不需要不停机就更换短信通道的功能,除非你在后台系统中提前配置好,或者是有明确的需要,我做出这么一个东西出来。往往在前期,不会用到,为什么?
在创业初期,短信通道往往用于用户注册,一旦出问题,就是生死问题,必须要有一个备份,运营商一怒封掉你的通道,很常见。
而重启一次服务,在创业前期,往往没有那么严重。所以,这些技能,是不是也应该归纳到架构师的职责里去?
架构师从开始就要考虑选型,从语言开始,从业务开始,要对这个领域里的开源框架熟悉,了解,要能解决疑难问题,要懂安全,要会备份,要学会面向未来编程,还需要什么?
还需要 DevOps,在持续集成的年代,在服务器规模越来越大,在云服务器的年代,在异地存储,冗灾,在全球化越来越快的年代。
运维的重要性已经到了一个很核心的程度了。弹性伸缩,自动扩容,灰度发布等等等概念,要求,都在冲击着架构师这个概念的定义。
如果说之前的架构师,更多的是在系统开发前,现在越来越偏于系统上线后。
还包括数据分析,日志分析,等等等等,对了,还没有提到 NoSQL DB,实时搜索,知识库,算法这一系列的东西。
每一个领域都在细分,每一个概念都在深化。简单说,架构师确实和语言无关,但是又绝对和语言有关系。
你可以说,架构师就是在做选型,但是只会做选型,肯定做不出架构师。
中级工程师的发展路线
说到了现在,我有没有讲清楚架构师是什么?而你,还想要做架构师吗?
反正,我说自己是架构师的时候,我的内心是羞耻的,我知道 ,我远远没达到架构师的能力。
然后,我曾整理过一个中级工程师的发展路线。
科班基础:
计算机组成原理(洗髓换骨营)
计算机操作系统(洗髓换骨营)
计算机网络(洗髓换骨营)
数据结构(洗髓换骨营)
数据库
算法
语言相关:
JDK
线程
Set
Hash
GC
ClassLoader
Lambda
IOC
Spring
Spring MVC
Spring Boot
Shrio
MySQL 基础
DB 设计
DB 调优
MySQL 底层架构
idcenter
常用工具
索引
设计模式
缓存
分布式
Key-Value
消息队列
定时任务
微服务
RPC
高并发
性能优化
接口定义
日志规范
编码规范
最佳实践
Linux 常用命令
JVM 常用工具
Nginx
Resin
LVS
Iptables
Jenkins
Ansible
容器 Docker
监控
CICD
一致性哈希
Gossip
Paxos
Spotsig
HTTPS
MD5
Auth2
Bloom Filte
编辑距离
TrieTree
Rete
Spring
Redis
Memcache
Mybatis
Log4j
Maven
Git
敏捷开发
金融
支付
电商
直播
教育
O2O
分销
会员
活动
秒杀
自顶而下
分层模式
抽象
落地
推测
验证
组件
定制
生成
为什么很多程序员做不了架构师?
是刚开始就么有奔着这个目标去,好比是动作变形,反而不好纠正了。
是思维没能提升一个台阶,只局限于具体的编码,没有考虑过选型,复用,扩展。
是身边没有架构师的引导和培养,环境问题是一个很大的问题。
作者:暗灭
编辑:陶家龙
出处:https://www.zhihu.com/question/36658435/answer/1304731422