甘肃省建设厅不动产网站,如何做网站推广达到好的效果,南昌网站外包,重庆网站建设夹夹虫作为程序员#xff0c;很多人都希望成为一名架构师#xff0c;但并非简单地通过编程技能就能够达成这一目标。事实上#xff0c;优秀的程序员和架构师之间存在一个明显的鸿沟——不确定性。 编程的本质是确定性的#xff0c;也就是说#xff0c;对于同一段代码#xff0c…作为程序员很多人都希望成为一名架构师但并非简单地通过编程技能就能够达成这一目标。事实上优秀的程序员和架构师之间存在一个明显的鸿沟——不确定性。 编程的本质是确定性的也就是说对于同一段代码无论由谁编写在何时执行其结果应该是确定的尽管有可能存在bug。相比之下架构设计本质上是不确定的。同一系统不同公司的架构可能存在较大的差异但最终都能正常运转。在面对多种可能性时架构师需要进行选择而这种选择往往会让人陷入两难的境地。 例如 是否选择业界最先进的技术还是选择团队目前最熟悉的技术 是否选择Google的Angular或Facebook的React 是否选择MySQL或MongoDB 对于这些问题架构师需要依赖自己的经验和直觉进行决策因为架构设计领域并没有一套通用的规范来指导架构师。但是通过研究架构设计的发展历史和多个公司的架构发展过程可以发现一些共性原则即合适原则、简单原则和演化原则。在遵循这些原则的基础上架构师可以做出最好的选择克服不确定性。 合适原则 合适原则宣言“合适优于业界领先”。 很多优秀的技术人员都怀有强烈的技术情结他们总想通过挑战自我实现甚至超越业界领先水平从而在年终KPI绩效总结中留下自己的印记。然而这种做法往往会导致失败。在互联网行业我见过许多“亿级用户平台”的失败案例例如某个几个人规模的业务团队雄心勃勃地想要和腾讯QQ一较高下但最终却以失败告终。为什么会这样呢 实现任何梦想都需要脚踏实地的付出。这里的“脚踏实地”主要体现在以下几个方面。 1.将军难打无兵之仗。 大公司的分工比较细每个小系统都可能由一个小组负责。但在大部分公司整个研发团队可能只有100多人某个业务团队可能只有十几个人。在这种情况下想要完成类似于几十人团队才能完成的事情并且还要做得更好难度可想而知。 2.罗马不是一天建成的。 业界领先的很多方案并不是一群天才某个时期灵机一动就做出来的。它们经过了数年的发展才逐步完善和初具规模。如果没有足够的积累和历练靠拍脑袋或者头脑风暴是无法和真正的实战相比的。 3.冰山下面才是关键。 业界领先的方案大多是“逼”出来的。随着业务的发展和量变导致质变新的问题出现了已有的方式无法应对这些问题需要用新的方案来解决。通过不断的创新和尝试业界领先的方案才得以形成。 如果没有类似于腾讯那样海量用户积累、大量的人力资源、优秀的业务场景想要建立一个“亿级用户平台”就注定会失败。真正优秀的架构应该是在企业当前的人力、条件、业务等各种约束下设计出来的能够将资源合理地整合在一起并发挥出最大的功效并且能够快速落地。许多BAT公司的架构师到了小公司或创业团队却无法创造出成果因为他们缺乏大公司平台、资源和积累的支持他们只是生搬硬套大公司的做法这样的做法成功的概率非常低。 因此真正优秀的架构设计应该是在实际条件下的切实可行的设计将资源合理利用并能够快速落地。成功的架构设计需要充分考虑公司当前的资源、团队能力和业务需求不断优化和改进不断学习和尝试新的方法和技术以适应日益变化的市场和业务环境。同时我们也需要认识到技术的发展需要时间需要不断的积累和经验只有在大量的实践中才能不断提升自己的技术水平。 简单原则 简单原则宣言“简单优于复杂”。 确实在软件领域过度追求复杂性往往会导致设计出来的系统难以维护、扩展和调试进而影响整个团队的工作效率。因此我们需要转变思路不要将复杂性作为评价架构的主要指标而是要以系统的实际需求和问题为出发点遵循合适原则、简单原则、演化原则以最小的复杂度满足系统的需求。简单来说就是要“追求简单”。 追求简单不等于简单粗暴而是在不降低系统性能、稳定性和可扩展性的前提下以最少的设计和实现来满足需求。这需要架构师具备全面的技术能力和对系统的深刻理解能够对复杂性进行有效的把控和分解从而将系统的设计和实现变得更加简单明了。 此外简单也不意味着架构师可以忽略细节和考虑不周。实际上追求简单需要更加注重细节和全局的把握要通过精心的设计和实现来避免各种潜在的问题和风险。只有在这样的基础上才能够设计出真正合适的、简单的、可演化的软件架构。 软件领域的复杂性体现在两个方面 1.结构的复杂性 结构复杂的系统几乎毫无例外具备两个特点 组成复杂系统的组件数量更多 同时这些组件之间的关系也更加复杂。 我以图形的方式来说明复杂性 2个组件组成的系统 3个组件组成的系统 4个组件组成的系统 5个组件组成的系统 为了避免这些问题我们需要尽量简化架构。简化架构并不意味着牺牲可用性或者功能而是在保证功能和可用性的前提下尽量减少组件的数量和组件之间的关系复杂度。 一个好的架构需要在多方面权衡如系统可用性、开发效率、维护成本、可扩展性等等。因此在进行架构设计时需要从多个角度出发考虑系统的实际需求和限制条件逐步迭代优化设计方案而不是一开始就试图设计出最完美的方案。 另外一个好的架构设计需要在实践中不断迭代和优化。系统运行过程中会出现各种各样的问题需要不断地对架构进行调整和优化。同时随着业务的发展和变化架构设计也需要随之变化及时做出调整和优化才能够保证系统的稳定性和可持续发展。 2.逻辑的复杂性 意识到结构的复杂性后我们的第一反应可能就是“降低组件数量”毕竟组件数量越少系统结构越简。最简单的结构当然就是整个系统只有一个组件即系统本身所有的功能和逻辑都在这一个组件中实现。 不幸的是这样做是行不通的原因在于除了结构的复杂性还有逻辑的复杂性即如果某个组件的逻辑太复杂一样会带来各种问题。 逻辑复杂的组件一个典型特征就是单个组件承担了太多的功能。以电商业务为例常见的功能有商品管理、商品搜索、商品展示、订单管理、用户管理、支付、发货、客服……把这些功能全部在一个组件中实现就是典型的逻辑复杂性。 逻辑复杂几乎会导致软件工程的每个环节都有问题假设现在淘宝将这些功能全部在单一的组件中实现可以想象一下这个恐怖的场景 系统会很庞大可能是上百万、上千万的代码规模“clone”一次代码要30分钟。 几十、上百人维护这一套代码某个“菜鸟”不小心改了一行代码导致整站崩溃。 需求像雪片般飞来为了应对开几十个代码分支然后各种分支合并、各种分支覆盖。 产品、研发、测试、项目管理不停地开会讨论版本计划协调资源解决冲突。 版本太多每天都要上线几十个版本系统每隔1个小时重启一次。 线上运行出现故障几十个人扑上去定位和处理一间小黑屋都装不下所有人整个办公区闹翻天。 …… 不用多说肯定谁都无法忍受这样的场景。 但是为什么复杂的电路就意味更强大的功能而复杂的架构却有很多问题呢根本原因在于电路一旦设计好后进入生产就不会再变复杂性只是在设计时带来影响而一个软件系统在投入使用后后续还有源源不断的需求要实现因此要不断地修改系统复杂性在整个系统生命周期中都有很大影响。 功能复杂的组件另外一个典型特征就是采用了复杂的算法。复杂算法导致的问题主要是难以理解进而导致难以实现、难以修改并且出了问题难以快速解决。 以ZooKeeper为例ZooKeeper本身的功能主要就是选举为了实现分布式下的选举采用了ZAB协议所以ZooKeeper功能虽然相对简单但系统实现却比较复杂。相比之下etcd就要简单一些因为etcd采用的是Raft算法相比ZAB协议Raft算法更加容易理解更加容易实现。 综合前面的分析我们可以看到无论是结构的复杂性还是逻辑的复杂性都会存在各种问题所以架构设计时如果简单的方案和复杂的方案都可以满足需求最好选择简单的方案。《UNIX编程艺术》总结的KISSKeep It Simple, Stupid!原则一样适应于架构设计。 在架构设计中我们应该遵循KISS原则尽量让架构设计简单而易于理解和维护。另外我们还可以通过以下几种方式来避免复杂性问题 将系统分解为小的组件。每个组件都应该尽可能地简单只实现一个功能。这样可以避免单个组件变得过于复杂同时也方便组件的维护和升级。 采用标准化的组件。通过采用标准化的组件可以避免重新发明轮子也可以减少对复杂组件的依赖。 避免过度设计。过度设计往往会导致代码过于复杂难以维护。在设计时应该尽量避免不必要的设计只实现必要的功能。 尽量采用简单的算法。尽量使用简单的算法可以使系统更加易于理解和维护。对于一些比较复杂的算法可以考虑采用现成的库避免重复造轮子。 借鉴已有的成功经验。在架构设计时可以参考已有的成功案例借鉴其中的经验和教训避免犯类似的错误。 总之架构设计是一门艺术需要不断地思考和实践才能设计出简单、易于理解和维护的系统。 演化原则 演化原则宣言“演化优于一步到位”。 软件架构从字面意思理解和建筑结构非常类似事实上“架构”这个词就是建筑领域的专业名词维基百科对“软件架构”的定义中有一段话描述了这种相似性 从和目的、主题、材料和结构的联系上来说软件架构可以和建筑物的架构相比拟。 例如软件架构描述的是一个软件系统的结构包括各个模块以及这些模块的关系建筑架构描述的是一幢建筑的结构包括各个部件以及这些部件如何有机地组成成一幢完美的建筑。 然而字面意思上的相似性却掩盖了一个本质上的差异建筑一旦完成甚至一旦开建就不可再变而软件却需要根据业务的发展不断地变化 古埃及的吉萨大金字塔4000多年前完成的到现在还是当初的架构。 中国的明长城600多年前完成的现在保存下来的长城还是当年的结构。 美国白宫1800年建成200年来进行了几次扩展但整体结构并无变化只是在旁边的空地扩建或者改造内部的布局。 对比一下我们来看看软件架构。 Windows系统的发展历史 如果对比Windows 8的架构和Windows 1.0的架构就会发现它们其实是两个不同的系统了 Android的发展历史 http://www.dappworld.com/wp-content/uploads/2015/09/Android-History-Dappworld.jpg 同样Android 6.0和Android 1.6的差异也很大。 软件架构需要根据业务发展不断变化所以在做架构设计时应该采用迭代的方式而不是一步到位。这样做的好处是可以让架构师随着业务的变化逐渐深入了解业务需求同时也可以避免设计出过度复杂、不切实际的方案。 另外预测和分析的确是不可靠的但是我们可以采用一些技术手段来帮助我们应对变化。比如可以采用微服务架构将系统划分成若干个小服务每个服务都可以独立开发、测试、部署和扩展。这样一来当业务需求发生变化时只需要修改涉及到的服务而不用对整个系统进行修改。此外还可以采用容器技术通过容器化应用程序来实现快速部署和扩展以应对业务变化带来的挑战。 总之软件架构需要根据业务发展不断变化我们应该采用迭代的方式来设计架构并采用一些技术手段来帮助我们应对变化。同时我们也需要明确软件架构永远不可能一劳永逸只有不断地学习和改进才能保持软件架构的健康和持续性。 考虑到软件架构需要根据业务发展不断变化这个本质特点 软件架构设计其实更加类似于大自然“设计”一个生物通过演化让生物适应环境逐步变得更加强大 首先生物要适应当时的环境。 其次生物需要不断地繁殖将有利的基因传递下去将不利的基因剔除或者修复。 第三当环境变化时生物要能够快速改变以适应环境变化如果生物无法调整就被自然淘汰新的生物会保留一部分原来被淘汰生物的基因。 软件架构设计同样是类似的过程 首先设计出来的架构要满足当时的业务需要。 其次架构要不断地在实际应用过程中迭代保留优秀的设计修复有缺陷的设计改正错误的设计去掉无用的设计使得架构逐渐完善。 第三当业务发生变化时架构要扩展、重构甚至重写代码也许会重写但有价值的经验、教训、逻辑、设计等类似生物体内的基因却可以在新架构中延续。 因此架构师在设计软件架构时需要始终关注业务需求不断调整和改进架构以适应业务的发展。架构设计不应该是一次性的而是一个持续演化的过程。同时要注重简单性避免过度复杂的架构设计这样才能更好地满足业务需求提高系统的可靠性和可维护性。 小结 以上的这三个原则都是为了应对“不确定性”而提出的帮助架构师在复杂、快速变化的业务环境下做出更好的决策。 需要注意的是这些原则并不是刻板的规则而是指导思想。在实践中架构师需要根据具体情况进行权衡和调整。有时候一个复杂的方案可能确实更适合当前的业务需求有时候一个一步到位的方案也可能更符合业务发展的需要。架构师需要根据自己的经验和专业知识综合考虑各种因素做出最适合当前业务的决策。 最后需要强调的是架构设计并不是一项孤立的技术活动而是需要和业务、运维、开发等各个环节协同配合的。只有将架构设计和整个软件开发、运维流程无缝衔接才能真正实现架构的价值为业务的成功提供坚实的支持。 本文由 mdnice 多平台发布