架构与面试讲解
C++ 后端服务器框架架构与面试讲解
CHAPTER 01

架构与面试讲解

9 分钟阅读 · 2,484 字

本文档用于面试场景,目标是帮助你在 5~15 分钟内清晰讲解项目的整体设计、核心模块实现细节、可被深挖的问题、与 Go + Gin 的差异以及改进方向。


1. 项目定位与设计目标

c++Server 是一个轻量级 C++ HTTP 服务框架,当前具备:

  • HTTP 服务接入与请求分发
  • 路由与中间件机制
  • 请求解析(query/form/json/multipart)
  • 响应构建(json/text/file/fileStream)
  • 线程池并发模型
  • 协程与调度器基础设施(跨平台)
  • MySQL / Redis 连接器
  • JWT 与密码哈希
  • 基础日志与崩溃处理

项目特点是“底层可控、模块化清晰、可跨平台”,但在工业化能力(连接池、可观测性、协议完备性)上仍有演进空间。


2. 总体架构分层

2.1 分层视图

  1. 接入层(Network / HTTP)

    • 监听端口、accept 连接、读取请求、解析协议、回写响应
    • 关键实现:src/Server.cpp、include/Server.h
  2. 并发调度层(ThreadPool / Coroutine)

    • 线程池并发执行连接任务
    • 协程与调度器提供用户态协作式调度能力
    • 关键实现:src/Threadpool.cpp、include/Coroutine.h、src/Coroutine.cpp
  3. 路由与处理层(Router / Handler / Middleware)

    • method + path 路由命中
    • 全局与路由级 middleware 链
    • handler 负责业务逻辑并填充 Response
    • 关键实现:src/route.cpp、src/handlers/common_handler.cpp
  4. 基础设施层(JSON / DB / Redis / JWT / Config / Log)

    • JSON 解析序列化、MySQL/Redis 操作、鉴权与加密、日志、配置
    • 关键实现:include/JsonValue.h、include/DBConnector.h、include/RDConnector.h、include/jwt.h、include/ApiSender.h

2.2 依赖关系(简版)

  • main -> Server + registerRoutes
  • Server -> ThreadPool
  • Server::parseRequest -> Request::parseBody -> JsonValue
  • handler -> Response
  • 业务侧可调用 DBConnector / RdConnector / JWT / ApiSender
  • Server / Response / 其他模块 -> Log

3. 请求处理主链路(面试必背)

3.1 启动阶段

  1. main.cpp 中创建 Server 实例
  2. 调用 registerRoutes(app) 注册路由
  3. app.run() 进入监听循环

3.2 运行阶段(核心流程)

  1. Server::run() 创建监听 socket(IPv4/IPv6)
  2. accept() 获取客户端连接
  3. 将连接处理函数投递到线程池:threadpool_.addTask(&Server::handleClient, ...)
  4. handleClient() 从 socket 读取请求数据:
    • 先读取并解析 header
    • 从 Content-Length 得到 body 长度,继续读取 body
  5. parseRequest() 解析请求行、header、query
  6. request.parseBody() 按 Content-Type 解析 body
  7. 执行 middleware 链(全局 + 路由级)
  8. findRoute(method, path) 命中 handler 并执行
  9. buildResponse(response) 构建 HTTP 报文并 send
  10. 关闭连接或结束处理

3.3 请求数据结构

Request 关键字段:

  • method, path, headers, body
  • queryParams
  • bodyParams
  • jsonBody
  • uploadedFiles

Response 关键字段:

  • statusCode, headers, body
  • streamWriter(用于大文件流式输出)

4. 核心模块细节

4.1 协程与调度器模块(Coroutine / Scheduler)

职责

  • 提供用户态协程上下文切换
  • 提供任务提交、工作窃取、时间片抢占基础能力
  • 跨平台实现(Linux ucontext,Windows Fiber)

关键类型与函数

  • Coroutine
    • resume()
    • suspend()
    • state()
  • Scheduler
    • submit() / go()
    • start() / stop()
    • run_on_worker_thread()
    • configureTimeSlice()
    • shouldPreempt()
  • yield() / yield_now()

当前状态(面试建议说法)

  • 协程基础设施完整,支持平台差异封装与调度队列。
  • 但在 HTTP 主链路中仍以线程池同步处理为主,协程尚未全面承载 I/O 处理链路。

4.2 线程池模块(ThreadPool)

职责

  • 管理 worker 线程
  • 提供线程安全任务队列
  • 支撑连接并发处理和异步任务执行

关键实现点

  • maxTasks_ = 10000:限制队列长度,防止无限堆积
  • addTask():线程安全入队,支持可变参数绑定
  • worker 循环:cv_.wait -> pop task -> execute

面试可讲的权衡

  • 优点:实现稳定、易理解、适合快速搭建服务并发框架
  • 不足:阻塞 I/O 场景下线程开销较大;队列满时拒绝策略较基础

4.3 服务器模块(Server)

职责

  • 网络接入(监听、accept)
  • HTTP 请求解析
  • 路由与 middleware 执行
  • 响应报文构建与发送

关键函数

  • run()
  • handleClient() / handleClientIPv6()
  • parseRequest()
  • findRoute()
  • buildResponse()
  • addRoute(), get/post/put/del()
  • use()(全局中间件)

请求解析支持

  • Query 参数
  • application/x-www-form-urlencoded
  • application/json
  • multipart/form-data(含文件)
  • text/plain / xml / 自动类型检测

响应能力

  • json() / text() / success() / error()
  • file():整文件加载响应
  • fileStream():分块流式输出(更适合大文件)

4.4 路由与中间件模块

路由机制

  • 核心结构是 method -> path -> RouteEntry
  • 路径匹配当前为精确匹配
  • 支持 RouterGroup 前缀分组

Middleware 机制

  • 类型:std::function<bool(const Request&, Response&)>
  • 执行链:全局 middleware -> 路由 middleware -> handler
  • middleware 返回 false 时可中断后续执行

当前业务路由

  • 根路径(GET/POST)
  • 文件下载接口(普通下载 + 流式下载)

4.5 JSON 模块(JsonValue)

职责

  • 提供 JSON 数据模型(null/string/number/bool/object/array)
  • 支持 JSON 字符串解析与序列化

关键能力

  • fromJson()
  • toJson()
  • 递归解析:
    • parseValue()
    • parseObject()
    • parseArray()
    • parseString()

实现特征

  • 手写递归下降解析,兼容常见 JSON 语法
  • 支持转义字符与基础数值格式

面试要点

  • 优势:可控、无外部依赖、便于按需扩展
  • 风险:复杂 JSON 边界、深层嵌套、性能与成熟库仍有差距

4.6 数据库模块(DBConnector / Model)

职责

  • MySQL 连接管理
  • SQL 查询与执行封装
  • 错误信息记录

关键函数

  • DBConnector::initInstance()
  • DBConnector::getInstance()
  • connect()
  • query()
  • execute()
  • escapeSqlLiteral()

设计现状

  • 单例模式管理连接参数与连接句柄
  • 提供通用二维结果结构(vector<map<string,string>>)

面试风险点

  • 当前偏“单连接模型”,高并发下扩展性与线程安全策略需加强
  • 缺少连接池、超时分级、重试策略、事务抽象层

4.7 Redis 模块(RdConnector)

职责

  • Redis 连接管理与基础 KV 操作

关键函数

  • connect()
  • get()
  • set() / set(..., expireSeconds)
  • exists()
  • del()
  • getError()

面试要点

  • 已覆盖常见缓存基础能力
  • 工业化增强方向:连接池、超时重试、pipeline、集群/哨兵支持

4.8 API 发送模块(ApiSender)

职责

  • 向外部 HTTP API 发起请求(同步/异步)
  • 支持 GET/POST/PUT/DELETE/PATCH
  • 支持回调

关键接口

  • request()(异步通用)
  • requestSync()(同步)
  • get/post/put/del/patch()
  • doRequest()(底层执行)

实现特征

  • 内部可用线程池执行异步任务
  • 封装 ApiResponse { statusCode, body, error, success }

4.9 加密与鉴权模块(JWT)

职责

  • JWT 令牌生成与校验(HS256)
  • claims 解析
  • 密码哈希与验证

关键接口

  • generateToken()
  • verifyToken()
  • parseClaims()
  • encrypt_password()
  • verify_password()

安全实现点

  • 包含 constant_time_compare(常量时间比较)
  • 支持默认 TTL 与自定义 claims

面试建议

  • 明确说明令牌生命周期管理、密钥加载方式、过期校验策略
  • 说明后续可接入更成熟安全库与密钥管理方案

4.10 配置、日志、稳定性模块

配置

  • Config + YamlParser 用于读取配置项
  • 面试可强调“配置化替代硬编码”思路

日志

  • Log 提供基础文件日志写入
  • 当前适合基础排障,后续可升级为结构化日志与分级日志

稳定性

  • CrashHandler 负责崩溃兜底与异常场景处理
  • 可作为“工程可靠性意识”的加分点

5. 关键时序图(文字版)

  1. Client 发送 HTTP 请求到 Server
  2. Server 接受连接并投递线程池任务
  3. Worker 线程执行 handleClient
  4. 解析 header/body,构建 Request
  5. 执行 middleware 链
  6. 路由匹配并执行 handler
  7. handler 访问 DB/Redis/JWT/Json 等模块
  8. 构建 Response 并回写 socket
  9. 记录日志并结束连接处理

6. 面试高频深挖点(按优先级)

  1. 并发模型:为何采用线程池?协程为何未完全接管主链路?
  2. HTTP 兼容性:Content-Length 处理、长连接策略、边界条件与异常包处理
  3. 路由能力:精确匹配 vs 参数路由,如何扩展 REST 友好能力
  4. 数据库与缓存:单连接模型在高并发场景的问题与演进路径
  5. 安全性:JWT 签名校验、密码哈希、下载接口路径安全
  6. 可观测性:如何定位慢请求、错误高峰、资源瓶颈
  7. 跨平台设计:Windows/Linux 差异抽象与维护成本

7. 与 Go + Gin 的对比(面试表达模板)

当前项目优势

  • 对底层网络与并发策略可控
  • C++ 生态下便于做高性能定制
  • 可作为“从 0 到 1 搭建服务器核心”的工程能力证明

相对不足

  • 协程与 I/O 尚未完全协同
  • DB/Redis 缺连接池与成熟治理能力
  • 路由、中间件生态能力弱于 Gin
  • 可观测性与运维链路未形成完整闭环

一句话总结

“Go + Gin 在工业化能力上开箱即用更成熟;本项目的价值在于底层机制可控与可深度定制,但需要继续补齐池化、可观测、协议完备性等能力。”


8. 改进路线图(可直接回答‘下一步怎么做’)

短期(1周)

  • 配置全面接入启动流程(端口、DB、Redis、JWT)
  • 增加健康检查与统一错误响应
  • 增强日志字段(request_id、latency、status)

中期(1个月)

  • MySQL/Redis 连接池化与超时重试机制
  • 补参数路由、统一上下文对象、标准中间件链
  • 压测基线与回归指标(QPS/P95/P99)

长期(1季度)

  • 事件驱动 I/O(epoll/IOCP)与协程协同
  • Metrics + Tracing + 集中日志完整可观测体系
  • 容器化部署与发布治理(探针、滚动发布、回滚)

9. 面试速背版(30秒)

“这个项目是一个 C++ 轻量 HTTP 服务框架,分接入层、并发调度层、路由处理层和基础设施层。主链路是 accept -> 线程池 -> 请求解析 -> middleware -> handler -> 响应回写。我重点做了协程调度、线程池、JSON 解析、DB/Redis 接入、JWT 认证这些基础能力。当前优势是底层机制可控,短板是连接池、可观测和协议完备性,我的改进方案是短期配置化和健康检查,中期池化和中间件标准化,长期把事件驱动 I/O 与协程打通并完善运维体系。”

全部章节