写点什么

每日一 R「15」实践课之 kv-server(一)

作者:Samson
  • 2022 年 8 月 25 日
    上海
  • 本文字数:2021 字

    阅读完需:约 7 分钟

每日一R「15」实践课之 kv-server(一)

今天是实践课程,我们一起跟着老师来构建一个 KV server。在此之前,我们先来学习下 Rust 中一个 package 典型的目录结构。

01-典型的 package 目录结构

.├── Cargo.lock├── Cargo.toml├── src/│   ├── lib.rs│   ├── main.rs│   └── bin/│       ├── named-executable.rs│       ├── another-executable.rs│       └── multi-file-executable/│           ├── main.rs│           └── some_module.rs├── benches/│   ├── large-input.rs│   └── multi-file-bench/│       ├── main.rs│       └── bench_module.rs├── examples/│   ├── simple.rs│   └── multi-file-example/│       ├── main.rs│       └── ex_module.rs└── tests/    ├── some-integration-tests.rs    └── multi-file-test/        ├── main.rs        └── test_module.rs
复制代码


这是 Cargo 推荐的目录结构,其中主要的目录解释如下:


  • src 是源码目录

  • src/lib.rs 是默认的 lib 包根

  • src/main.rs 是默认的二进制包根,src/bin/ 是其他二进制的包跟

  • tests 是继承测试代码目录

  • benches 是基准测试代码目录

  • examples 是示例代码


Rust package 相关的更多内容,可以参考:[1] crate 和 module [2] cargo target

02-一个示例实现

首先,要实现课程中给出的示例,并能成功运行。包目录结构:


.├── Cargo.lock├── Cargo.toml├── api.proto                        # proto 定义文件├── build.rs                         # prost_build 脚本,将 proto 编译成 rs ├── src/│   ├── lib.rs│   ├── error.rs│   └── pb/│       ├── abi.rs                   # 根据 abi.proto 生成的 rs│       └── mod.rs└── examples/    ├── client.rs    └── server.rs
复制代码


接下来,我们将一步步拆分,最终达到能够运行的目的。项目的源码我放在自己的 gitee 上,感兴趣的朋友可以克隆下来运行。


# 以下代码需要在两个 terminal 上执行cargo run --example server
cargo run --example client===============> 输出结果:2022-08-25T05:23:00.668291Z INFO server: Start listening on 127.0.0.1:95272022-08-25T05:23:18.802592Z INFO server: Client 127.0.0.1:53575 connected2022-08-25T05:23:18.803378Z INFO server: Got a new command: CommandRequest { request_data: Some(Hset(Hset { table: "table1", pair: Some(Kvpair { key: "hello", value: Some(Value { value: Some(String("world")) }) }) })) }2022-08-25T05:23:18.804176Z INFO server: Got response: CommandResponse { status: 200, message: "", values: [Value { value: None }], pairs: [] }
复制代码

02.1-初始化项目

可以通过cargo new kv --lib初始化一个项目。下文默认的当前目录是 package 根目录。编辑 Cargo.toml 添加如下 prost 和 prost-build 依赖。


02.2-编译 proto

在 package 根目录下,添加 abi.proto (proto 定义文件)和 build.rs (prost-build 编译脚本)


与 proto 编译相关的依赖包括:prostprost-build


prost is a Protocol Buffers implementation for the Rust Language.prost-build makes it easy to generate Rust code from .proto files as part of a Cargo build.


如果想了解更多使用 prost-build 的例子,可以参考 [1] Snazzy


运行cargo build会将 abi.proto 文件编译生成 src/pb/abi.rs 文件。

02.3-使用 module

通过 proto 定义并生成的数据结构作为当前 crate 的一个 module,需要在 src/pb 下放一个 mod.rs 引入该模块的其他文件。


// src/pb/mod.rspub mod abi;
// src/lib.rsmod pb;
pub use pb::abi::*;
复制代码


mod.rs 与 Python 中的 init.py 有异曲同工之妙。lib.rs 作为库的入口文件(对应的,main.rs 作为可执行项目的入口文件),在它之中可以通过mod pb;将 module 加载进来。


除了加载相关地文件外,mod.rs 中还为 abi.rs 中定义的 struct 实现了一些辅助 trait 和辅助方法。mod.rs 完整内容在 gitee.


因为 mod.rs 中用到了 KvError 类型,所以在 src 目录下添加一个 error.rs

02.4-运行示例

现在到了最后一个环节了,在 examples 下添加 server.rsclient.rs


server 的代码来自于课程中的示例,主要思路是:


  • 通过 tokio 中的 TcpListener 监听本机的 9527 端口,

  • 在无限循环中接受客户端的链接

  • 当客户端连接后,使用 tokio::spawn 创建新的线程来处理客户端链接


client 的代码来自于课程 github,主要思路是:


  • 通过 tokio 中的 TcpStream 链接到本地 9527 端口

  • 生成一个 HSET 命令,发送给服务端,等待响应


好了,到此为止,我们所有的要素都准备好了,可以尝试运行一下了。运行效果如下图所示:


本节课程链接:

21|阶段实操(1):构建一个简单的KV server-基本流程

22|阶段实操(2):构建一个简单的KV server-基本流程

发布于: 刚刚阅读数: 5
用户头像

Samson

关注

还未添加个人签名 2019.07.22 加入

还未添加个人简介

评论

发布
暂无评论
每日一R「15」实践课之 kv-server(一)_Samson_InfoQ写作社区