Skip to content

My poor web server: 在前人大佬的基础上修改了部分内容,实现了可以登陆账号访问Web服务器中的图片、音视频等资源。

License

Notifications You must be signed in to change notification settings

JianjiaoSQ/MyPoorWebServer

Repository files navigation

My Poor Web Srever

概述

此项目基本模型属于的是B/S模型;(Browser-Server Model)

服务器编程框架

IO 处理单元

  • 非阻塞socket

    socket 在创建的时候默认是阻塞的,设置为非阻塞才能发挥 epoll 的作用;

  • 事件处理模式

    • 三类事件:IO事件、定时事件、信号

    事件处理模式有:Reactor、Proactor;

    同步IO通常用于实现 Reactor;而异步IO通常用于实现 Proactor;本项目中的 Proactor 则是由同步IO模拟实现的;

    Reactor 主线程(IO处理单元)只负责监听文件描述符是否有事件发生,有的话则通知工作线程(逻辑单元,线程池中的线程),主线程没有作任何其他实质性工作;读写数据、接受新连接、处理客户请求均在工作线程中完成;因此主线程往 epoll 内核事件表中注册的是 cocket 上的就绪事件

    Proactor IO 操作都交给主线程完成,工作线程只负责业务逻辑处理(即本项目中的报文解析和生成应答报文),因此主线程往 epoll内核事件表中注册的是 读完成事件,工作线程业务处理完成后往 epoll 内核事件表注册 写完成事件

    模拟 Proactor

  • 并发模型

    并发的目的是让程序同时执行多个任务;

    并发模式是指IO处理单元和多个逻辑单元之间协调完成任务的方法;

    • 并发编程模式:半同步/半异步模式、领导者/追随者模式;本项目使用的就是半同步/半异步模式的优化版本 半同步/半反应堆模式;

IO 同步/异步 与 并发模式中的同步/异步 ??

半同步/半异步:同步指程序完全按照代码顺序来执行;异步是指程序的执行由系统事件来驱动;(中断、信号等)
IO 同步/异步:指区分内核向应用程序通知的是哪种IO事件(就绪还是完成事件),以及该由谁来完成IO读写(应用程序还是内核)

  • 半同步/半反应堆

    • 同步线程简单,能同时处理多个请求;异步线程,实时性强,执行效率高;—— 工作线程
    • 同步线程用于处理客户逻辑;异步线程用于处理IO事件;—— 主线程
  • 领导者/追随者模式

    • 也就是不停的换领导者,先推选新的领导者,自己去处理接受的IO读写和逻辑,新的领导者继续监听新的连接;缺点就是仅支持一个事件源集合;

逻辑处理

  • 有限状态机

    • 主从状态机应用:HTTP 报文的读取与解析
    ——— 图片来源见水印 ———

    主状态机三个状态:CHECK_STATE_REQUESTLINE(请求行)CHECK_STATE_HEADER(请求头)CHECK_STATE_CONTENT(消息体 - 仅用于 POST)

    从状态机三个状态:LINE_OK,LINE_OPEN,LINE_BAD

线程池、连接池

线程池:预先存放一定数量的线程,请求来了直接用,避免使用时才构造带来的较大开销; 连接池:一样的目的,作用是用于连接数据库,查询数据库中中存放的用户数据库(包含用户名称和密码)

在 游双《Linux高性能服务器》书中,提供了详细的代码及说明;


  • 三种锁:信号量、互斥锁、条件变量
    • 半同步/半反应堆:信号量或者条件变量
    • 互斥锁:更改资源时就需要加互斥锁

定时器

定时器实现有:升序链表定时器,时间轮定时器,时间堆定时器;此项目利用时间轮定时器关闭非活动连接;

升序链表:添加定时器的事件复杂度O(n),删除操作O(1),执行任务O(1);

时间轮:添加O(1),删除O(1),执行O(n) 实际效率比 O(n) 效果好;使用多轮时效率也越接近O(1);

时间堆:添加O(logn),删除O(1),执行O(1);

Demo


压测

实现近10K的并发量;


下一步

  • 实现文件上传或者下载功能;

测试

环境

MySQL & ubuntu:

mysql Ver 8.0.25-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu))

Browser:

windows (MS Edge) & linux (Firefox) 均测试通过

运行

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

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

    //数据库登录名,密码,库名
    string user = "你的mysql用户名";  
    string passwd = "密码";
    string databasename = "你的数据库名称"; 
  • build

    sh ./build.sh
  • 启动server

    ./server

致谢

书籍《Linux高性能服务器编程》- 游双著;


Github作者: 在此大佬代码基础上修改@qinguoyi

About

My poor web server: 在前人大佬的基础上修改了部分内容,实现了可以登陆账号访问Web服务器中的图片、音视频等资源。

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages