基于Linux的2种HTTP服务器实现与对比分析

2017-09-30 03:01江存
现代计算机 2017年24期
关键词:线程报文服务器

江存

基于Linux的2种HTTP服务器实现与对比分析

江存

(四川大学计算学院,成都 610000)

探讨Linux环境下的多线程并发编程的问题,介绍采用C语言实现基于动态线程池模式的简单服务器与基于epoll+多线程模式的简单服务器,采用Webbench进行压力测试,并对结果做出分析与思考。

线程池;epoll;并发编程;HTTP

0 引言

HTTP协议是互联网中重要的协议,Web浏览器、服务器和相关的应用程序都是HTTP互通的,对其进行研究十分有必要。本文着重研究分析了HTTP服务器的设计与实现方式,一个设计架构良好的服务器需要高效稳定可扩展性,尽可能满足多的任务请求。本文着重设计实现了态线程池模式和epoll加多线程模式,并对其进行分析。

1 原理分析

1.1 HTTP协议简介

http服务器是基于TCP协议的应用层协议,名为超文本传输协议。Web客户端与服务器端进行数据传输就是依靠HTTP协议实现的。它是全球因特网使用的公共语言。

通常,一个客户端与服务器建立连接之后,会发送一个请求个服务器,请求报文的格式一般为:请求起始行、请求首部字段和主体部分。服务器在将报文解析出来,在发送一个响应报文,和请求报文类似,也分为三个部分:响应起始行、响应首部、响应主体。

请求报文格式如下:

<method> <reque-uri> <version>

<headers>

<entity-body>

响应报文格式为:

<version> <status> <reason-pharse>

<headers>

<entity-body>

●方法(method)

客户希望服务器对资源进行的动作。如get,post等方法。

●请求 URL(request-URL)

所请求的资源地址。

●版本(version)

所使用的HTTP协议版本。

●状态码(status)

这三位数字描述了请求过程中所发生的情况。

●原因短语(reason-phrase)

数字状态码的可读版本,包含行终止序列的所有文本。

●首部(header)

可以有零个或者多个首部,每个首部包含一个名字,后面接一个逗号,然后是个可选空格,然后是一个值,最后是一个CRLF。

●实体的主体部分(entity-body)

包含任意数据组成的数据块。并不是所有的报文都包含实体的主体部分,有时报文以一个CRCL结束。

1.2 HTTP服务器架构分析与设计

(1)基于线程池的HTTP服务器

由于单个进程无法同时处理读个连接,并且无法发挥服务器多核心的优势,但是用多进程,每个进程分别处理不同的请求,又太耗费资源,所以采用多线程的模型来处理,与此同时,由于HTTP请求和响应很快,创建和销毁线程又非常的频繁,需要很大的系统资源开销,所以采用预先创建线程池来处理HTTP任务,既发挥了CPU多核心的优势又减少了不必要的系统开销。服务器工作原理如下:首先建立套接字描述符,接着绑定地址,在监听套接字看是否有连接接入,有接入就分配一个线程去处理任务。

其中线程池管理过程为:当主线程获取了一个连接后,将任务添加到线程池管理结构中的任务队列中,并检测是否需要增加线程,唤醒等待中的线程,唤醒的线程去任务队列中取下任务进行处理,处理完后继续队列任务。如此同时,单独创建一个检测线程,当满足条件后就会销毁一部分线程,以达到根据具体需求动态改变线程池大小的需求,如此往复。

(2)基于epoll加多线程的HTTP服务器架构

由于前面采用线程池模型,每个请求必须要一个线程去处理,处理完成后才会去做下一个任务,如果请求时保持型的长连接,那么很快线程池就被消耗完了,而其他的请求得不到满足。在这个问题基础上,改进了单独线程池模型的不足,采用epoll模型来,为了充分利用多核心的优势,采用了多线程加epoll模型,每个线程单独处理一个epoll对象,这样线程之间互不干扰,减少线程调度和切换的开销,同时提高了CPU的利用率。

2 详细设计实现

2.1 线程池模型关键结构设计

(1)下面介绍一些必要的数据结构

●任务结点设计

(2)服务器处理步骤

图1

图2

2.2 epoll+多线程模式关键结构设计

(1)epoll主要结构如下

①连接信息结构

void add_epoll_event(int epfd,Conn*conn,int flags)函数负责向epoll对象中添加事件信息,epfd是epoll对象文件描述符,conn是连接请求信息,flags事件触发方式。

void mod_epoll_event(int epfd,Conn*conn,int flags)函数负责对epoll对象中的事件信息进行修改。

void del_epoll_event_close_fd(int epfd,Conn*conn)函数负责删除epoll对象中的事件,并且关闭套接字描述符fd。

其他创建和收集发生事件的连接直接调用系统函数epoll_create和epoll_wait函数。

(2)基于epoll的服务器处理流程图如下:

图3

3 测试结果与分析

笔者采用开源软件Webbench进行测试,主要采用GET方法请求,属于I/O型事件处理请求,两个模式服务器部署在同一个主机上进行测试,另一个主机每次模拟不同数量的客户端,每次测试时间30秒,测试10次,失败为止,表1是基于线程池的服务器的测试数据,表2是基于epoll+多线程的服务器的测试数据,可以看到,随着并发客户数越多,epoll效率几乎不受影响,同等条件下,当并发数超过4000时,线程池服务器就会出现请求失败的情况,而epoll服务器几乎不受影响。说明对于高并发和I/O型事件,epoll模式要由于一般的线程池模式。测试结果如下:

基于线程池服务器测试的截图和结果:

图4

图5

4 结语

笔者研究了HTTP服务器原理以及实现,并且为了最大可能利用计算机资源和尽可能并发处理程序,经过比较最后选择基于线程池和epoll+线程模式两种方式进行对比测试分析,得出在不同情况下根据具体需求采用不同模型的必要性,当并发程度要求不高,二者性能将近,但是特别是在并发连接多I/O型事件请求任务下,epoll模式表现良好。一个好的服务器需要考虑很多方面,笔者才疏学浅只是在相对理想条件下进行测试,总之对此还需继续深入的研究与分析。

表1

表2

[1]W.Richard Stevens,Stephen A.Rago著.UNIX环境高级编程[M].戚正伟,张亚英,尤晋元译.北京:人民邮电出版社,2014.

[2]W.Richard Stevens,Bill Fenner,Andrew M.Ruoff著.UNIX网络编程[M].北京:人民邮电出版社,2015.

[3]David Gourley,Brian Totty,Marjorie Sayer,Sailu Reddy,Anshu Aggarwal著.HTTP权威指南[M].陈涓,赵振平译.北京:人民邮电出版社,2012.

[4]王远洋,周渊平,郭焕丽.Linux下基于Socket多线程并发通信的实现[J].微计算机信息,2009,25(5).

[5]催滨,万旺根,余小清,楼顺天.基于EPOLL机制的Linux网络游戏服务器实现方法[J].微计算机信息,2006,22(7).

[6]梁明刚,陈西曲.Linux下基于epoll+线程池高并发服务器实现研究[J].武汉轻工大学学报,2012,31(3).

Implementation and Comparison of Two Kinds of HTTP Server Based on Linux

JIANG Cun
(College of Computer Science,Sichuan University,Chengdu 610000)

Discusses the problem of multi-threaded concurrent programming in Linux environment,introduces the simple server based on dynamic thread pool mode and simple server based on epoll+multi-thread mode written in C language and Webbench is used for stress testing,fi⁃nally makes a summary of test.

Thread Pool;Epoll;Concurrent Programming;HTTP

1007-1423(2017)24-0058-05

10.3969/j.issn.1007-1423.2017.24.014

江存(1991-),男,湖北黄冈人,硕士研究生,研究方向为网络与信息安全

2017-04-27

2017-08-05

猜你喜欢
线程报文服务器
基于J1939 协议多包报文的时序研究及应用
以太网QoS技术研究及实践
实时操作系统mbedOS 互斥量调度机制剖析
浅析体育赛事售票系统错票问题的对策研究
PowerTCP Server Tool
浅析反驳类报文要点
BlackJumboDog
2018年全球服务器市场将保持温和增长
计算机中的多线程问题
1588v2中的PTP报文格式及应用