Sylar Webserver 是一个使用 C++ 实现的高效 Web 服务器项目,具备高并发处理能力和良好的可扩展性。该项目涵盖了日志模块、配置模块、协程调度模块、网络模块和 HTTP 模块等多个核心模块,下面将对这些模块进行详细介绍。
- 多级别日志记录:支持 DEBUG、INFO、WARN、ERROR、FATAL 等多种日志级别,支持Logger,LoggerAppender多层次设定日志级别。
- 多目标输出:可以将日志输出到控制台或文件,满足不同场景下的日志查看需求。
- 异步日志写入:采用
双缓冲区异步日志写入机制,多个线程可以同时将日志写入缓冲区,提高了日志写入的性能。缓冲区管理器会定期将缓冲区中的日志数据写入目标输出,避免了同步写入日志时可能产生的性能瓶颈。
- YAML 文件解析:支持从 YAML 文件中读取配置信息,通过解析 YAML 文件的节点和数据结构,将配置信息提取出来并进行处理。
- 配置变量映射:将解析后的配置信息映射到项目中的配置变量,使得开发人员可以在代码中方便地访问和使用这些配置。例如,通过配置文件可以设置服务器的端口号、日志级别等参数,在代码中直接获取这些配置变量的值。
- 数据类型转换:支持不同数据类型的配置信息,如基本数据类型、容器类型(如 vector、list、map 等)。在读取配置信息时,会自动进行数据类型的转换,确保配置信息能正确应用到项目中。
- 配置变更通知:提供配置变更的回调机制,当配置值发生变化时,可以触发相应的回调函数,通知系统进行相应的调整。例如,当日志级别配置发生变化时,可以及时更新日志模块的日志级别。
约定大于配置。
- 线程:封装 pthread 库
- 协程:创建和管理协程,包括协程的创建、销毁、暂停和恢复等操作。
(仿Boost协程实现,使用汇编实现协程切换) - 任务调度:从任务队列中取出任务并进行调度,按照先来先服务策略。支持将任务调度到指定的线程或协程中执行,提高任务处理的效率。
- I/O 多路复用:使用
epoll实现 I/O 多路复用,能够同时监听多个文件描述符的 I/O 事件。当有事件发生时,触发 epoll_wait 将事件对应任务添加到调度队列中,等待调度。 - 定时器管理:支持
定时器功能,在指定的时间点或时间间隔后执行相应的任务。使用最小堆set管理所有的定时器任务。
- 地址解析与绑定:支持
地址解析功能,将域名或 IP 地址转换为对应的网络地址结构。可以将套接字绑定到指定的地址和端口,确保服务器能够在指定的地址和端口上监听客户端的连接请求。 - 套接字创建与管理:提供了创建不同类型套接字的接口,如 TCP 套接字、UDP 套接字等。同时,对套接字进行管理,包括套接字的初始化、关闭等操作。
- 服务器与客户端实现:实现了 TCP 服务器和 UDP 服务器,支持多客户端连接。服务器可以监听指定的端口,接收客户端的连接请求,并处理客户端发送的数据。同时,也提供了客户端的实现,方便与其他服务器进行通信。
网络模块
├─ 基础地址类(Address系列)
│ ├─ Address(基类)
│ │ ├─ IPAddress(IP地址抽象)
│ │ │ ├─ IPv4Address(IPv4地址)
│ │ │ └─ IPv6Address(IPv6地址)
│ │ ├─ UnixAddress(Unix域套接字地址)
│ │ └─ UnknownAddress(未知协议地址)
│ └─ 功能:地址解析、网络/广播地址计算、接口地址查询
│
├─ 套接字操作(Socket类)
│ ├─ 核心功能:创建套接字(TCP/UDP)、绑定(bind)、连接(connect)、监听(listen)、接收连接(accept)、数据收发(send/recv)
│ ├─ 协议支持:IPv4、IPv6、Unix域套接字
│ └─ 关联类:Address(地址操作)、FdManager(文件描述符管理)
│
├─ 服务器抽象(TcpServer类)
│ ├─ 核心功能:监听连接、管理客户端生命周期、业务逻辑扩展(handleClient虚函数)
│ ├─ 依赖:Socket(套接字操作)、IOManager(协程调度)
│ └─ 扩展场景:HTTP服务器(HttpServer)、自定义业务服务器
│
└─ 协程与Hook支持
├─ Hook模块:替换系统IO调用(如read/write/connect),实现协程化异步IO
│ ├─ 关键函数:do_io(封装阻塞IO为协程调度)、connect_with_timeout(带超时的连接)
│ └─ 依赖:IOManager(协程调度)、FdManager(文件描述符状态)
├─ IOManager:协程调度器,管理IO事件(READ/WRITE)的注册与触发
└─ FdManager:文件描述符管理器,跟踪套接字状态(超时、是否阻塞)
- HTTP 请求解析:解析客户端发送的 HTTP 请求,包括请求行、请求头和请求体。通过解析请求信息,提取出请求的方法、URL、参数等关键信息,为后续的处理提供基础。
- HTTP 响应处理:根据请求的处理结果,生成相应的 HTTP 响应,包括响应行、响应头和响应体。支持设置不同的状态码和响应头信息,确保客户端能够正确理解服务器的响应。
- Servlet 分发:实现了
Servlet 分发机制,根据请求的 URL 路径将请求分发到相应的 Servlet 进行处理。开发人员可以定义不同的 Servlet 来处理不同的业务逻辑,提高代码的可维护性和可扩展性。 - 长连接与短连接支持:支持 HTTP 长连接和短连接,根据客户端的请求和服务器的配置,选择合适的连接方式。长连接构建
连接池,可以减少连接建立和关闭的开销,提高通信效率;短连接则适用于一次性的请求响应场景。
HTTP 模块
├─ 协议定义层(http.h)
│ ├─ HttpRequest(HTTP 请求对象)
│ ├─ HttpResponse(HTTP 响应对象)
│ ├─ HttpMethod(HTTP 方法枚举)
│ └─ HttpStatus(HTTP 状态码枚举)
│
├─ 协议解析层(http_parser.h/.cc)
│ ├─ HttpRequestParser(HTTP 请求解析器)
│ ├─ HttpResponseParser(HTTP 响应解析器)
│ └─ 依赖:http-parser 库(处理底层协议解析逻辑)
│
├─ 会话管理层(http_session.cc)
│ └─ HttpSession(HTTP 会话类)
│ ├─ recvRequest(接收并解析 HTTP 请求)
│ └─ sendResponse(发送 HTTP 响应)
│ └─ 依赖:SocketStream(网络 IO 基类)
│
├─ 客户端操作层(http_connection.cc)
│ ├─ HttpConnection(HTTP 客户端连接类)
│ │ ├─ sendRequest(发送 HTTP 请求)
│ │ └─ recvResponse(接收并解析 HTTP 响应)
│ │ └─ 依赖:Socket(网络套接字)、HttpResponseParser
│ └─ HttpResult(HTTP 操作结果封装)
│
└─ 连接池管理层(http_connection.cc)
└─ HttpConnectionPool(HTTP 连接池)
├─ getConnection(获取复用连接)
└─ ReleasePtr(释放连接回池或销毁)
部署
sudo apt-get install libevent-dev libhiredis-dev
sudo apt-get install sqlite3../bin/orm ../bin/orm_conf/ ../orm_outsudo apt install zookeeper zookeeperd