简述一种高效网络服务器的设计思路

在我们实现的分布式服务器中,每个节点都存有时空数据,这些节点上的时空数据利用RTree进行索引。每个节点同时保存着路由(邻居节点)信息。客户端可以向服务器端发送数据查询请求。服务器负责接收请求,并根据请求的类型进行相应的处理, 包括查询本地的数据,转发请求到邻居节点。

时空数据是以数据流的形式源源不断的插入到服务器中。当某个节点的数据达到系统预定义的阈值时,该节点将分裂成两个节点。我们将计算数据的***划分策略划分数据,并将划分的数据迁移到新的节点上。同时更新当前节点和新建节点的路由信息。

  针对上面的要求,我们的服务器需要满足以下两个目标:

满足高并发的数据查询请求和数据传输请求

同时处理长连接和短连接

服务器中同时存在两种连接方式:长连接和短连接。长连接是指Client端与Server端先建立通讯连接,连接建立以后不断开,然后再进行报文的发送和接收。长连接常用于点对点的通讯,在服务器中,数据传输采用长连接。短连接是指Client端和Server端只有在进行一次报文收发操作时才进行通讯连接,操作完毕以后立即关闭连接。短连接一般针对一点对多点的通讯,如多个Client连接一个Server。在服务器中,数据查询请求采用短连接。

  常见的网络服务器采用以下几种方式:

一个线程服务一个客户端,使用阻塞I/O

一个线程服务多个客户端,使用非阻塞I/O

一个线程服务多个客户端,使用异步I/O

第1种方式缺点在于当并发连接数过高时,操作系统同时处理几百个线程会有性能问题。而且在服务器硬件配置不改变的情况下,随着连接数的增加,将会导致性能急剧下降。第3种方式目前在Unix上还没有普遍的应用,因此,在我们的系统中并没有采用。第2种方式是将网络句柄设置为非阻塞模式,然后使用select或者poll IO多路复用技术来告知那个句柄已经有数据在等待处理。在此模型下,由系统内核来告知应用程序某个网络句柄的状态。这种模型也就是传统的IO多路复用模型,是目前大部分网络服务器的解决方案。

我们的服务器是基于Linux开发的,在Linux上,实现IO多路复用有几个主要的技术,分别是select模型,poll模型和epoll模型。

select模型***的缺点是***并发数限制,因为一个进程所打开的socket FD(文件描述符)是有限制的,默认是1024,因此select模型的***并发数就被限制了。当然,我们可以通过修改系统参数增大***并发数,然而由于select的每次调用都会线性扫描全部的socket FD集合。当socket FD增大时,会导致服务器效率线性下降。

poll模型基本上和select在效率上是一样的,select的问题在poll模型中也没有被解决。

epoll模型是目前比较优秀的IO多路复用模型,首先,epoll没有***并发连接的限制,上限是整个系统***可以打开的socket FD数目,这个数远大于2048,一般这个数目和系统内存关系很大,1G内存的机器的***sockef FD数目可以达到10万左右。其次,epoll***的优点在于它只关心活跃的连接,而跟连接总数无关。因此在实际的网络环境中,epoll的效率会远高于select和poll。

  鉴于epoll的优点,我们的服务器采用了epoll作为IO多路复用的基本技术。

常见的基于epoll的设计模式主要为单线程的事件循环,用于一些非阻塞的业务逻辑开发是很高效的,然而,在我们的服务器开发中,涉及传输数据。转发请求的需求,耗时比较长。因此,单线程的epoll并不能满足我们的需要。下面用一个简单的例子来说明单线程模式下epoll的缺点。

简述一种高效网络服务器的设计思路插图亿华云

由于是单线程模型,当某个客户端的请求处理时间较长时,会影响服务器接收来自其他客户端的连接请求,进而影响整个服务器的并发性能。

因此,单线程的epoll模型在我们的分布式服务器中并不适用。下面是我们服务器的设计方案:

  

THE END
Copyright © 2024 亿华云