单机服务器、集群和分布式
单机服务器,故名思意,就是一台服务器提供所有功能,所有客户端的连接都在一台服务器上。 集群:每一台服务器独立运行一个工程的所有模块。 分布式:一个工程拆分了很多模块,每一个模块独立部署运行在一个服务器主机上,所有服务器协同工作共同提供服务,每一台服务器称作分布式的一个节点,根据节点的并发要求,对一个节点可以再做节点模块集群部署。 以聊天服务器为例,假设一个聊天服务器有以下功能:
ChatServer把用户管理、好友管理、群组管理、消息管理、后台管理都做了模块化处理,这些模块构成了完整的ChatServer,每个模块都包含特定的业务。 用户管理模块有用户登录,用户注册,用户注销,用户退出等功能业务。好友管理有添加好友,删除好友等功能业务。群组管理有添加群,创建群,解散群,群里踢人等功能业务。消息管理有离线消息,一对一的消息,群组消息等和功能业务。后台管理有广播消息,公告消息,活动消息等功能业务。
对单台物理机器来说,它的硬件资源是有限的。因为我们只有一台服务器,聊天服务器所能承受的用户的并发量是有限的。假设我们使用32位linux,给一个进程把资源开满,最多支持2万多人的在线。用户量上不去了。硬件资源不够,socket资源不够。 假设这个服务聊天器有5个模块,每个模块有几十上百个功能业务,这一套项目编译得花2个小时,部署得花3个小时。现在如果我们突然发现用户管理模块有个注销的业务里面有bug,但是改起来特别简单,就几行代码。但是这是一整套系统,得把整个项目的所有代码全部重新编译!这样又得花2个小时编译,运维部署3个小时!服务器还得停止服务。 系统中有些模块是属于CPU密集型(计算量大),有些模块是属于I/O密集型的(设备驱动 输入输出,网络I/O),造成各模块对硬件资源的需求是不一样。 有些模块是CPU密集型的,这些模块应该部署在CPU资源非常好的机器上,有些模块是I/O密集型的,这些模块应该部署在内存大,带宽好的机器上,不需要太强的CPU资源。不同模块属于不同的型,对硬件的需求不一样,打包在一套机器上,只能综合所有模块,提出平衡的供给需求,没办法针对性。
单机服务器存在以下缺点:
- ?受限于单台机器硬件资源,服务器所能承受的用户并发量有限
- ?任意模块的修改,都会导致整个项目代码重新编译,部署
- 各模块对硬件资源的需求不一样,有些事IO密集型,有些是CPU密集型,需要全部考虑
服务器集群
每一台服务器都是独立的系统 集群就是通过扩充多台服务器,解决单台机器硬件资源受限问题,横向扩充机器数量,每台机器都能提供所有的服务,假如ChatServer1崩了,只有ChatServer2和ChatServer3没问题,就不影响服务。
集群解决了单台机器硬件资源受限的问题,可以通过扩充机器来提高性能,让硬件资源可以扩充,单台服务器崩溃不影响其他服务器的运行。
?但模块修改会导致整个项目要重新在每台服务器上重新编译,部署,代价比单台服务器还大
?各模块硬件资源需求不同的问题还是没有解决,同时也带来一个新问题:有些模块并发需求不大,根本不需要集群部署。比如后台管理模块,使用的用户只有管理员,服务频次肯定不高,但把这个模块也做集群部署到多台机器上,就显得太多余了。
分布式
各模块进行拆分组合,单独部署在不同的机器上,对于并发量需求高的服务模块进行集群部署,IO密集型的服务模块选择在内存大,带宽好的机器上部署,多个机器构成一个完整系统,各服务节点协同为客户端提供服务。 假设ChatServer用户管理和消息管理对并发要求较高,就把这两个服务抽取出来组合到一起,对这两个服务组合单独做集群部署。 好友群组用户管理需要的频繁的读写磁盘,选择在内存大,带宽好的机器上部署。 而后台管理两者要求都不高,就做普通部署即可。
假设图中的后台管理节点机器崩了,ChatServer就无法提供后台管理服务,但其他不依赖后台管理的服务同样可以照常运行。 假设后台管理的某个业务除了BUG,需要修复,只需要把后台管理这个服务模块重新部署,其他服务并不需要重新部署更新。 ?对于并发量高的模块,拓充多个分布式结点(集群),提高并发量。有的模块并发能力小,部署在一台机器就可以。 把CPU密集型的模块部署在CPU资源好的机器上。把内存小的模块部署在硬盘资源少的机器上。把I/O密集型的模块部署在CPU不是很好的机器上。
分布式需要客服的问题
?软件模块怎么划分? 要做到各服务间完全解耦是不可能的,模块和模块间的界限不清晰,模块服务的提供需要依赖另一个模块业务逻辑(需要调用另一个模块的函数代码),各模块可能会出现大量重复的代码逻辑。 处理不好就会造成大量的代码重复,如果各模块间对重复代码做不同的更新,提供的业务就会造成冲突。
?各模块之间怎么访问(跨进程访问)?
假设用户登录成功了,想展示好友列表,但是用户管理模块只负责用户的登录,退出,修改密码等业务功能,它并不知道好友列表,负责管理好友的是好友管理模块。通过传入用户id,得出好友列表。在单机或者集群中,这些模块是运行在一个服务器进程当中,相当于自己调用自己。但是在分布式中,用户管理和好友管理部署在不同的进程中,用户管理进程如何调用另一个模块上的业务呢?就需要实现RPC(Remove Procedure Call)远程方法调用通信实现。
|