Skip to content

Kiwi 服务器入口

marsevilspirit edited this page Aug 10, 2025 · 1 revision

Kiwi 服务器入口(以源码为准)

快速上手

  • 编译与运行(默认监听 127.0.0.1:9221)
cargo run -p server
  • 建议开启日志(env_logger):
RUST_LOG=info cargo run -p server
  • 使用 redis-cli 验证:
redis-cli -h 127.0.0.1 -p 9221
127.0.0.1:9221> SET k v
OK
127.0.0.1:9221> GET k
"v"

启用日志输出(env_logger)

  • 初始化位置(源码依据):
// init logger
// set env RUST_LOG=level to control
env_logger::init();
  • 基本用法(不同终端)

    • Linux/macOS(bash/zsh)
      • RUST_LOG=info cargo run -p server
    • Windows PowerShell
      • $env:RUST_LOG='info'; cargo run -p server
    • Windows cmd.exe
      • set RUST_LOG=info && cargo run -p server
  • 常见级别(从少到多):error < warn < info < debug < trace

    • 示例:
      • RUST_LOG=debug cargo run -p server
  • 按模块过滤(crate 或模块路径)

    • 仅提升网络层日志为 debug:
      • RUST_LOG=info,net=debug cargo run -p server
    • 仅提升 TCP 子模块:
      • RUST_LOG=info,net::tcp=debug cargo run -p server
    • 指定多个模块:
      • RUST_LOG=cmd=debug,storage=info cargo run -p server
  • 预期输出示例(不同级别会有差异):

    • info: tcp listener listen on 127.0.0.1:9221
    • info: Listening on TCP: 127.0.0.1:9221
    • error: Protocol error: ... / Write error: ...

提示:日志格式与颜色由 env_logger 默认样式决定,可通过环境变量进一步定制(例如在 CI 中关闭颜色)。

默认监听地址(源码依据)

  • main 入口固定地址:
let addr = String::from("127.0.0.1:9221");
let protocol = "tcp";
info!("tcp listener listen on {addr}");
if let Some(server) = ServerFactory::create_server(protocol, Option::from(addr)) {
    server.run().await.expect("Failed to start the server. Please check the server configuration and ensure the address is available.");
}
  • TcpServer 的缺省地址:
addr: addr.unwrap_or("127.0.0.1:9221".to_string()),

连接与并发模型(概述)

  • 绑定与监听:
let listener = TcpListener::bind(&self.addr).await?;
info!("Listening on TCP: {}", self.addr);
  • 每连接一个任务:
let (socket, _) = listener.accept().await?;
let s = TcpStreamWrapper::new(socket);
let mut client = Client::new(Box::new(s));
tokio::spawn(async move {
    process_connection(&mut client, storage, cmd_table).await.unwrap();
});
  • 处理流程总览(配合 Net 文档):
    • 读取请求 → RESP2 解析 → 形成 argv/cmd_name → 查表执行 → 将 RespData 编码写回

运行时日志与健康检查

  • 服务启动:
    • info 日志会打印 Listening on TCP: 127.0.0.1:9221
    • 同时 main 也会打印 tcp listener listen on 127.0.0.1:9221
  • 连接异常:
    • 接受或写回失败会在日志中体现(如 Write error / Failed to accept)
  • 健康检查:
    • 用 redis-cli 执行 PING 等价的最小验证:SET/GET 往返即可判定

常见排错

  • 端口被占用:
    • 现象:启动时报 bind 错误
    • 处理:确认系统中 9221 是否已被占用,关闭占用进程或临时更换端口(源码中地址在 main 与 TcpServer 缺省中定义)
  • 无法连接:
    • 现象:redis-cli 超时或被拒绝
    • 处理:确认服务已启动、地址和端口正确、没有被防火墙阻断
  • 协议错误:
    • 现象:日志提示 Protocol/Parse 错误
    • 处理:确认客户端发送的是合法 RESP2(使用标准 redis-cli 最稳妥)

Unix 套接字(仅 Unix 平台)

  • 创建与监听:
let listener = UnixListener::bind(&self.path)?;
info!("Listening on Unix Socket: {}", self.path);
  • 接入与错误处理:
match listener.accept().await {
    Ok((socket, _)) => { /* ... */ }
    Err(e) => { error!("Failed to accept connection: {e:?}"); }
}

更多细节请参阅 Net 模块文档。

Clone this wiki locally