服务器 频道

分析:如何改进SOCKS5服务器的性能

    【IT168 专稿】SOCKS5协议的扩展性强、安全性能好、灵活通用、便于网络规划和管理等优点,我们以SOCKS5为基础来建立应用层安全体系结构,而性能问题对SOCKS5服务器来说是非常关键的,SOCKS5服务器的性能问题主要有两个指标:最大并发连接数和吞吐量。

    目前有关SOCKS5协议的实现主要有美国NEC公司开发的SOCKS5 Reference Im plementation和由挪威Inferno Nettverk A /S公司开发的的Dantellsl。本文将对SOCKS5 Reference Implementation(SOCKS5_ NECRI)的源代码进行分析,总结SOCKS5服务器的运
行模式,分析SOCKS5_ NECRI服务器的性能。


SOCKS5_NECRI服务器的运行模式

    在SOCKS5_NECRI服务器中,有normal、inetd、Singleshot、preforking和thread五种运行模式。

1.  Normal模式

    这是一种缺省的模式,它的工作原理就是用一个主进程来接收连接,每接收一个连接后就fork一个子进程来处理这个连接,父进程关闭接收到的套接口,返回继续接收来自客户的连接请求。它的工作流程如图1.

 图1.  Normal模式流程图

2.  Inetd模式

    这种模式和telnet等服务一样通过inetd超级服务器运行SOCKS。它是由inetd守护进程启动的。它处理了所有转变成守护进程所需要的步骤,在启动真正的服务器时套接口已在标准输入、标准输出、标准错误输出上打开。这样就不必再调用socket, bind, listen和accept
了。

3. Singleshot模式

    这是一种快照的方式,在前台处理一个请求,打开debug模式,输出到stderr,然后退出。这种模式一般用于调试时。                                                                        

4.  Preforking模式

    这种模式先派生N个子进程,父进程一直运行对信号进行处理,每个子进程都用一个无限循环来接收并处理连接,工作流程图见图2。

图2.  Preforking模式流程图

5. Thread模式

    这种模式先fork一个子进程,父进程一直运行对信号进行处理,子进程进入无限循环,接收连接,每当接收到一个连接,就创建一个线程,这个线程又进入一个无限循环,第一次处理由主线程接收的连接,再接收新的连接,一直循环,工作流程图见图3。

图3.  Thread模式流程图

各种运行模式的比较

     传统上,并发服务器调用fork派生一个子进程来处理每个客户,在SOCKS5服务器上,默认的模式也是这种,即Normal模式,这种模式问题在于fork子进程时所消耗的CPU时间,这对负载较轻时还能适用,但当负载较重(比如并发连接数较多)时,对性能就会有很大的影响。

     Preforking模式就是Normal模式的一个增强,它是预先派生一组子进程来接受客户请求而不再为每个客户请求fork一个子进程。这种模式的优点在于: 不需要引入父进程fork的开销,新客户就能得到处理,而缺点在于:每次启动服务器时,父进程必须猜测到底需要预先派生多少子进程。

     另外一种增强模式就是Thread模式,它是利用创建一个线程来处理每个客户,使用多线程的理由之一是和进程相比,它是一种非常“节俭”的多任务操作方式。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种“昂贵”的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。

     Inetd模式通常不用于提供大量服务的时候,由于它的开销是每个客户一个fork和一个exec。Singleshot模式只是一种用于调试的运行模式,它只能处理一个连接。

SOCKS5_NECRI服务器性能分析

     SOCKS5_NECRI各种运行模式的最大并发数都与程序的设置及操作系统的限制有关。

     在preforking模式时,能够preforking的子进程数是由启动SOCKS5时用户的输入参数决定,比如socks5 –p –n 100表示的就是preforking模式,并preforking100个子进程,但这个参数会和操作系统的_SC_CHILD_MAX(一个用户打开的最大子进程数)进行比较,如果大于该值,则preforking的子进程数将是_SC_CHILD_MAX,这个值可由sysconf(_SC_CHILD_MAX)得到,在Red Hat Linux 7.3(内核2.4.18-3)中,这个值为999。故preforking运行模式的最大并发连接数也就是999个。

    在normal和thread运行模式中,最大并发连接数都受到程序根据操作系统而设的限制。设置限制的主要原因时SOCKS5_NECRI服务器设计所采用的任务体系结构是每个连接对应一个进程或者线程,如果系统的进出数或者线程数过大,会严重影响系统的性能,甚至让操作系统崩溃。所以,当SOCKS5服务器运行在normal模式时有一个NUMCILIENTS为64的限制,而服务器运行在thread模式时有一个MAXTHREADS为126的限制。

    通过三种运行模式吞吐量的比较,thread和normal模式相差不是很大,但比preforking模式要高27%,主要原因时他们接受的并发连接数不多,这样占用系统资源相对比较少,进程调度和切换之间的开销不是很大。thread模式比normal模式的吞吐量稍高,主要原因是线程比进程更“轻”,比如线程的创建时间比进程更快,线程的调度比进程调度更快等。

SOCKS5_NECRI服务器局限性

    1. SOCKS5服务器选用的Linux操作系统在某些方面有所限制,比如进程数的限制;

    2. SOCKS5_NECRI在normal和preforking模式都是采用的单进程单任务的任务体系结构,所采用的程序分别是传统的TCP进程并发服务器程序和TCP预先派生子进程并发服务器程序;thread模式采用的则是单线程单任务的任务体系结构,所采用的程序是一般的TCP线程并发服务器程序;

    3. SOCKS5_NECRI服务器程序的所有模式都是采用阻塞的TCP/IP调用体系结构;

    4. SOCKS5_NECRI服务器最大并发连接数为999个,吞吐量则随着并发连接数增多时则急剧下降。

    SOCKS5_NECRI服务器所采用的任务体系结构和TCP/IP调用体系结构限制了性能的提高和改进,无法满足实际需要。只有采用不同于原来的任务体系结构和TCP/IP调用体系结构才能真正将SOCKS5服务器性能得以较大的提高。

SOCKS5服务器改进思想

1. 任务体系结构

    SOCKS5服务器所采用的任务体系结构将是一种新的任务体系结构,是常用三种技术(单进程单任务、单线程单任务和单线程多任务)的综合。首先是预派生子进程,采用的是单进程单任务技术;每个子进程每接受一个连接就创建一个线程来处理SOCKS连接链路的建立过程,采用的是单线程单任务技术;每个子进程将创建一个线程专门用来处理该子进程空间所有连接的数据转发,采用的是单线程多任务技术。

2. TCP/ IP调用体系结构

    SOCKS5服务器在连接(connect)和接受连接(accept)连接时采用的是阻塞的TCP/IP调用:在进行数据转发时采用非阻塞的TCP/IP调用,并采用了I/O复用模型中select技术。

3.设计思想描述

    SOCKS5将以prefoking模式启动,启动后将预派生若干个子进程,每个子进程又采用多线程的并发服务器模型,但与传统的多线程模型又有所不同,分成不同用途的三个线程:主线程,连接线程,数据转发线程。

    主线程:一直监听套接口,有连接请求则创建一个新的线程,即连接线程。

    连接线程: 对客户端的连接进行处理,主要包括与配置文件中的有关项进行匹配,与SOCKS5服务器认证方法的协商,与应用服务器建立相应的连接,保存有关信息到全局变量中,然后发送一个消息给数据转发线程,连接线程终止。

    数据转发线程: 负责该子进程空间所有建立连接的数据转发,采用I/O select技术,有套接口可读或可写将从select返回,进行数据相应的读写并进行转发。

    SOCKS5服务器启动后,创建一个监听套接口,然后预派生若干个子进程。在每个子进程空间内,每个子进程执行后将马上创建一个数据转发的线程,同时,该子进程改称为主线程。主线程的任务是接受(accept) SOCKS5客户端的连接请求,每当接受一个连接请求后,立即创建一个连接处理线程来进行连接过程的处理。当连接建立以后,连接线程发送一消息互数据转发线程,通知该连接己建立成功,可以开始进行数据的转发。数据转发线程将一直运行负责对本子进程空间的所有的连接进行数据转发。

4. 数据转发模型

    数据转发模型如图4所示

图4.  SOCKS5性能改进设计的数据转发模型

    采用select利用技术,当对应SOCKS5的客户端套接口和对应远程应用服务器的套接口可读可写时,则将相应套接口的数据读或写到缓冲区内。

小结:分析与展望

     SOCK5服务器性能不好的主要原因是所采用的任务体系结构和TCP调用体系结构。本文在SOCKS5_NECRI的基础上,提出了一种性能改进设计思想来提高SOCKS5服务器的性能一一最大并发连接数和吞吐量两个指标。

    限于文章篇幅,仅仅是简单介绍了一下设计思想,不过基于此思想而改进的SOCKS5服务器的最大并发连接数在程序不受限制,不过在一定程度上要受到系统资源的制约;吞吐量根据实验测试,比SOCKS5_ECRI最多能高出60%以上,特别是当并发连接数大,负载重的情况下,吞吐量有显著的提高。

0
相关文章