4个版本

0.2.3 2022年5月30日
0.2.2 2022年3月27日
0.2.1 2021年8月16日
0.2.0 2021年7月18日
0.1.12 2021年6月25日

#1689 in 网络编程

MIT许可证

55KB
1.5K SLoC

用于测试的RPC框架:labrpc

这是从Go到Rust的labrpc的逐行翻译。 labrpc帮助在受控环境中测试分布式系统。它可以模拟具有长延迟、随机丢包或随机顺序发送RPC响应的网络。可以动态添加和删除连接到网络的对等点,或单独启用和禁用。

此Rust版本利用了async-await功能,使得实现既安全、可靠又高效。

用法

labrpc允许创建一个传递RPC调用的网络。可以以唯一名称在网络中注册RPC服务器。客户端可以通过服务器名称连接到服务器。每个客户端都通过其名称进行识别,因此可以根据需要启用或禁用。

典型用例如下。

    // Start the network.
    let network = labrpc::Network::run_daemon();
    // Make it unreliable.
    network.lock().set_reliable(true);

    // Make an RPC server.
    let server = { ... };
    // Register the server in the network, call it "echo-server".
    network.lock().add_server(&"echo-server", server);
    
    // Make a connection to the above server.
    let client = network.lock().make_client(&"echo-client", &"echo-server");
    // Build and send a request.
    let request = { ... };
    // Await for the reply.
    let reply = client.call_rpc("EchoService.Echo", request).await?;

    // Echo server should echo.
    assert_eq!(request.get_message(), reply.get_message());

    // Disable the client we created above.
    network.lock().set_enable_client(&"echo-client", false);

    // Now we should get errors.
    let result = client.call_rpc("EchoServer.Echo").await;
    assert!(resut.is_err());

错误

网络在不同情况下返回不同类型的错误。请参阅client.rs以获取更多详细信息。

实现

幕后,所有客户端都通过共享请求队列发送请求。有一个专用线程从队列中获取请求并将请求委托给一组工作者。每个工作者查找客户端,检查ACL,找到正确的服务器,并调用服务器。工作者还决定请求是否应该被丢弃或延迟。

延迟

平均而言,每个RPC需要大约40ms才能通过网络。

在只有一个客户端发送数百万个请求的情况下,此实现的速度仅为Go版本的一半。大约2/3的延迟是由于网络线程池和服务器线程池中的上下文切换造成的。

依赖关系

~4–11MB
~109K SLoC