一种能够提升CS架构中服务端性能的方法

服务端并发处理数据

目前基本都是在数据处理阶段采用并发技术,这主要有两个原因:第一,一般情况下瓶颈都卡在数据处理阶段,比如磁盘读写;第二,实现不了并发接收数据,因为服务端口,比如WEB服务80端口,只能绑定到一个socket上。

对于有些使用场景,比如客户端向服务端推送大量数据包,这时候如果接收端不能并发处理可能会存在丢包丢数据的情况。

为了能够实现并发接收数据,可以为服务端绑定多个服务器端口。但是标准的端口号只有一个,比如WEB服务80端口,绑定的其它扩展端口,网络中的其它客户端是不知道的,客户端只知道标准的80端口。

如果要实现并发数据接收,必须要绑定不同的端口号。但在Linux系统中一个服务对外只有一个端口号比如WEB服务80端口、MySQL服务3306端口,所以我们需要做到内部绑定多个端口,同时对外还是只有一个端口。

这里借鉴NAT地址转换的原理,使用一个端口映射模块,将多个子服务进程的不同端口号映射到一个固定的端口上,该模块对客户端来讲是透明的,对外服务端提供的还是一个标准端口号。

一种能够提升CS架构中服务端性能的方法

多端口绑定

典型的C/S结构中的服务端都绑定一个固定的端口号如WEB服务的80端口、MySQL服务的3306端口。该方案在服务端程序启动时除了启动服务端指定端口的服务外比如MySQL的3306,还同时加载了若干子服务进程的端口号,比如33060、33061、33062等等。各个子程序分别侦听其加载的端口号。

一种能够提升CS架构中服务端性能的方法

端口映射 

服务端扩展的若干端口号对客户端是透明的,客户端只知道服务端固定的端口号比如MySql的3306,所以客户端请求的目的端口号都是3306。为了支持扩展出来的端口号,需要增加一个端口映射模块,将固定的端口号映射到扩展的众多端口号中。

一种能够提升CS架构中服务端性能的方法

 

如上图,客户端发起的请求报文中的目的端口号都是固定端口,比如MySQL的3306,而服务端希望这些请求访问的是子服务侦听的端口号。所以端口映射模块需要将客户端请求报文中的固定端口号替换成子服务侦听的端口号,修改端口后只需要计算TCP或者UDP的头部的校验码,所以性能还是有保证的。

在替换之前,为了避免多个客户端集中访问某一个扩展服务(扩展服务本身还是支持并发访问的),模块首先根据算法将一个客户端分配到指定的扩展服务上。

端口映射模块利用Linux的netfliter的Hook机制,替换端口后重新提交到协议栈中,该方法能够做到报文零拷贝,利用inmod和rmmod动态加载、删除模块。