假设一个大系统分为A、B、C、D、E五个模块,也可以认为是五个基本的服务,该系统靠这五个模块协同工作,共同为用户提供服务。
单机
单机:显然,单机表名该系统完完全全的部署在该台机器上,拥有完整的服务,这样做的第一个弊端也是很明显的,假如该系统需要承载很高的并发量,那么单台机器很难胜任,因为单台机器的硬件资源是有限的。
集群
那么很容易想到的一个解决方案是将该系统的整套服务部署在多台机器上,这也就是集群的由来,这样提高了并发量(当然具体提高了多少并不能通过服务器的数量而线性的相加),也提高了容错性,因为通过集群处理请求,显然是需要用到负载均衡器来分发请求,这样也保证了某台机器不会负载量过高而宕机。
再看下一个由单机引发的问题,由于A、B、C、D、E模块同属于一个系统,那么任何一个模块的修改,都需要重新编译代码,然后重新部署,很大的修改也就罢了,如果是很微小的修改但又不得不改的情况,重新编译打包这种耗时耗力的操作是不能忍受的,在项目很大的情况更是无法忍受(大型项目重新编译可能需要几小时或者半天,部署也是一样)。
那么集群架构是否会解决上述问题?显然没能解决,反而大大加重了重新部署的工作量,因为是多台机器,每台机器都是整套的服务,那么某个模块的修改,会导致所有部署该服务的机器都要重新部署,在机器部署的数量数量足够多的时候,这对程序员来说也是不能够接受的。
先不谈怎么解决,再看单机的下一个比较具有代表性的问题,如果A、B模块是IO密集型的服务(例如网络IO),C、D模块是计算密集型的服务(也叫CPU密集型任务,例如矩阵乘法、3D建模等等),E模块相对普通。那么单机很容易暴露出一个问题,即就一台机器,这个资源显然分配是不合理的,E模块不应该和AB模块或是CD模块等同地位的抢占CPU资源或是网络带宽的资源。对于AB和CD这两个模块更是竞争激烈。
集群也不能解决这个问题,因为集群本质上就是把单机水平扩展成了多台机器,每台机器资源还是同单机一样资源分配是不合理的。
怎么解决?这就需要用到分布式。
分布式
分布式概念:将一个大的系统拆分成多个不同的模块,每个或每几个模块部署在一台服务器上,所有服务器协同工作共同提供服务,每台服务器称作分布式的一个结点,每个结点又可以根据并发量的不同,把某个结点进行集群化部署在多台服务器。
根据分布式的概念,可以将AB、CD、E模块单独放在一个服务器上,即第一台服务器有着AB模块、第二台服务器上有着CD模块、E模块单独在第三台服务器上。这样很好的解决了单机和集群共有的第三个问题,因为IO密集型和CPU密集型模块分别部署在不同的服务器上,针对第一台服务器可以提高服务器的网络带宽、内存配置(IO密集),针对第二台服务器可以配备更好的CPU硬件资源,第三台服务器普通配置即可,那么这样很好的解决了不同模块资源分配不合理的问题。且还可以针对并发量要求很高的模块集群化部署,例如AB模块,第一台服务器可以扩展为多台服务器共同提高并发的承载量
。
第二个问题能解决吗?也即某个模块的修改导致整个系统的重新编译在部署?在分布式的环境下显然不存在这个问题,某个模块需要修改,修改完之后只需要单单编译这一小模块然后部署其所在的某台服务器即可,不会影响其他模块,这大大提升了工作效率。
分布式面临的问题:
1、如何更好的把一个大的系统划分为一个个模块?
2、因为整个系统需要所有模块协同工作,那么必然涉及到远程调用问题(rpc)
即:节点1服务器上的服务1如何调用节点2服务器上的服务2的业务方法?
节点1服务器上的服务1如何调用节点1服务器上的服务2的业务方法?