这么一个场景:一个要承载高并发、具备高性能的后台服务,每每会有多个不一样的应用服务。问题来了,你会怎样设计架构呢?
nginx
以下图所示,为了共用一个稳定高效的网络处理功能,把全部服务写在一个进程里。安全
接下来悲剧一幕幕就要上演了,若是各个模块是多人协做开发,网络库的做者得想办法设计个插件机制供各个应用挂载,开发时不管是人员或者代码都耦合很是严重,大大影响协做、开发效率,后期要增减一个应用也得大动手脚。好吧,这还能够忍受,问题是写应用的人技术水准还可能层次不齐,一个短板就可能形成整个服务崩溃。服务器
彼此的依赖太严重,效率低下,责任推诿让各个协做者们苦不堪言,各个应用服务的做者决定在本身的服务里单独提供网络模块。就有了以下图的状况,每一个应用服务的提供者本身还要提供网络功能模块微信
接下来悲剧又一幕幕上演了,要知道高性能网络服务模块须要的技术含量之高不是人人均可以写好的,即便咱都能写好或者统一使用了一个牛X的网络库,你对客户端暴露那么多服务地址不讨人嫌嘛,甚至在我身边还有采用专门写一个集中服务来供客户端获取各应用服务的地址的设计......。网络
经过对上面两种设计的批判,你们是否是会想,这架构缺陷很明显,确定采用的人不多吧,可是说实在的我已经遇到屡次这种设计了,也许是观点不一样吧,我对以上两种设计在上述场景下持否认态度。架构
那咱们应该采用怎样的设计适应这种场景呢?并发
以下图,这是腾讯和微信的部分后台设计架构图负载均衡
能够看到都会有个接入服务,而后把不一样的请求分发给不一样的应用服务。其实这个接入服务就是“网关服务”,这种设计在nginx的负载均衡和反向代理功能中都有体现,另外在网游服务器中也大量采用了这种设计思路,由网关服务器将不一样的请求分发到不一样的应用服务上,等应用服务器处理完后再经过网关服务器转发给客户。运维
那这种设计的优势在哪呢?ide
借用知乎王明雨知友的一个比喻:
把服务器想象成饭店,没有网关服务器的状况,就如同每个厨师服务一桌顾客,从点菜开始到炒菜到上菜到收银,有n个厨师就只能服务n桌顾客。有了网关服务器的话,网关服务器就成了强大的服务员,把招呼,点菜、上菜和收银的活都作了,厨师只须要专心炒菜就行。这样饭店的效率就大大提升了。
这样能够把要承载高并发,高性能任务的网络服务独立出来专门作好,作强(对于http协议的场景,能够直接用nginx作网关服务器)。这样各个应用只需把重点放在对业务逻辑的处理便可。从技术架构和项目协做上都作到了解耦。
加强了系统的健壮性,一个应用出现故障并不会对其余应用产生影响。后期运维也好作灰度更迭。
有应用集群的状况下,能够经过网关服务器作负载均衡,把请求分发在负载低的服务器上。
再引用一个游戏公司对网关服务器的评价:
服务器架构
采用带网关的服务器架构,将客户端与游戏服务器隔离,相比传统的客户端-服务端直连的架构有以下优点:
(1)做为网络通讯的中转站,负责维护将内网和外网隔离开,使外部没法直接访问内部服务器,保障内网服务器的安全,必定程度上减小外挂的***。
(2)网关服务器负责解析数据包、加解密、超时处理和必定逻辑处理,这样能够提早过滤掉错误包和非法数据包。
(3)客户端程序只需创建与网关服务器的链接便可进入游戏,无需与其它游戏服务器同时创建多条链接,节省了客户端和服务器程序的网络资源开销。
服务端高度模块化
大厅服务端将登陆、用户信息、房间信息、平常任务、道具、银行、比赛、排行、活动、网站等11个功能拆分红11个独立的服务端子模块,模块之间不会相互影响,即便某模块出错也不会影响全局,提升了服务端的稳定性;与子模块平行的新功能能够自由新增挂载,扩展性强。