ImageVerifierCode 换一换
格式:DOCX , 页数:31 ,大小:1.43MB ,
资源ID:4575438      下载积分:5 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/4575438.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(Linux环境下高并发web服务器-的设计与实现.docx)为本站上传会员【二***】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

Linux环境下高并发web服务器-的设计与实现.docx

1、Linux环境下高并发web服务器的设计与实现 摘要 随着信息技术的飞速开展,互联网已经成为社会生产生活中不可缺少的一局部。特别是近十年来,由于移动技 术的进步和智能移动设备的普及,互联网用户数量呈爆发式增长,越来越多的行业正在通过互联网进行变革。用户 群体的开展改变了互联网服务的形式,越来越多的服务器需要同时为大量客户提供服务。因此,如何设计服务器的 通信框架,如何有效利用服务器的系统资源,成为服务器开发人员关注的焦点。 Web应用具有连接间隔短、突发性强、响应时间短等特点,它是一种对并发性要求很高的服务。本文在服务器系 统中选择主流的Linux操作系统,采用C++,结合Socket、

2、I/O多路复用技术epoll、无阻塞I/O、线程池、定时器和 Reactor事件处理模式,设计并实现了一个稳定支持高并发的Web服务器。 本文首先介绍和分析了Wob服务器的相关技术,包括Socket、epolK Reactor事件处理模式、线程池和数据库连 接池;重点讨论了epoll与其他I/O模型的区别,以及epoll模型的特点。其次,根据Reactor模式分析了服务器的整 图3. 4事件处理器与存储队列存储单元从阻塞队列获取获取数 据进行存储。如图3. 5所示。 图3. 5存储队列与存储单元 3. 2事件别离器流程事件别离器主要负责接收新连接、侦听到达事件。HTTP长连

3、接可以减少TCP连接的创立次数,使客户端和服务器能 够有效复用TCP连接。但是,“在长连接应用 中,服务器与客户端实例都保持一个持久的连接,这将大量消耗服务器资源,特别是在一些大型应用系统中更是如 此,大量并发的长连接有可能导致新的请求被阻塞甚至系统崩溃[18]。” 为了对长连接进行管控,服务器可以通过实现定时器,对每个连接记录超时时间点来解决这个问题。每当某个 连接有新请求到达时重置该连接的定时器,如果连接超时那么服务器主动释放连接。判断超时和重置定时器的工作均 由事件别离器完成,事件别离器工作流程如图3. 6所示。 设置新连接的定时 器,把新迩接加入 设置新连接的定时 器,把新

4、迩接加入 重置龙援的定时器,把 事件和处理方法加入到 I 到检测集合中 II 事件阻塞队列中 I 图3.6事件别离器流程3. 3事件处理器流程 事件处理器是服务器的核心模块,主要负责的工作是:服务器的I/O操作、业务处理,因此对服务器的业务拓展 工作主要是对事件处理器的功能进行拓展。在本工程实现的Web服务器中,I/O操作主要是指对Socket进行读写操 作 ,业务处理主要是指对接收到的HTTP请求报文进行解析,并生成相应的HTTP响应报文。同时为了能够支持用户登录 功能和用户注册功能,当HTTP请求为该两种功能请求时,事件处理器还需要通过访问数据库对接收到的用户名和用 户密码进行判断

5、或存储操作。 事件处理器的整体流程如图3. 7所示。 图3. 7事件处理器流程在本工程中事件处理器的业务处理可以分为两个模块:HTTP请求报文解析模块、HTTP 响应报文生成模块。3. 3. 1 HTTP请求报文解析模块 本模块主要工作是对客户端发送来的HTTP请求报文进行解析。HTTP请求报文由请求行、请求头部、空白行、请 求体构成,每一行都以CRLF (回车符和换行符)作为结尾标志[19]。 在IITTP/L1中,请求行由请求方法、URI、HTTP协议版本构成。请求头部由多行构成,每行以键值对的形式表示 (键为头部字段名)。请求头部包含了一些该连接和报文的信息,如表示长连接状态

6、的keep-alive、请求体的编码 方式content-type等。空白行没有数据只有CRLF表示空白的一行,用来区分请求头部和请求体。请求体携带客户端 发送的数据,如通过POST请求报文发送的表单。 HTTP请求解析模块主要有三个状态:解析请求行、解析请求头部、解析请求体。状态转移如图3. 8所示。GET请求报 文和POST请求报文是本文的主要解析对象。GET请求报文把参数存放在URL请求体数据为空,事件处理器无需解析GET请求报文的请求体。POST请求报文的参数被存放在POST请求报文的请求体中,事件处理器需要对 POST请求报文的请求体进行解析,从中获取报文参数。 登陆和注册通过P

7、OST报文发送请求,用户名和用户密码存放在请求体中。在解析请求体过程中,需要对通过解 析得到的用户名、用户密码进行处理:当报文请求为登录时,向存储单元查询用户名、用户密码进行校验;当报文 请求为注册时,向存储单元查询用户名、密码合法性,如果合法那么进行存储。 3.3.2 HTTP响应报文生成模块 本模块主要工作是生成发送给客户端的HTTP响应报文。HTTP响应报文由响应行、响应 头部、空白行、响应体构成,每一行以CRLF表示该行结尾。响应行由HTTP协议 版本、状态码、状态码描述构成。 状态码由三个十进制数字组成,状态码的类型由第一个数字定义。状态码和状态码描述表示HTTP响应报文的报 文

8、类型。HTTP响应报文生成模块流程如图3. 9所示。 图3. 8 HTTP解析模块状态转移 图3. 9 HTTP响应报文生成模块流程“客户端请求资源合法”是指客户端请求的资源存在并且是一些 指定的文件,而不是某个文件夹。3.4日志系统 日志是记录服务器运行状态的文件,对于服务器开发人员和服务器运维人员而言日志是一种能够直观地观察服 务器状态的重要文件。通过日志,服务器开发人员可以查看服务器的日常运行状态,对服务器架构和功能作出调整 和拓展;服务器运维人员可以根据日志中的错误信息对服务器进行错误排查。日志系统的实现有两种方式:同步模 式和异步模式。 同步模式的写入操

9、作与事件处理器串行执行。写日志文件会涉及到I/O操作,同步模式在I/O操作时会阻塞整个 处理流程。当单条日志记录较大时,事件处理器会被阻塞较长时间,整个服务器的并发度将有所下降。如果服务器 需要处理大量连接请求时,写日志操作可能会成为系统瓶颈。 异步模式需要阻塞队列作为事件处理器和写日志模块的传输介质。事件处理器把日志记录存入阻塞队列,写日 志模块异步地从阻塞队列中获取日志记录并写入日志文件。异步模式把写日志操作与业务处理流程进行别离,防止 业务处理流程被阻塞,提高了服务器业务处理的并发度。 日志记录根据记录信息被划分为多个等级。例如,日志记录被分为调试信息、运行信息、错误信息等几个级别

10、服务器正常运行时仅记录运行信息和错误信息;服务器调试时记录包括调试信息的所有信息。服务器可以根据 不 同的运行状态选择不同的日志等级,过滤无需记录的日志信息,从而提高日志文件的可读性。日志系统的写入记录 流程如图3. 10所示。 根据日志等 级、日志参数 创立相应的E 志记录 ✓ 1 < । JU) 第N个日志文件 结束 同步璜式 日阻先 入业不 11 志塞处板 异步建式 写日志模块异步地从 阻塞队列中茨取日志 记录,并把日志记录 写入日志文件 图3.10写入日志记录流程 4工程实现4.1服务器整体功能 本工程是在Linux环境下使用C++实现的Web服务器

11、目标服务器基于Reactor模式,结合了 epoll和非阻塞 Socket,利用线程池和数据库连接池实现了LT模式、ET模式下对GET请求报文、POST请求报文的解析和响应,使用定 时器实现了对长连接的管控。此外,本工程还实现了同步和异步两种模式下的日志系统,用于记录系统运行状态。 4.2阻塞队列 STL向C++开发者提供了deque、queue等模板类队列,这些模板类使用方便、接口清晰,但不具备线程平安性。 根据参考文献[20]的第十二条: library implementation that allows multiple readers on one container and

12、multiple writers on separate containers. You can't hope for the library to eliminate the need for manual concurrency control, and you can,t rely on any thread support at all. ”可知如果要实现STL的线程平安性,程序员必须 自己去完成相关平安措施。 本工程通过互斥锁、条件变量对deque重新封装,利用“生产者-消费者”模式实现了具有线程平安性的阻塞队 列。 力口锁(lock mutex) 被条件兖量 consumer

13、 阻塞 元素出队 解锁(unlock mutex) 图4.1阻塞队列的入队和出队4.3日志系统 4.3.1 单例模式为了防止日志文件混乱,日志系统在服务器运行过程中应该只存在一个实例,即单例模式实现日志 系统。单例模式是最常用的设计模式之一,通过私有化构造函数来保证一个类无法类外实例化,并提供相应的实例访问接口给 其它程序模块访问,该接口只能获取该类的唯一实例。在C++11标准[21]中,对局部静态变量的初始化作出以下要 求: “Otherwise such a variable is initialized the first time control passes through

14、 its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration c

15、oncurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined. n 因此,在C++11 标准中,局部静态变量的初始化 是具备线程平安性的。单例类可以通过在实例访问接口中定义该类

16、的局部静态对象来定义唯一实例。这种方法是单例模式中的懒汉模式,因为C++中的局部静态对象只有在第一次访 问时才会被初始化。 实例接口代码如下所示。 1 .Log* Log::Instance() {. static Log minstance; 2 . return &m_instance;.) 4.3.2 日志级别日志系统提供四种日志级别,从低到高依次为:DEBUG、INFO、WARN、ERRORo低级别的记录信息会 被日志系统的级别过滤。 DEBUG:记录调试信息,如请求资源信息、数据库查询信息等。该级别的信息用于记录调试服务器时服务器的详 细运行过程,在服务器实际运行时不使用。

17、 INFO:记录服务器当前状态,如当前的执行流程、接收信息、连接数量等。该级别的信息用于记录服务器实际 运行时的状态。 WARN:记录警告信息,如服务器连接数已满。该级别的信息表示服务器可能出现了异常情况。ERROR:记录系统出 错信息,如服务器初始化出错、创立Socket出错、检测到了未定义的事件等。该级别的信息用于记录服务器的出错信息。日志系统定义了四个宏:“LOG_DEBUG”、“L0GJNF0"、“LOGJVARN”、“ LOG_ERROR”。其它程序通过调用 这四个宏向日志系统传输日志信息。为了区分记录级别,四个宏都通过调用“LOG_BASE”来进行级别检查,不同的 接口调用“

18、LOG_BASE”时传入不同的记录等级参数。 “LOG—BASE”的伪代码如图4. 2所示。 4.3.3 分日期、分记录数量创立日志文件 日志记录写入日志文件时日志系统对当前翻开的日志文件的日期、记录数量进行检查,日志系统根据日期、记 录数量对日志文件进行分类。如果当前日期与日志系统翻开日志文件的日期不一致,那么日志系统新建日志文件,日 志名称为当前日期;如果当前翻开的日志文件的记录数到达单个日志文件的最大记录数,那么日志系统将创立一个日志名称带有当前日期和计数后缀的新日志文件[22] o 检查日志文件日期、记录数量的伪代码如图4. 3所示。 4.3.4 同步模式、异步模式日志系统的

19、模式在服务器初始化中决定:阻塞队列长度等于零为同步模式,阻塞队列长度大于零为异步模式。日志 系统根据不同的记录级别、日志信息生成相应的日志记录,并写入日志文件。同步模式中记录写入日志文 件的I/O操作与处理业务的工作线程串行执行,会阻塞工作线程;异步模式创立一个日志写入线程,工作线程把日志 记录插入阻塞队列,由日志写入线程异步地从阻塞队列获取日志记录并执行I/O操作。、日志写入的伪代码如图4. 4 所示。 Algorithm 1: LOG_BASEInput: level, loginfo if level》Instance.level thenWirteLog(level, login

20、fo); flush;end 图4.2 L0G_BASEAlgorithm 2: CheckLog if log. date * today or (count % maxCount) = 0 thenif log. date 卢 today then create new log, name is today;log. date = today; count = 1;else create new log, name is today,(count / maxCount);end end图4. 3检查日志文件 Algorithm 3: WriteLogInput: level

21、 loginfo CheckLog;logging = C r eat eLogging (level. liglnfo); if is A sync thenLogging Q uque. p ush (logging); elsewrite (logging); end图4. 4日志写入 4.3.5 4线程池4. 4.1线程池成员线程池主要由儿个成员组成:存储任务(任务为回调函数)的阻塞队列、负责线程互斥访问临界 区的互斥锁、 负责线程同步的条件变量。 4. 4.2工作线程的同步与竞争 根据图3. 7可知线程池中的工作线程与主线程存在同步关系,与其它工作线程存在竞争关系,

22、即半同步/半异步模式。工作线程的执行流程伪代码如图4. 5所示。 Algorithm 4: Workmutex lock; while threadpool is not closed doif BlockQueue is not empty then get task from BlockQueue;mutex unlock: processing the task;mutex lock; elsethread is blocked by condition variable; endend mutex unlock;图4.5工作线程工作线程初始化后对线程池中的mutex进行加

23、锁,然后访问临界区,在线程池关闭前循环执行。如 果存储任务的 阻塞队列不为空,工作线程从阻塞队列中取出任务,然后对mutex解锁并处理任务。任务完成后重新尝试对mutex力口 锁,再次参与竞争。如果存储任务的阻塞队列为空,工作线程被条件变量阻塞(工作线程被条件变量阻塞会释放 mutex的所有权,即解锁),只有主线程向阻塞队列插入新的任务或主线程关闭线程池时才被唤醒(工作线程被唤醒 后重新尝试对mutex加锁,重新参与竞争)。两种唤醒方式的区别在于新的任务插入阻塞队列只会唤醒一个被条件变 量阻塞的工作线程,线程池关闭会唤醒所有被条件变量阻塞的线程。 4.5数据库连接池 数据库连接池的实现方法

24、比线程池更简单,本质是使用一个阻塞队列存储空闲的数据库连接。工 作线程向数据库连接池申请和归还数据库连接实际是对阻塞队列的出队和入队操作。但阻塞队列的入队操作如果交给程序员处理 可能会存在遗漏入队的情况,导致空闲的数据库连接没有重新进池,从而浪费空闲资源,甚至最后会导致数据库连 接池无空闲的数据库连接可用。同时,程序没有主动释放动态申请的资源,造成了内存泄漏。 为了防止某个线程使用完数据库连接后没有释放数据库连接的所有权,数据库连接的分配和回收通常采用RAH (Resource Acquisition Is Initialization,资源获取就是初始化)机制,程序通过定义一个封装了从数据

25、库连 接池获取和归还连接的RAU类来管理连接的分配和回收[23]。RAH类在构造函数中获取数据库连接,在析构函数中 归还数据库连接。通过RAU机制,工作线程只能通过定义一个RAH实例获取数据库连接。同时工作线程无需主动归 还数据库连接,因为线程对数据库连接的所有权周期就是RAH实例的生命周期,当线程完成数据库访问后退出相应 作用域,RAH实例被系统自动销毁,RAH实例的析构函数释放数据库连接。数据库连接RAH类的构造函数和析构函 数的伪代码如图4. 6所示。 Algorithm 5: Construct SqlPoolRAIIOutput: sqlConnection get sqlCon

26、nection from sqlConnectionQueue;mySqlConnection = sqlConnection; Algorithm 6: Destruct SqlPoolRAIIif mySqlConnection is not empty then sqlConnectionQueue.push(mySqlConnection): end图4.6数据库连接RAH类的构造函数和析构函数 4. 6解析HTTP请求报文4. 6.1 HTTP请求报文解析流程根据图3. 8可知HTTP解析主要分为三局部:解析请求行、解析请求头部、解析请求体 o请求行主要解析请求报文的请求方

27、法、URI、HTTP协议版本,请求头部主要解析关于连接和报文的各种信息,请求体主要解析某些报文的参数 (POST报文)。解析请求体前逐行解析行、请求头部。本工程HTTP请求报文解析模块从HTTP请求中解析得到的信息 ,包含:请求方法,URL协议版本,连接类型 (Connection,表示短连接或长连接),长连接信息(keep-alive)请求体编码方式,请求体长度,表单参数(用 户名、密码)。 4. 6. 2解析请求行 请求行由请求方法、URI和HTTP协议版本组成,以空格分隔,整行格式为“请求方法URI HTTP/协议版本”。请 求行可以通过正那么表达式进行匹配。由于请求行的三个元

28、素由空格隔开,并且版本协议前带有“HTTP/",所以匹配 正那么表达式为: 乂厂]*)(厂]*) HTTP/(1]*)$通过正那么表达式匹配可得到请求报文的请求方法、URI和HTTP协议版本。URI作为 唯一资源标识符,本工程可以通过URI和自定义的“URI-资源路径”映射表得知请求资源的路径。 4. 6. 3解析请求头部 请求头部包含许多连接信息,以键值对的形式表示,每个键值对占一行。STL提供了以键值对形式存储的模板 类:map、unordered_mapo其中map底层由红黑树实现,unorderedjnap底层由哈希表实现。由于HTTP请求头部中的 信息无顺序意义,因此本工程使用

29、时间复杂度更低的unorderecUnap存储请求头部信息。 请求头部中的键值对以冒号和空格(“:”)进行分割,因此可以使用正那么表达式对键值对进行匹配。匹配请 求头部信息的正那么表达式: ”[:]*): ?(.*)$如果匹配失败,说明解析到了空白行,结束解析请求头部。解析请求体 请求体的长度和编码方式在解析请求首部中得知,键的名称分别为"Content-Length"和"Content-Type' o 本工程对编码方式为uapplication/x-www-form-(JRIencodeclv (大多数主流浏览器提交表单的默认编码方式)的 POST请求进行解析。 “applicati

30、on/x-www-form-URIencoded”的数据参数是键值对,表现形式为“key=value”,因此可以使用 unorderedjnap存储键值对参数。多个参数之间由别离。编码规那么为:参数中的空格使用“ + ”替换,非数字、 字母的特殊字符使用三个字符“%xy”替换,其中“xy”表示该字符的十六进制表示形式。 请求体的整体解析过程:根据"app 1 i cat i on/x-w wf orm-UR I encoded v编码方式对请求体进行反编码,别离键 值对参数并存入哈希表中。判断请求报文是否请求注册或登录,如果是那么根据相应的参数判断请求是否合法,如参 数中否含有用户名、用户密

31、码。 本工程的登陆与注册校验过程由HTTP解析模块完成。客户端通过POST请求报文提交表单,用户名和用户密码存 放在请求体中。服务器解析post请求消息并获取用户名和密码,然后通过数据库连接访问数据库,并查询用户名和 密码是否合法。 HTTP请求体解析过程如图4. 7所示。 Algorithm 7: Parse Postif method = POST and Content-Type = application/x-www-form-urlencoded thenEncoded (Body); if Register or Login thenif username and pas

32、sword are legal then path = welcome; elsepath = error; endend end图4.7解析HTTP请求体 如果请求报文是登录或注册请求,那么返回给客户端的资源的路径由用户名、用户密码检查结 果决定:如果信息 正确,资源路径为成功页面的路径;如果信息错误,那么资源路径为错误页面的路径。 4. 7生成HTTP响应报文4. 7.1 HTTP响应报文生成流程响应报文生成模块根据解析模块的结果,生成响应行、响应头部、空白行和响应体。 响应行主耍生成状态码; 响应头部主要生成长连接状态、响应体长度;响应体为根据解析结果得到的资源文件。本工程的

33、HTTP响应报文生成 模块中,因为每个连接的报文信息都可能各不相同,因此响应行、响应头部、空白行存储在各个连接的响应报文缓冲区中。为了加快发送报文时对资源文件的读取速率,响应体对应的资源文件通过 内存映射存放到内存中。“内存映射 文件提供了一种独特的内存管理特征,它允许应用程序与通过指针访问动态内存相同的方式访问磁盘上的文件。因 此,可以在进程地址空间中将磁盘上的文件局部或者全部映射到特定地址范围,然后通过指针就可以访问内存映射 文件中的内容。一旦该文件被映射,就可以访问它,就像整个文件已经加载内存一样,从而可以不必对文件执行I/O 操作,这对大数据量文件来说存取效率较高[24]。” 图4

34、 8响应报文存储关系 4.7. 2生成状态码 根据图3. 9可知,能够成功请求资源的请求报文需要经过三次检查:成功解析请求报文、客户端请求的资源合 法、客户端拥有足够权限访问资源。每个阶段出错都会生成相应的状态码,只有三次检查都通过才会生成表示成功 体框架,包括框架中的事件别离器、事件处理器;其中事件处理器是核心模块,重点分析了其HTTP请求报文解析模 块和HTTP响应报文生成模块;还分析了日志系统的同步模式和异步模式。在完成需求分析后,对服务器的各个模块 进行设计和实现,包括阻塞队列、日志系统、线程池、数据库连接池、HTTP请求报文解析、HTTP响应报文生成以及 管控HTTP长连接的定

35、时器。各模块通过面向对象的思想实现了相应的功能接口,降低了模块间的耦合度。最后,本 文对服务器进行了压力测试和稳定性测试,并对应用层面的注册功能、登录功能和大文件传输功能进行了测试。本 文涉及了Socket的监听与连接、网络I/O管理、线程池设计和HTTP协议分析,对解决Web服务器中遇到的问题具有很 好的工程参考价值。 关键词:Linux, C++,高并发,epoll, Reactor Abstract With the rapid development of information technology, the Internet has become an indispensabl

36、e part of social production and life. Especially in the past decade, due to the progress of mobile technology and the popularity of intelligent mobile devices, the number of Internet users is growing explosively, and more and more industries are changing through the Internet. The development of user

37、 groups has changed the form of Internet services, more and more servers need to provide services for a large number of customers at the same time. Therefore, how to design the communication framework of the server and how to effectively use the system resources of the server have become the focus o

38、f server developers. Web application has the characteristics of short connection interval, strong burst and short response time. It is a service with high concurrency requirements. In this thesis, we choose the mainstream Linux operating system in the server system, use C++, combine socket, I/O mul

39、tiplexing technology epoll, non blocking I/O, thread pool, timer and Reactor event processing mode, design and implement a stable and high concurrent web server. This thesis first introduces and analyzes the related technologies of web server, including socket, epoll, Reactor event processing mode,

40、 thread pool and database connection pool; the differences between epoll and other I/O models and the characteristics of epoll model are discussed. Secondly, according to the Reactor mode, the overall framework of the server is analyzed, including the event separator and event processor in the frame

41、work; the event processor is the core module, focusing on the analysis of its HTTP request message parsing module and HTTP response message generation module; the synchronous mode and asynchronous mode of the log system are also analyzed. After the completion of the requirements analysis, the design

42、 and implementation of each module of the server, including blocking queue, log system, thread pool, database connection pool, HTTP request message parsing, HTTP response message generation and the timer to control the HTTP long connection. Each module realizes the corresponding function interface t

43、hrough the idea of object-oriented, which reduces the coupling degree between modules. Finally, this thesis tests the pressure and stability of the server, and tests the registration function, login function and large file transfer function of the application level. This thesis involves socket monit

44、oring and connection, network I/O management, thread pool design and HTTP protocol analysis, which has good engineering reference value to solve the problems encountered in web server. Key words: Linux, C++, high-concurrency, epoll, Reactor目录 1绪论.12开发技术介绍 2 2. 1 Socket,22.2 I/O多路复用技术EPOLL.4 1. 2

45、1 五种 I/O 模型 ..42. 2 EPOLL4 2. 3 Reactor事件处理模式...7的状态码“200”。能否成功解析请求报文是由请求报文解析模块进行判断的。如果HTTP请求报文格式出错(如请 求行格式出 错),那么状态码设置为“400”。该阶段检查的“出错”仅表示请求报文格式出错,而登录或注册请求中的用户信息 出错不属于该阶段的检查范围,仅属于应用层面上的出错。所以用户信息错误的登录或注册请求也是一次成功的请 求,服务器发送的响应报文依然是状态码为“200”的成功响应报文,只是页面资源是表示用户信息出错的页面,而 不是成功页面。 客户端请求资源合法表示客户端请求的资源应

46、该存在并且是有效资源,不能是某个文件夹。客户端拥有足够权限访 问资源表示客户端请求的资源在服务器的权限是中是“其它用户可读"。Linux中的文件权限分为“可读”、“可写”、“可执行”,本工程主要检查客户端是否有权限读资源,在开发中使用SJR0TH (表 示其他用户可读的权限值,与文件的权限值进行与运算可知文件能否被其他用户读)对资源文件的权限进行检查。 生成状态码的伪代码如图4. 9所示。 Algorithm 8: CreateStatusCode Output: Status Code if Parse Post = FALSE thenStatus Code = 400; endels

47、e if resource does not exist or resource is a folder then Status Code = 404;end else if resource is not readable thenStatus Code = 403; endelse Status Code = 200;end 图4.9生成状态码的伪代码生成响应行、响应头部、空白行 本工程定义了 “状态码-状态码描述”映射表,生成响应行时向HTTP响应报文缓冲区写入协议版本、状态码、状 态条件。 本工程定义了 “文件类型-MIME类型”映射表,生成响应头部时根据资源的文件类型向

48、HTTP响应报文缓冲区写入 资源的MIME类型参数(Content-Type) o同时,根据连接类型向缓冲区写入连接类型参数(Connection),如果连 接类型为长连接还需写入长连接参数(keep-alive) o长连接类型参数的值为timeout和max,表示连接生存时间和 最大请求数。最后写入响应体长度参数(Content-Length)和空白行。 4. 7.4生成响应体目标资源文件通过内存映射被映射到内存中。服务器向客户端发送响应报时文从映射对象中读取 数据并写入Socketo为了防止程序影响原文件,内存映射类型应设为MAP_PRIVATE。这种类型表示程序对内存映射中的映射区进

49、行修改时会执行“写时拷贝”获得一份私有的文件拷贝,对文件的修改都是对这篇私有内存的修改,不写回原文件 O4. 8定时器 本工程通过定时器对HTTP长连接进行管控。服务器在初始化时定义连接的生存时间,接收到请求报文后为连接 设置定时器。 定时器使用小顶堆实现,每个节点存储某个连接的定时器信息。定时器信息包括Socket的文件描述符、超时时 间点、回调函数,其中超时时间点为定时器设置时间加上连接的生存时间,回调函数为关闭连接函数。各个信息的 作用是:主线程设置或重置连接的定时器时根据Socket的文件描述符找到指定的定时器节点;主线程根据定时器的 超时时间点判断该连接是否超时,如果超时那么调

50、用回调函数关闭连接。 小顶堆的底层数据结构是数组,根据节点的超时时间点排序建堆。主线程在重置定时器时需要根据文件描述符 找到定时器节点,因此还需要定义一个“文件描述符-节点下标”映射表,可以使用unorderedjnap实现。 新增连接时判断堆中是否存在含有该Socket文件描述符的节点。如果不存在,主线程向堆尾中插入新的定时器 节点,并根据超时时间点对节点向上调整;如果存在,说明之前使用该文件描述符的连接虽然已经被关闭但目前事 件还到达该连接的超时时间点,主线程重置该节点的超时时间点,并对节点向下调整。 某个连接有新的事件到达,主线程重置该连接定时器的超时时间点:通过文件描述符和“文件

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服