Giter Site home page Giter Site logo

c-based-high-concurrency-multi-reactor-model-httpserver's Introduction

C-based-high-concurrency-multi-reactor-model-httpserver

Highly concurrent multi-reactor model http server written in C webserver概览 • epoll ET模式(边缘触发) • mysql(业务部分的内容) • 连接池(数据库) • 线程池 • 日志 • 定时器 • Reactor模式 • http • 大端序小端序互转 hton • 读写缓冲区 大概流程 主线程监听连接 主线程让epoll监听活跃的文件描述符 处理完之后开工作线程 工作线程任务(读写是分开的,不一定是同一个线程搞操作) 读写缓冲区是数据httpconn的,httpconn是一个类,一个用户一个实例。所以直接独立了。 • read客户端数据(用非阻塞IO) o 有个读缓冲,每个连接独享一个读 和写缓冲,有个65K缓冲区 保证能一次读完,读不完就扩容 • 以下业务逻辑 o 先去看读缓冲有没有数据 o 解析HTTP o 生成响应数据 o 封装响应传回去 Reactor没有分离读和业务逻辑,proactor才可以实现封装业务逻辑 性能相关 半同步半反应堆 个人答案: • 一种高效的并发模式(半同步/半异步模式)的一种实现方式,另一种并发模式是领导者/追随者模式。 • 并发模式指的是I/O处理单元和多个逻辑单元之间协调完成任务的方法。 • 这里的同步和异步与I/O模型中的同步与异步不同: o I/O模型中的同步异步:内核向应用程序通知的是就绪事件还是完成事件  并发模型中的同步异步:程序执行顺序是否按照代码顺序执行。中断、信号。 • 同步线程:按照同步方式运行的线程 o 优点:逻辑简单  缺点:效率相对较低、实时性较差 • 异步线程:按照异步方式运行的线程 o 优点:执行效率高、实时性强  缺点:程序复杂、难以调试、不适合大量并发。 • 半同步/半反应堆的内容: o 异步线程只有一个,由主线程充当。负责监听所有socket伤的事件。如果有新连接请求,主线程接受得到新的连接socket,往epoll内核事件表中竹醋socket上的读写事件。如果连接上有读写事件,主线程将该连接socket插入请求队列。所有工作线程(同步线程)睡眠在请求队列上,当有任务到来,通过竞争的方式获得任务管理权。  上面的方式采用的事件处理模式为Reactor模式。要求工作线程自己从socket傻姑娘读取客户请求和往socket上写入服务器应答。  也可以采用模拟的Proactor事件处理模式。要求主线程完成数据的读写,主线程将应用程序数据、任务类型等信息封装成一个任务对象,然后插入请求队列;工作线程从请求队列中取得任务对象后,直接处理即可,不需要读写操作。 • 半同步/半反应堆的缺点: o 主线程和工作线程共享请求队列。主线程添加任务、工作线程取出任务,都需要对请求队列进行加锁保护,从而耗费cpu时间。  每个工作线程在同一时间只能处理一个客户请求。 线程池如何实现 个人答案: • 主线程轮流选取子线程 • 通过共享队列+互斥量来同步 • 信号量来通信 • 同步问题 线程的数目 个人答案: • CPU密集型,线程数和CPU数目相同即可 • I/O密集型,线程数目可以大一点。 o (线程等待时间/线程CPU时间 + 1)* CPU数目 多进程模型 • 为每个客户端分配一个进程来处理请求。 • 服务器的主进程负责监听客户的连接,一旦与客户端连接完成,accept() 函数就会返回一个「已连接 Socket」,这时就通过 fork() 函数创建一个子进程,实际上就把父进程所有相关的东西都复制一份,包括文件描述符、内存地址空间、程序计数器、执行的代码等。 o 根据返回值来区分是父进程还是子进程,如果返回值是 0,则是子进程;如果返回值是其他的整数,就是父进程。  因为子进程会复制父进程的文件描述符,于是就可以直接使用「已连接 Socket 」和客户端通信了。  子进程不需要关心「监听 Socket」,只需要关心「已连接 Socket」;父进程则相反,将客户服务交给子进程来处理,因此父进程不需要关心「已连接 Socket」,只需要关心「监听 Socket」。 • 可能出现的问题: o 当「子进程」退出时,实际上内核里还会保留该进程的一些信息,也是会占用内存的,如果不做好“回收”工作,就会变成僵尸进程,随着僵尸进程越多,会慢慢耗尽我们的系统资源。  父进程要“善后”好自己的孩子,怎么善后呢?那么有两种方式可以在子进程退出后回收资源,分别是调用 wait() 和 waitpid() 函数。  进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源。 多线程模型 • 线程是运行在进程中的一个“逻辑流”,单进程中可以运行多个线程,同进程里的线程可以共享进程的部分资源的,比如文件描述符列表、进程空间、代码、全局数据、堆、共享库等,这些共享资源在上下文切换时是不需要切换,而只需要切换线程的私有数据、寄存器等不共享的数据,因此同一个进程下的线程上下文切换的开销要比进程小得多。 • 当服务器与客户端 TCP 完成连接后,通过 pthread_create() 函数创建线程,然后将「已连接 Socket」的文件描述符传递给线程函数,接着在线程里和客户端进行通信,从而达到并发处理的目的。 • 注意事项 o 父进程accept后会把socket放入一个队列。然后线程从这个队列中取socket做操作 o 这个队列是全局的,每个线程都会操作,为了避免多线程竞争,线程在操作这个队列前要加锁。 大端序小端序 网络序是大端字节序 大端字节序是看着一样的,数据低位存在内存大位(高位) 小端字节序看着是反过来的,数据低位存在内存小位(低位) 字节序的单位应该是字节,所以string(char为组织结构)是没有大小端之分的。 但是看int和short是能看出来是大端字节序还是小端字节序,借助union。 有现成的转换函数。BSD Socket提供了封装好的转换接口,方便程序员使用。包括从主机字节序到网络字节序的转换函数: htons、htonl;从网络字节序到主机字节序的转换函数:ntohs、ntohl。 h - host 主机,主机字节序 to - 转换成什么 n - network 网络字节序 s - short unsigned short l - long unsigned int sql连接池 实际生产中,数据库连接是一种关键的、有限的、昂贵的资源。怎样清空不活跃的用户是需要解决的问题。数据库连接池初始化后需要创建一定量数据库连接放到连接池中。数据库连接池有最大连接数与最小连接数。 不论数据库连接是否使用,连接池都将一直保持最小连接数的连接。连接池的达到最大数据库连接数量时,再有新的连接则会被加入到等待队列中。 设计思路 容器 对连续内存没有要求,要求头尾插入删除时间复杂度低即可。list容器即符合要求。所以通过list容器存放空闲的连接。 线程锁 对容器进行读取放回操作时,需要加锁保证安全性。 单例模式 由于所有连接需要被统一管理,所以维护一个连接池对象,这个对象采用单例模式实现。 获取释放连接 获取连接 • 容器有空闲连接,直接拿 • 容器无空闲连接 o 未达上限,自己创建  达上限,报错打回等待(这一步是有改进空间的,可以阻塞掉等待。不过也不一定好) 释放连接 • 放回容器 • 目前暂无较好的销毁连接策略 销毁对象池

  1. 关闭销毁池中连接
  2. 释放连接池对象(clear操作)
  3. 完成释放

c-based-high-concurrency-multi-reactor-model-httpserver's People

Contributors

jinxiwen avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.