架构大咖言传身教:从程序员到架构师
正文共:12515 字 38 图
预计阅读时间: 32 分钟
从程序员到架构师
我们来讲一个故事,一位旅行者路过一个烈日下的工地,所有人都在那儿汗流浃背地搬砖。旅行者问第一个人在干什么,那人头也没抬地回答:“我在搬砖。”
旅行者问第二个人在干什么,这个匆匆抬起头认真地说:“我在砌墙。”
旅行者问第三个人在干什么的时候,那个人脸上充满了光彩,很自信地说:“我在盖圣玛利亚大教堂。”
这个故事是不是像极了我们从事软件开发工作的不同阶段的不同状态。
每当听到从程序员到架构师的书或者文章时,我们总是充满好奇,想从其中获取一些观点亦或是技能点,接下来我们就详细讲讲一下,如何从程序员走向架构师。
首先我们定一个基准点:架构师只是功底深厚的程序员,千万不要成为不会写代码的架构师。
架构师应该是立足于技术和业务之间的中间角色或者平衡点, 在针对业务深刻理解的基础上,针对业务中存在诸多变数,挑选适合的技术架构和技术方案。可以这样说,一个架构师工作的好坏决定了整个开发项目的成败。
开篇的基准点:架构师只是功底深厚的程序员;
程序员从初级、中级、高级再到架构师,是一个不断经验积累的过程,但是在这过程中我们常常很迷茫,不仅仅是面对技术繁杂的无力感,更重要的是因为长期埋没于代码世界的浩大的分工体系中,无法看清从业务到系统架构的价值链条,无法清楚定位自己在分工体系的位置,处理不好自身与技术、业务的关系所致。
所以在程序员生涯中除了技术实力以外,其它软实力也不容忽视。如:主动学习、积累经验、控制注意力、超越自我。
卓越的程序员
对于一个卓越的程序员来说,编程技能毋庸置疑是很重要的。但是,除了基本的编程开发能力,其他方面的能力也是体现一个程序员的能力的很重要因素。比如,问题排查能力、线上运维能力、项目管理能力、协调沟通能力等。
我们先看IT市场对于一个不同阶段的程序员的要求:
职位要求
初级开发工程师
综述:主动性,积极主动,能够主动了解相关业务需求,在上级的领导和监督下定期完成量化的工作要求;
项目管理:不需要项目管理的能力,具备管理简单模块开发任务的时间点。
开发语言技能及架构能力:1.能独立处理和解决所负责的任务;2.根据开发进度和任务分配,完成相应模块软件的设计、开发、编程任务;3.进行程序单元、功能的测试,查出软件存在的缺陷并保证其质量;
业务理解:1、根据产品需求PRD理解简单模块的业务流程,根据业务流程书写相应的开发流程,能够根据自己的理解评估模块开发的时间点。
影响:1、能影响同级开发人员,得到项目组认可。
职位要求
中级开发工程师
综述:独立性,根据项目具体要求、承担开发任务,按计划完成任务目标。
项目管理:具备有一定初级难度的项目(如链路较短模块复杂较低风险较小发布周期不紧)的PM的经验和能力。
开发语言技能及架构能力:1、理解产品文档,参与需求评审、需求分析、系统设计;2、负责确保项目的进度和质量;3、整理和提交相关设计文档,对负责的功能模块有自测习惯;4、对所负责的模块有维护责任,有问题及时解决。
业务理解:1、熟悉自己负责的业务模块,对业务模块的流程有独立的思考,产品设计时能给出合理有效的方案建议;
影响:1、能影响项目的成员,是团队内公认的主力成员之一;2、加分项:有良好的分享习惯。
职位要求
高级开发工程师
综述:自主性,独当一面,能独立主导和推动项目及任务,在专业领域具备辅导他人的能力
项目管理:具备有一定中等复杂度的项目(如链路较长、模块复杂度较高、风险较大、发布周期较紧、技术驱动等)的PM经验和能力。
开发语言技能及架构能力:1、能独立解决问题,能够负责重要业务模块的需求分析及设计实现。2、熟悉设计原则,能够在日常编码工作中恰当使用,优化原有设计(有实例支撑);3、熟悉编程语言、编码规范、安全规范,具备性能意识,代码具备高可读性;4、了解常用框架背后的原理。
业务理解:1、熟悉自己直接负责的业务,对业务产品具有独立沟通,完善业务需求;并识别方案的风险能力;关注自己参与项目的业务数据;2、能够在所负责的业务及产品上有独立的见解,能提出合理的建议,更有效的解决业务问题;
影响:1、能影响项目组或产品线的成员,是项目组或产品线公认的主力人员;范围:团队内。2、加分项:具备辅导他人的能力和技能,有良好的分享习惯。
根据上面的招聘需求,我们来看看作为一个开发工程师从初级到架构师,需要哪些技能和非技能的积累,下面我们就从技能和非技能来总结。
卓越的程序员
技
能
篇
技术技能树
业务自测
一般的研发流程
在上面职级要求中,对于初级开发工程师的要求就是得到项目组的认可,如何得到项目组的认可呢?不管哪个职级的公司成员,首先要对自己做出的事情负责,上面的流程中发现一个问题,功能开发结束提测后,测试成员进行测试的时候,发现功能不能正常运行,无法开展测试工作。
这自然是不合理的,会影响测试成员对研发成员的信任、还会影响测试成员的工作积极性,信任就类似刷信用卡,当你的信用值逐次降低,其他成员就很难相信你,演化到最后就是不愿意和你合作,他们认为你是一个不靠谱的人。
当然这个问题很容易解决,只要研发这个环节中增加自测流程即可。
优化后流程
关于研发自测这个环节为什么我们开始没有加上?这是因为,我们一般认为研发人员对自己开发的模块进行自测,是应该的,用研发术语来讲是默认的,不需要另行强调。程序猿的工作是团队协作中的一环,和环上的所有人一样,都应该对自己所做的工作负责,这样对于环上的其他人才是公平的、有效的,团队的整体效率才能提高。
为了让研发成员能进行测试,我们还有些问题需要解决:
测试用例范围问题
被测试环境和测试执行环境的复杂性问题
测试数据准备的问题
测试执行与集成问题
失败测试用例归属问题
这些问题我们就不展开说了,但是业务自测是作为一个开发工程师必要的职业素养。
解决问题能力
解决问题能力不是天生的,自然得靠后天的经验积累。我们工作中会遇到各种各样的问题,比如需要去跟踪调试产品所产生的bug,又比如说使用第三方组件所遇到的一些问题,再比如说使用一些插件或者IDE所产生的一些编译问题。这个时候第一反应不是去别人那里寻求帮助,而是自己尝试去看去解决问题。
当遇到阻塞性问题的时候,需要立即排查并处理。由于是线上的环境,我们在排查问题会有一定的难度,但依旧有一定的方法可寻,一般按照如下步骤进行。
日志查看
从日志中查看到报错的信息,依据这些信息进行问题排查,比如什么时间、什么人、操作了什么、触发了什么、产生了什么结果。
代码检查
在日志无法排查问题的情况下,需要通过代码来定位。这需要对代码有一定的熟悉程度,可以知道用户的操作是由哪里的代码执行的,然后对该块代码进行检查。代码检查的时候需要着重检查一些逻辑分支语句,同时可以借助一些工具,例如:FindBugs,Alibaba Code Guidelines等。另外,还需要关注一下触发器之类的隐蔽代码。
远程调试
由于代码是静态的,而代码执行是动态的。静态代码的检查可能并不能检查出问题,而需要通过线上的环境、数据一并进行检查。这时,可以在不影响线上用户使用的情况下,远程断点调试程序。
本地调试
有的系统可能并不方便进行远程调试,那么可以尝试把线上的全部数据(或者关键历史数据)拷贝下来,在本地环境使用线上环境的数据库,进行调试。断点调试是比较直观的一种检查错误的方式,通过异常信息的日志,能确定到指定的代码行,并结合线上的数据,很容易发现问题。
学会提问
问问题的能力是一个人的修养,学会提问是一个人成长的必经之路。尤其是软件行业的从业者,要保持对技术的钻研精神,不做伸手党,问出水平,问出修养!
有礼貌
毕竟谁也没有义务帮你解决;
问对的人
选择相关主题的板块,不要多次发布相同问题!
主题清晰
问了让别人不用看描述就知道问题类型和背景,github一般都会对issue做tag标记的。
较差的标题:保存,老实提示系统异常。
较好的标题:在firefox中保存时导致系统异常的兼容性问题求解。
描述要准确
描述机器环境(os,机器配置,版本信息);描述自己的排查方向和相关现象;描述问题的触发背景(升级了什么组件/改了什么);提供复现方法。
描述要客观
不要加主观判断;
描述目标
不是中间的某个步骤step;可能你的方向偏了,实现目标根本就不需要实现这个step。
想提高自己解决问题的能力,首先得学会如何提问。给自己提问或者向别人寻求帮助时。
总结分享
我们日常遇到的问题就类似打怪升级一样,你解决的问题越多你的能力就会越强,经验自然也会越来越丰富。但人的脑袋不可能记住所有事情,将自己遇到的问题沉淀下来对以后自己查阅也有很大的帮助,就不必每次都要去Google,自己也能够有一个索引库。
经常自己总结,也能够提高自己的写作能力,以后写文章、ppt总结提炼自然也难不倒你了,也是一举两得的事情。
还有你以后求职面试过程中,提及自己这方面的能力的时候,也能够为自己面试加分哦。
一个人能产生多大价值取决于他的影响力有多大,之前看到有人在我们内部论坛提问说提高影响力有什么用?你看看马云就能知道有什么用了,他说一句话比你说上百句都管用,毕竟人家的影响力在那里。我们程序员做知识经验的传承,不仅能够提高你自身的影响力,还能够帮助你提升逻辑思维能力,因为你需要去总结提炼,你需要将问题梳理清楚,并且要将知识点描述得能够让别人更容易接受。你的经验虽然是你自己的,但如果你的经验能够帮助到别人,那你的价值就不一样了。
卓越的程序员
非
技
能
篇
主动学习
大脑不是一个用来填充的容器,而是一束需要点燃的火焰
----普卢塔赫
学习不是强加于你做的事情,是需要你主动做的事情,仅仅掌握知识不去实践是没用的,
古人已经总结了,『纸上得来终觉浅,绝知此事要躬行』,学习也需要方式方法,需要目标反馈,针对自己在日常项目遇到的问题去学习再进行实践验证学习效果会更好。SMART目标就能很好的帮助你如何学习。
SMART目标
*S:Specific(具体的):首先,一个目标任务应该是具体的,把学习的目标具体化,例如:『我想用PHP写一个Mock服务端』
*M:Measurable(可度量的):如何知道你何时完成,如果无法度量目标任务,那么目标还不太具体
*A:Achievable(可实现的):先确定目标是否合理,从你现在所处的情况着眼,让每一个目标都可实现。
*R:Relevant(相关的):目标需要和你相关,需要在你的掌控之中。
*T:Time-boxed(时间可控的):这是目标最重要的一个特性,你需要设定一个最后的期限,没有期限,目标会逐步衰退,它可能就无法实现。
现在互联网技术的发展也是日新月异,我们学习的速率也要提高了,目前我们获取新知识的途径一般都是碎片化的,阅读老司机的公众号或购买高质量的纸质书籍,现在的问题就是我们如何在短时间内阅读并吸收其中的技术点呢?好的阅读方法让你对于知识的掌握事半功倍,SQ3R法主动阅读法让你如何更有效阅读。
SQ3R法
1 | Survey(调查):带着问题审视书,看目录,各章介绍,总结,在深入细节前有一个总体的印象 |
2 | Question(问题):写下你要弄明白的问题,标题改为问题 |
3 | Read(阅读):可以阅读全部内容了,在困难的地方放慢速度;如果内容不是很清楚则重新阅读 |
4 | Recite(复述):复述回想和使用自己的语言改写书本最重要的部分,做笔记(思维导图,要点) |
5 | Review(回顾):扩展笔记 |
重复阅读相同的材料和笔记,不会有助于记住你的笔记,所以多编程实践,解释给其他人听,使用思维导图做笔记——需要使用颜色、符号和其他有意义的东西标记不同的事物,认真审查是否需要生成文档,避免不必要的文档,写文档的过程比文档本身更重要,学习某项事物的最简单有效的方法是尝试教别人
积累经验
积累经验是学习和成长的关键——实践出真知。但单纯的『实践』并不是成功的保证,你需要从实践中学习其中的价值,而一些常见障碍会让这个过程很艰难。但是你也不要刻意地拼命实践,过犹不及。我们应该研究如何利用反馈、乐趣和失败来创造更有效的学习环境,关注设定最后期限的危害,并体会如何通过自我引导积累经验。
加班(我不鼓励):主动加班去掌握工作外的技能、资源,承担的多了,自然经历的就多。
自学:日常项目的业务有限,不可能涉及很多,靠自学才能延伸更多的技能。可以参加一些兴趣群,相互学习进步。
复盘:很多经历变成经验,往往只差一步之遥——复盘,复盘可以帮你回顾这个项目过程,就可以看到哪里做的好,哪里做的不好,我们下一次可以做的更好。
换位:不能仅用现在自己的角度思考问题,多身份变换,谋求多元化,否则思维容易固化。
交流:思想的碰撞才能激发灵感,多加入一些社群,听高手、同行、前辈分享交流一些过往的经验,这些往往是自己无法经历的,也是书上无法获取的。
坚持:坚持上面的这些点,你不卓越都难。
注意控制力
不知道你还记得最近一次解决真正的难题是什么时候吗?你可能是在试图修复一些BUG,或者要弄清楚为什么代码跑不动。时间飞逝,你忘了吃饭、喝水乃至睡觉,一门心思扑在你的任务上。你全身心的投入到单个项目上,如果任何人胆敢打扰你,你就会暴跳如雷。这就是「专注」。就像生活中许多事情一样,专注就像一个「冲量」的游戏,想要达到专注工作的状态很难,但是一旦进入专注状态,就能轻松的保持下去。我觉得用来形容人类思维从一个「注意力分散」的状态进入到「专注」状态的过程是再好不过的概念了。
像我们启动电脑程序,第一次打开程序往往需要较长的时间。因为计算机要花一些时间把程序代码写入到内存,之后,你使用软件就更加顺畅了。就像以前写Java的程序员,上班第一件事打开MyEclipse,然后直到下班才关闭。也像你忽悠产品经理,打开网站第一次会慢点,第二次就会飞快了。所以,当我们需要对一件事情「专注」的时候,我们需要花一些时间把所有的事务在脑子里过一遍,然后才能达到思维高峰以完成任务。
如果不幸,你专注期间,产经忽如其来讨论需求,测试忽如其来报BUG,之后你还需要重新回想刚才做到哪里,重新花一些时间来形成「冲量」。就像计算机线程间来回切换所需要花费的成本。被打断的间隔越长,需要继续之前的任务所需要的成本也就越高。
忽然想起个段子:「你跟产品经理讨论了一天,他的需求有了,你的代码呢?」
如何保持专注
明白了什么是「专注」,以及专注的克星「打断」。
我们可以总结保持专注所需要解决的几个主要问题:
锻炼专注,缩短冲量的成本
减少干扰源,避免打断
注意休息,注意思维体力
学会管理任务,明确目标
超越自己
制定计划
制定一段时间的计划,然后努力实现。跟踪你的进展,当你感觉做得不沟时重新审视你的成果。
“不作为”是敌人,而“错误”不是
危险不在于做了错事,而在于根本没去做事。不要害怕犯错误。
给新习惯适应时间
在新行为变成习惯之前通常需要至少三周的时间,或许更长。
信念是真是的
你的想法的确会改变大脑的机制和化学物质。
采取步步为营的细小步骤
开始时目标设置低一些。当你实现时奖励自己一下,再设立下一个目标。脑子里记住你的最终目标,但不要试图把所有步骤想明白。只关注下一步,一旦达到这一步,再继续为实现下一步目标而努力。
总结
用战术的勤快掩盖战略的懒惰!那么这样的后果就是我们把自己限死在流水线的工位上,阉割了自己能够发现业务价值的能力,而过多关注新技术对职场竞争力的价值。这也就是我们面对繁杂技术,而产生技术学习焦虑症的根本原因,希望通过上面的内容能让职业更进一步,让我们的职业生涯进行脱变。
优秀的架构师
对工作多年的程序员而言,日后的职业发展无非是专精技术,转型管理,晋升架构师三种选择。成为一名优秀的架构师,是大多数技术人的追求。想要做架构,空有一身技术是远远不够的,知识的深度和广度,往往会决定一个架构师的架构能力。而这些知识,从你踏入IT行业那一刻起,甚至更早就应该开始储备了。那么到底什么是架构师?如果有一天把你丢到架构师的位置上你会怎么做?做什么呢?以下来具体阐述下一些看法和建议!
先看看IT市场对于架构师的职位要求:
架构师要求
1
综述:
系统性,知其然知其所以然。是某一个领域的专家,在专业领域具备一定的预见性,可独立领导跨部门的项目。
项目管理:
具备较高复杂度的(项目如链路较长/模块复杂度较高/风险较大/发布周期较紧/技术驱动等任意两项及以上)的PM经验和能力。
开发语言技能及架构能力:
1、可以写出比较优秀的代码,能够基于设计原则及模式掌握代码演变的方向和节奏;具备技术攻坚的能力;
2、具备高复杂度的平台/框架/业务系统技术与架构设计能力,掌握常见的架构设计方法和模式,理解大型网站所需要用到的架构和技术;
3、熟悉业务的价值、特点及对系统的要求,掌握领域建模的方法,可以对业务进行必要的抽象,并推进技术实现;
4、能够负责复杂度高,平台级产品或跨团队的产品架构,系统设计和实现。
业务理解:
1、行业开发:开发熟悉自己直接负责的及上下游相关的业务,关注业务发展相关的数据并能有效的分析解读;
2、平台开发:熟悉所在业务域,并且负责核心业务目标的分解&落地;能够把纵向行业需求落地为横向产品化形态;
3、在业务及产品规划方面有自己独立的思考,能够影响业务及产品的发展方向。
影响:
1、在所处的业务线具有广泛的影响力,对相应涉及的技术和业务都能有足够的公信力;2、具备辅导他人的能力和技能,有良好的分享习惯,对团队有正向影响和帮助。
一
架构师职责
架构师是一个既需要掌控整体又要洞悉局部瓶颈,并依据具体的业务场景给出解决方案的团队领导型人物,他需要参与项目开发的全部过程,包括需求分析、架构设计、系统实现、集成、测试和部署各个阶段,负责在整个项目中对技术活动和技术说明进行指导和协调。
架构师主要职责有4条:
01
确认需求
在项目开发过程中,架构师是在需求规格说明书完成后介入的,需求规格说明书必须得到架构师的认可。架构师需要和分析人员反复交流,以保证自己完整并准确地理解用户需求。
02
系统分解
依据用户需求,架构师将系统整体分解为更小的子系统和组件,从而形成不同的逻辑层或服务。随后,架构师会确定各层的接口,层与层相互之间的关系。架构师不仅要对整个系统分层,进行“纵向”分解,还要对同一逻辑层分块,进行“横向”分解。
架构师的功力基本体现于此,这是一项相对复杂的工作。
03
技术选型
架构师通过对系统的一系列的分解,最终形成了软件的整体架构。技术选择主要取决于软件架构。Web Server运行在Windows上还是Linux上?数据库采用MSSql、Oracle还是Mysql?需要不需要采用MVC或者Spring等轻量级的框架?前端采用富客户端还是瘦客户端方式?类似的工作,都需要在这个阶段提出,并进行评估。
架构师对产品和技术的选型仅仅限于评估,没有决定权,最终的决定权归项目经理。架构师提出的技术方案为项目经理提供了重要的参考信息,项目经理会从项目预算、人力资源、时间进度等实际情况进行权衡,最终进行确认。
04
制定技术规格说明
架构师在项目开发过程中,是技术权威。他需要协调所有的开发人员,与开发人员一直保持沟通,始终保证开发者依照它的架构意图去实现各项功能。
架构师与开发者沟通的最重要的形式是技术规格说明书,它可以是UML视图、Word文档,Visio文件等各种表现形式。通过架构师提供的技术规格说明书,保证开发者可以从不同角度去观察、理解各自承担的子系统或者模块。
架构师不仅要保持与开发者的沟通,也需要与项目经理、需求分析员,甚至与最终用户保持沟通。所以,对于架构师来讲,不仅有技术方面的要求,还有人际交流方面的要求。
二
架构师综合能力
作为架构师,必须成为所在开发团队的技术路线引导者,具有很强的系统思维的能力;需要从大量互相冲突的系统方法和工具中区分出哪些是有效的,哪些是无效的。架构师应当是一个成熟的、丰富的、有经验的、学习快捷、善沟通和决策能力强的人。他必须广泛了解各种技术并精通一种特定技术,至少了解计算机通用技术以便确定哪种技术最优,或组织团队开展技术评估。优秀的架构师能考虑并评估所有可用来解决问题的总体技术方案。需要良好的书面和口头沟通技巧,一般通过可视化模型和小组讨论来沟通指导团队确保开发人员按照架构建造系统。所以作为架构师需要如下的综合能力:
01
沟通能力
为了提高效率,架构师必须赢得团队成员、项目经理、客户或用户认同,这就需要架构师具有较强的沟通能力。沟通能力是人类最普遍性的素质要求,技术人员好像容易忽略,想成为架构师就不能忽略。千万不要抱着这样的观念:怀才跟怀孕似的,时间久了总会被人发现的。还是天桥上卖大力丸的哥们说得对:光说不练假把式,光练不说傻把式。看看你周围的头头脑脑们,哪一个不是此中高手,我们千万不要鄙视,认为这是阿谀奉承、投机钻营,凡事都要看到积极的一面,“沟通”的确是一种能力。我认为自己是一个略内向的人,因为我是农村出来的孩子,普通话都说不好,以前或多或少带有点自卑感,幻想着是金子总会发光,所以在职业生涯中吃了不少亏。现在,我深深懂得了沟通的重要性,我会很主动地跟同事们,跟老大们不定时地沟通,感觉工作起来顺畅多了。
这一条我认为最为重要,所以排在首位。我甚至认为下面几条都可以忽略,唯一这一条得牢记,而且要常常提醒自己
02
技术能力
架构师最好精通1-2个技术,具备这种技术能力可以更加深入的理解有关架构的工作原理,也可以拉近和开发人员的距离,并形成团队中的影响力。
架构师的技术知识广度也很重要,需要了解尽可能多的技术,所谓见多识广,只有这样,才可能综合各种技术,选择更加适合项目的解决方案。有的人说,架构师技术广度的要求高于技术深度的要求,这是很有道理的。总而言之,一句话:架构师是项目团队中的技术权威。
03
架构能力
架构是架构师洞察内在结构、原则、规律与逻辑的过程,架构师要做到清晰理解系统、简洁描述,除此之外,一个架构师还必须具备极强的分析能力,要做到根据产品宗旨和目标,分析清楚产品定位、产品业务,再整合利用现有的技术领域,找出最佳方案,实现产品概念。
04
抽象分析
架构师必须具备抽象思维和分析的能力,这是你进行系统分析和系统分解的基本素质。只有具备这样的能力,架构师才能看清系统的整体,掌控全局,这也是架构师大局观的形成基础。你如何具备这种能力呢?一是来自于经验,二是来自于学习。架构师不仅要具备在问题领域上的经验,也需要具备在软件工程领域内的经验。也就是说,架构师必须能够准确得理解需求,然后用软件工程的思想,把需求转化和分解成可用计算机语言实现的程度。经验的积累是需要一个时间过程的,这个过程谁也帮不了你,是需要你去经历的。但是,如果你有意识地去培养,不断吸取前人的经验的话,还是可以缩短这个周期的。
05
决策能力
决策能力是一个架构师最重要的职责。
1. 技术方案决策原则
通常一个问题都会有多种可解决的技术方案,怎么来决策就至关重要了,而决策通常又和全面相关,大的来说通常决策的原则就是性价比和可持续发展。性价比简单来说是方案的实现成本,这个成本要包括非常多的方面,例如有些场景可能会是用硬件解决看起来是花钱,但最终折算成本是最划算的,很多系统设计在决策性价比时都过于随意,例如一个另外常见的场景就是建设一套新系统替代旧系统,这个时候可能完全没考虑旧系统的迁移代价甚至超过了改造旧系统的代价;
可持续发展简单来说就是所选择的技术方案在公司是否可持续,例如简单的案例是公司主体的研发人员都是php,却搞一个其他语言,且只有极少人懂的(当然,这还是要看性价比,如果搞一个其他语言带来的效益超过了语言/人才体系的更换成本),又例如引入一个开源产品,有无专业团队维护这都是要考虑的关键因素。
2. 优先级和节奏控制
经常我会问做系统设计的同学一个问题:对于这个业务场景而言,在系统设计上最需要把握的一个点是什么;这是一个关键问题,全面意味着考虑到了很多地方的问题,但通常业务需求实现都是有很强的时间要求的,因此在这个时候必须考虑清楚不同点的优先级,同时也包括技术方案在决策时也要做出取舍,有可能选了一个不是那么好的技术方案,但通过留下一些可改造的空间,为以后的重构做好铺垫,那就是很不错的,尤其技术同学有些时候比较容易陷入解决技术问题的场景去,但那个问题其实有可能不是现阶段最重要的。
优先级和节奏控制是我认为一个优秀的架构师的最佳体现,优先级意味着把握住了重点,可以确保在所设计的架构指导下业务实现不会出现大问题,节奏控制则意味着全面,知道随着业务发展该在什么时间点做什么事,为将来做好铺垫。
三
架构师技能
技能树
架构优化思路
架构优化一方面是优化系统交易链上的每个环节进行分析并优化,另一方面是对单一架构进行瓶颈点分析和调优。但是优化的目标大致相同,最终目的是提高系统的响应速度、吞吐量、降低各个模块之间的耦合。
优化原则
在应用系统的设计、开发过程用中,应始终把性能放在考虑的范围内。
确定清晰明确的性能目标是关键。
性能调优是伴随整个项目周期的,最好进行分阶段设定目标开展,在达到预期性能目标之后即可对本阶段工作进行总结和知识转移进入下一阶段调优工作。
必须保证调优后的程序运行正确。
性能更大程度是取决于良好的设计,调优技巧只是一个辅助手段。
调优过程是叠代渐进的过程,每次调优的结果要反馈到后续的代码开发中去。
性能调优不能以牺牲代码的可读性和维护性为代价。
后端优化手段
硬件升级
硬件问题对性能的影响不容忽视。
举一个例子:一个DB集群经常有慢SQL报警,业务排查下来发现SQL都很简单,该做的索引优化也都做了。后来DBA同学帮忙定位到问题是硬件过旧导致,将机械硬盘升级成固态硬盘之后报警立马消失了,效果立竿见影!
缓存化
缓存可以称的上是性能优化的利器,使用缓存时需要考虑缓存命中率、缓存更新、数据一致性、缓存穿透及雪崩、Value过大等问题,可以通过mutiGet将多次请求合并一次、异步访问等方式来提升缓存读取的性能。
产品逻辑优化
业务逻辑优化经常会容易被忽略,但效果却往往比数据库调优、JVM调优之类的来的更明显。
举一个例子,12306春运抢火车票的场景,由于访问的人多,用户点击“查票”之后系统会非常卡,进度条非常慢,作为用户,我们会习惯性的再去点“查票”,可能会连续点个好几次。假设平均一个用户点5次,则后端系统负载就增加了5倍!而其中80%的请求是重复请求。这个时候我们可以通过产品逻辑的方式来优化,比如,在用户点击查询之后将“按钮置灰”,或者通过JS控制xx秒只能只能提交一次请求等,有效的拦截了80%的无效流量。
服务化
做服务化最基础的是按业务做服务拆分,避免跨业务间的互相影响,数据和服务同时拆分。同一个业务内部我们还按计算密集型/IO密集型的服务拆分、C端/B端服务拆分、核心/非核心服务拆分、高频服务单独部署等原则做拆分。
异步化
异步化可以利用线程池、消息队列等方式实现。
使用线程池的时候一定要注意核心参数的设置,可以通过监控工具去观测实际创建、活跃、空闲的线程数,结合CPU、内存的使用率情况来做线程池调优。
另一种是通过NIO实现异步化,一切网络IO皆可异步:RPC框架、Servlet 3.0提供的异步技术、Apache HttpAsyncClient、缓存异步接口等等。
搜索引擎
复杂查询以及一些聚合计算不适合在数据库中做,可以利用搜索引擎来实现,另外搜索引擎还可以帮我们很好的解决跨库、跨数据源检索的场景。
数据库优化
数据库优化原则
优先考虑缓存降低对数据库的读操作。
再考虑读写分离,降低数据库写操作。
最后开始数据拆分,切分模式:首先垂直(纵向)拆分、再次水平拆分。
首先考虑按照业务垂直拆分。
再考虑水平拆分:先分库(设置数据路由规则,把数据分配到不同的库中)
最后再考虑分表,单表拆分到数据1000万以内。
数据库垂直、水平拆分
数据拆分前其实是要首先做准备工作的,然后才是开始数据拆分,我先讲拆分前需要做的事情:
第一步:采用分布式缓存redis、memcached等降低对数据库的读操作。
第二步:如果缓存使用过后,数据库访问量还是非常大,可以考虑数据库读、写分离原则。
第三步:当我们使用读写分离、缓存后,数据库的压力还是很大的时候,这就需要使用到数据库拆分了。
数据库拆分原则:就是指通过某种特定的条件,按照某个维度,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面以达到分散单库(主机)负载的效果。
垂直拆分
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面 。
比如淘宝中期开始的数据库端按照业务垂直拆分:按照业务交易数据库、用户数据库、商品数据库、店铺数据库等进行拆分。
优缺点
优点:
1. 拆分后业务清晰,拆分规则明确。
2. 系统之间整合或扩展容易。
3. 数据维护简单。
缺点:
1. 部分业务表无法join,只能通过接口方式解决,提高了系统复杂度。
2. 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高。
3. 事务处理复杂。
水平拆分
垂直拆分后遇到单机瓶颈,可以使用水平拆分。相对于垂直拆分的区别是:垂直拆分是把不同的表拆到不同的数据库中,而水平拆分是把同一个表拆到不同的数据库中。
相对于垂直拆分,水平拆分不是将表的数据做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中 的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。
分库分表需要涉及到对应的SQL路由规则主库备库等,例如:淘宝设计了一套TDDL来解决这些问题,应用端只需配置对应的规则即可,对应用端的没有任何侵入的设计。
水平拆分,总之,一般先分库,如果分库后查询仍然慢,于是按照分库的思想开始做分表的工作数据库采用分布式数据库(所有节点的数据加起来才算是整体数据),文件系统采用分布式文件系统任何强大的单一服务器都满足不了大型系统持续增长的业务需求,数据库读写分离随着业务的发展最终也将无法满足需求,需要使用分布式数据库及分布式文件系统来支撑。
总结
架构师是一个充满挑战的职业,知识面的宽窄往往决定着一个架构师的架构能力,所以在这一点上我比较赞成,就是要阅读大量的技术书籍,但我希望你不要仅限于软件相关的书籍,经常泡技术论坛,一方面可以结交朋友,一方面可以增加自己的知识面。
总之,想要成为架构师,需要有耐心,不断学习,拓宽自己的视野,不仅仅局限于自己眼前的项目,关注开源技术,关注热门技术社区的新动向。
技术方舟
技术方舟载你远航,去感受领略不一样的风景
#专注技术人的成长#
《架构宝典》
出品:中生代技术社区
最后感谢为本书付出大力支持的李晓时、右军、孔庆龙、李伟山、杨波、张逸、刘地生、田向阳、刘凡、王东、朱攀、朱永光、黄哲铿、王辉、陈宗、陈显铭、高磊、石涛生和曹洪伟;
点击阅读原文购买《架构宝典》,和本文作者李伟山老师一起学习架构
点个在看吧,我很在意你👇