如果能够学到架构理论,是一件很幸福的事,而要是能够从0到1搭建一个完整的大型网站,并且,将其投入到生活当中,还能被大多数人所使用,则是一件很幸运的事了。
这系列博客不谈业务,只谈技术,也暂且不论网站最终是否能够有幸上线。这些问题,我们技术人员都把控不了。我只是想把工作做好,在这个过程中自己也能学到东西,有所成长。
怎样的架构才是合理
有一句知名的话,叫做 “不结合业务的架构都是耍流氓” 。我想,这里所指的应该是你的网站体系不会有十万的用户,而你却针对其涉及了一个能抗住百万并发量的这种过度设计吧。当然,对于技术人员而言,能从中接触到很多技能,但导致整个项目周期不得不延长,这是不可取的。
所以,前期一定不要过度设计。
无论十万也好,百万也罢,底层是通的,只是前期,我们不在资源以及体系上投入太大的量,把时间控制在项目周期内。为什么讲底层是通的,就是前期在技术选型时,你需要考虑到后期可能到来的大量用户增长,考虑到将来需要面临的高并发问题,所以,你选择的技术需要在后期能够平滑的迁移,在设计时,你需要以发展的眼光来看。
比如,我们在前期选择了 Zookeeper
作为注册中心,后期系统体量大了,那么,我可以部署 Zookeeper
集群。这没有什么问题,可再到后来,我们发现,Zookeeper
集群会在出故障以后,出现短暂时间内不可用的现象。我们开始去排查问题,发现了原来 Zookeeper
是 CP
模型,在这期间,我们又发现了 AP
模型的 etcd
。现在,我们就不得不面临选择了,是临时换将呢?还是继续忍受着这一小点时间的不可用?如果在前期考虑了这些问题,那么,遇到这样进退两难的场景就比较少了。
所以,技术选型很重要。
讲到这里也就很明了了,合理的架构存在一个度。这个度,在时间上不会变的不可把控,在技术上不会陷入窘境,当然,最根本的,满足业务的情况下,考虑其拓展性。
如今大型网站的趋势又是如何
我想单体应用这个不用说了吧,从最开始的单体应用、前后端分离到现在的分布式开发,这是一个已然的定势,你无需再去尝试(PS:个人小型网站除外)。
而微服务又是如今一个炙手可热的话题,网站到底要不要服务化,如果将来会是一个巨无霸,那么提早布局,绝对错不了。
微服务相关技术,我们大多会选用市场上成熟的方案,并不会去自研,这往往托福于大公司。
Spring Cloud Alibaba
Spring Cloud
以上是两个方向,本质上的不同在于远程调用以及整个生态体系,Spring Cloud Alibaba
使用的是 Dubbo RPC
,而 Spring Cloud
使用的是基于 HTTP
协议的远程调用。Dubbo
的优势在于使用的是长连接,速度上会更有优势,但由于其调用方和提供方需要依赖公共 API
,有一定的耦合。而基于 HTTP
协议的远程调用则不强制依赖共同的API
,速度上则会相比较弱。
而关于最新的 Service Mesh
,它与微服务各有好处,我建议前期先进行微服务开发,当到达一定规模后,再考虑是否需要 mesh
。
所以,大型网站的趋势一定是服务化。
谈谈模块化,分布式,微服务,Service Mesh
下面都是个人的一些拙见,仅供参考。
模块化是拆分单体应用的第一步,毕竟,单体应用能够使用的资源始终有限,如果不能将其拆分,就像把整个动物园放在了深山里,明明有着能够容纳百万游客的量,却因为规划不当,每天只能接待几千位游客。
现在我们来模拟动物这个场景,从一开始这个动物园未做任何规划,所有物种都放在了一起(PS:假设它们会和平相处,好不好?)。现在呢,把这动物园做了拆分,分成了狮子山,猴子山,鳄鱼谷,鸟语花香林等,动物园能够容纳的人数增长了几倍。
渐渐的,动物园开始有了起色,游客开始反馈动物园不再那么拥挤了。可好景不长,来观赏的游客越来越多,尤其是在狮子山,经常挤满了人,不得已,我们又要开始规划了。既然狮子山游客多,那么我们就多划分几个狮子山出来,那这又带来一个问题,既然划分出来的狮子山都一样,那么我们就没必要让游客每个狮子山都看一遍,所以狮子山需要自己来调度这些游客,我们给狮子山增加一个游客调度中心,由它来统一规划这些游客。
狮子山游客调度中心仍然受总调度中心管控。如果现在调度中心要做更换设备等操作,那么势必会影响到狮子山游客调度中心。而现在狮子山游客调度中心又和狮子山牵扯的太深,担心一不小心改到狮子山的设备,那么到时候,放出来一只狮子,可就不好了。所以,我们需要考虑拆分狮子山和它的游客调度中心。
现在,狮子山和它的游客调度中心隔离开了,再也不用担心游客调度中心的调整,会影响到狮子山了。
模块化更像是将一个整体拆分成多个模块,而这模块并不是一个成熟的个体,而分布式则将拆分出来的模块根据需要灵活配置(需求高多配置几份),并将其部署成一个成熟的个体,而这个成熟的个体就可以称之为服务。
我们都知道,服务化后,服务间的调用必须通过远程调用,这就导致每个服务都需要嵌入远程调用框架。这种客户端嵌入式代理,耦合过深。其实呢,服务并不关心具体使用的是哪个远程调用框架,所以 Service Mesh
就应运而生,它将远程调用框架从服务中剥离了出来,抽象为一个代理,单独部署在同一个主机上,让服务通过本地调用这个代理。并且,处于本机上的其它服务也能够使用这个代理,调用其它服务,这就是解耦后的好处。
如果将动物园比做一个大型网站,你有没有发现它能够容纳的仍然有限,入口只有那么一个,程序上的话来说,吞吐量低,那么,我们多部署几个动物园不就解决这个问题了嘛?可外界又如何知道这些动物园呢?且看下图大型完整高并发一项。
实践出真知?
只有真真切切整理了一个大型网站的架构以后,你才会发现问题,知道并接受还有很多没发现的问题。
上面讨论的大多问题,更像是一种思想,而这张图,则反映到实际。这其中涉及的技术点颇多,需要我能够不间断的更新这些技术问题。
下一篇会结合技术,给出一个可进行压测的大型网站 Demo
。
我与风来
认认真真学习,做思想的产出者,而不是文字的搬运工
错误之处,还望指出