Skip to content

ZWiley/TinyWebServer

Repository files navigation

TinyWebServer

Linux下C++轻量级Web服务器,助力初学者快速实践网络编程,搭建属于自己的服务器.

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

模块概述

  • C/C++
  • B/S模型
  • 线程同步机制包装类
  • http连接请求处理类
  • 半同步/半反应堆线程池
  • 定时器处理非活动连接
  • 同步/异步日志系统
  • 数据库连接池
  • CGI及同步线程注册和登录校验
  • 简易服务器压力测试

Update

  • 解决请求服务器上大文件的Bug
  • 增加请求视频文件的页面
  • 解决数据库同步校验内存泄漏
  • 实现两种CGI数据库访问逻辑
  • 实现ET非阻塞和LT阻塞,并完成压力测试
  • 完善lock.h中的封装类,统一使用该同步机制
  • 改进代码结构,更新局部变量懒汉单例模式
  • 优化数据库连接池信号量与代码结构
  • 使用RAII机制优化数据库连接的获取与释放
  • 优化代码结构,封装工具类以减少全局变量
  • 编译一次即可,命令行进行个性化测试更加友好
  • main函数封装重构
  • 新增定时器时间轮,时间堆的设计方案

基础测试

  • 服务器测试环境

    • Ubuntu版本16.04
    • MySQL版本5.7.29
  • 浏览器测试环境

    • Windows、Linux均可
    • Chrome
    • FireFox
    • 其他浏览器暂无测试
  • 测试前确认已安装MySQL数据库

    // 建立yourdb库
    create database yourdb set utf8;
    
    // 创建user表
    USE yourdb;
    CREATE TABLE user(
        username char(50) NULL,
        passwd char(50) NULL
    )ENGINE=InnoDB;
    
    // 添加数据
    INSERT INTO user(username, passwd) VALUES('name', 'passwd');
  • 修改main.c中的数据库初始化信息

    //数据库登录名,密码,库名
    string user = "root";
    string passwd = "root";
    string databasename = "yourdb";
  • 生成server

    make server
  • 启动server

    ./server
  • 浏览器端

    ip:9006

个性化测试

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

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

  • -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

若使用CGI数据库校验方式,按如下编译代码,若使用同步校验,则跳过下面修改与生成CGI步骤.

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

    // root root修改为服务器数据库的登录名和密码
    // yourdb修改为上述创建的yourdb库名
    con = mysql_real_connect(con, "localhost", "root", "root", "yourdb", 3306, NULL, 0);
  • 生成CGISQL.cgi

    make CGISQL.cgi

测试示例命令与含义

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

Demo

  • 注册演示
  • 登录演示
  • 请求图片文件演示(6M)
  • 请求视频文件演示(39M)

压力测试

Webbench对服务器进行压力测试,在ET非阻塞和LT阻塞模式下均可实现上万的并发连接. 这里以同步日志,不使用优雅关闭连接为例.

  • ET非阻塞,18657 QPS
  • LT阻塞,22868 QPS
  • 并发连接总数:10500
  • 访问服务器时间:10s
  • 所有访问均成功

注意: 使用本项目的webbench进行压测时,若报错显示webbench命令找不到,将可执行文件webbench删除后,重新编译即可。

框架

web端界面

  • 判断是否注册
  • 注册
  • 注册失败提示
  • 登录
  • 登录失败提示

致谢

Linux高性能服务器编程,游双著.