TinyWebServer icon indicating copy to clipboard operation
TinyWebServer copied to clipboard

Linux下高性能服务器,详细梳理后台各个知识点

TinyWebServer

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

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

模块概述

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

Update

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

基础测试

  • 服务器测试环境

    • 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
  • [x] 端口9007
  • [x] 同步数据库校验,使用连接池
  • [x] 异步写入日志
  • [x] 使用LT水平触发
  • [x] 使用优雅关闭连接
  • [x] 数据库连接池内有10条连接
  • [x] 线程池内有10条线程

Demo

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

压力测试

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

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

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

框架

web端界面

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

致谢

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