跳转至

0 项目概述

项目概述

项目地址

TinyWebServer

Linux下C++轻量级Web服务器,快速实践网络编程,搭建属于自己的服务器。参考《Linux高性能服务器编程》

  • 使用 线程池 + 非阻塞socket + epoll(ET和LT均实现) + 事件处理(Reactor和Proactor均实现) 的并发模型
  • 使用**状态机**解析HTTP请求报文,支持解析**GET和POST**请求
  • 访问服务器数据库实现web端用户**注册、登录**功能,可以请求服务器**图片和视频文件**
  • 实现**同步/异步日志系统**,记录服务器运行状态
  • 经Webbench压力测试可以实现**上万的并发连接**数据交换

工作流程

以一个请求到来具体的处理过程介绍项目工作流程,具体包括web端和服务器建立连接,访问服务器数据库完成登录和注册,并通过定时器完成非活动连接的处理,最后服务器运行状态通过日志系统进行记录。

  • web端和服务器端建立连接

    • 采用**epoll的边缘触发模式**同时监听多个文件描述符,采用**同步I/O模拟proactor模式**处理事件,主线程负责监听客户端是否发起请求
  • 当web端发起http请求时,主线程接收请求报文,然后将任务插入请求队列,由工作线程通过竞争从请求队列中获取任务
  • 通过**http类中的主从状态机**对请求报文进行分析,根据请求报文对客户端进行http响应,然后由主线程给客户端发送响应报文。

  • 连接数据库

    • 单例模式创建**数据库连接池**,避免频繁建立连接,用于后续web端登录和注册校验访问服务器数据库
  • 实现web端的登录和注册

    • web访问的欢迎界面为**GET请求**,登录和注册界面是**POST请求**。
  • 欢迎界面有新用户(0)和已有账号(1)两个选项,若选择新用户,会跳转注册(3)界面,注册成功或选择已有账号,跳转登录(2)界面,注册或登录失败会提示失败,成功和失败为0,1

  • 同步/异步日志系统,记录服务器运行状态

    • 同步的方式下,工作线程直接写入日志文件
  • 异步会另外创建一个写线程,工作线程将要写的内容push进请求队列,通过写线程写入文件
  • 日志文件支持**按日期分类**,和**超过最大行数自动创建新文件**

  • 非活动连接的处理

    • 由于非活跃连接占用了连接资源,严重影响服务器的性能,通过实现一个服务器定时器,处理这种非活跃连接,释放连接资源。
  • 利用**alarm函数周期性地触发SIGALRM信号**,该信号的信号处理函数利用管道通知主循环执行定时器链表上的定时任务.

框架

img

快速运行

  • 服务器测试环境

  • Ubuntu版本16.04

  • MySQL版本5.7.29

  • 浏览器测试环境

  • Windows、Linux均可

  • Chrome
  • FireFox
  • 其他浏览器暂无测试

  • 测试前确认已安装MySQL数据库

  • 修改main.cpp中的数据库初始化信息

  • build

  • 启动server

  • 浏览器查看

个性化运行

./server [-p port] [-v SQLVerify] [-l LOGWrite] [-m TRIGMode] [-o OPT_LINGER] [-s sql_num] [-t thread_num] [-c close_log] [-a actor_model]

温馨提示:以上参数不是非必须,不用全部使用,根据个人情况搭配选用即可.

  • -p,自定义端口号
  • 默认9006
  • -v,选择数据库校验方式,默认同步校验
  • 0,同步校验,使用连接池
  • 1,CGI校验,使用连接池
  • 2,CGI校验,不使用连接池
  • -l,选择日志写入方式,默认同步写入
  • 0,同步写入
  • 1,异步写入
  • -m,epoll的触发模式,默认使用LT
  • 0,表示使用LT
  • 1,表示使用ET
  • -o,优雅关闭连接,默认不使用
  • 0,不使用
  • 1,使用
  • -s,数据库连接数量
  • 默认为8
  • -t,线程数量
  • 默认为8
  • -c,关闭日志,默认打开
  • 0,打开日志
  • 1,关闭日志
  • -a,选择反应堆模型,默认Proactor
  • 0,Proactor模型
  • 1,Reactor模型

测试示例命令与含义

./server -p 9007 -v 1 -l 1 -m 0 -o 1 -s 10 -t 10 -c 1 -a 1
  • 端口9007
  • CGI校验,使用连接池
  • 异步写入日志
  • 使用LT水平触发
  • 使用优雅关闭连接
  • 数据库连接池内有10条连接
  • 线程池内有10条线程
  • 关闭日志
  • Reactor反应堆模型