单体架构
在早期90年代互联网发展中,产生了软件工程,并催生了以C语言为代表的面向对象的高级语言。同时,单体架构也由此产生。当时软件概念还没普及,面对需求更多以一个单体项目开发的功能模块,所有的代码逻辑耦合在一起,一两个人就可以负责所有的功能业务开发,对于当时的用户使用量来说,单体架构足够应付。单体架构的方式,直接干练,到目前为止使用量也不在少数,毕竟这种架构方式也符合人类便捷思维的一种方式。类似的提出面向对象思想之前,使用的面向过程思想,一个功能按照有序的顺序一步步编写有序调用,这也是人们倾向的思考思维。
很明显,我们能够看到单体架构的优势:
易于开发,直接使用开发工具创建一个项目即可入手开发。
易于部署,开发完之后,直接打包部署在适应的服务器,例如:apache,iis,tomcat等。
易于扩展,需要扩展的功能我们也可以直接下手开发,甚至可以将项目打包多份运行在多台服务器实现负载均衡。
然而,以现在用户使用量的角度来看单体架构,它的弊处也随处可见。庞大的单体代码库,会吓倒自己和同事,也会吓跑新手。一时接手也需要花不少时间去逐个理解,单体架构庞大之后没有清晰的模块划分,可能会随着时间推移,且每个人代码习惯也会面临不一样,导致模块被分解,整体代码变得越来越难理解,代码的质量也逐渐下降,也就是我们俗称的“shit mountain。”谁碰谁倒霉!IDE过载较大,面临成堆的代码量,你可能早上高兴上班,启动项目的时间就已经喝了两杯咖啡了,或许新同事的不正确操作引来一堆红色警告,上午时间没了,血压也上去了。持续部署的困难。面临大型单体应用程序,刚开始开发完很顺利,部署也很顺利。然而,产品经理每次经过你的岗位,面带微笑,提了一堆需求给你,今晚改完发布。改完之后你需要重新部署整个应用程序,有时还得先中断其他后台任务,无论受不受你当前更改的影响,最终导致问题的概率会增加。或许因为新需求改动了组件,一部署即error警告,此时整个项目便无法运行,或许你在代码里不小心写了一行让cpu飙升的代码,导致服务器宕机整个服务也无法使用了,真让人头大。扩展应用程序可能变得困难,单体架构扩展只能在本身程序里扩展。我们虽然可以通过复制部署到多台服务器或者云服务来部署实现负载均衡,并根据负载数量来调整实例数量(也就是拷贝部署多少个服务)。但是在与数据交互时,所有服务始终都是使用一个数据库访问所有数据,这很显然降低了缓存效率并增加了内存消耗和IO流量,也就是数据访问量上来了,本该走缓存了却直接跑去访问数据库,大量访问数据库的同时需要频繁调度内存以及频繁输送数据,这将会是很糟糕的情况。扩展开发的障碍。单体应用也会阻碍扩展开发,到了一定规模之后,我们很难将UI,商品,库存分开独立开发,都将在一个应用程序里开发,任何一个出问题或者拖延了开发周期都将会影响到整个的服务,团队也将必须协调开发工作和重新部署。需要对技术堆栈做出长期承诺。开发单体程序被迫使你在开发之初时选择的技术栈要保持一致。如果我们当初选择了C#开发,那么后期想使用Go开发,那么将会是一件困难的事情,因为单体程序很难兼容其他的技术栈使用,要么将选择重构,面对庞大的单体程序重构一堆“shit mountain”将会面临不小的挑战。说了单体应用的诸多缺点,并不是我在找茬,它本身不是缺点,是在于面对型应用和超大型应用的出现(单纯应用的庞大,用户数并不庞大),以及用户量剧增时体现出来的不适用性,迫切需要新的且适应的架构方式来解决我们的麻烦。