2.4 KiB
2.4 KiB
Project-2 Balancebeam 实现记录
综述
这东西本质上是一个类似于反向代理之类的东西,
每个 Milestone 的说明
Milestone 0
依然是传统的看代码环节。
首先是 main.rs 里面的东西。
CmdOption用的是clap这个 crate,用非常奇葩的 macro 语法来定义命令行参数并解析。ProxyState是执行线程的共享参数,不知道有啥特别的意义,可能是为后面的东西预留的TCPListener是标准库提供的东西,提供了一个简单的 TCP server。它通过incoming迭代器来返回构造的 TCP stream 抽象,这种字节流抽象最终会被分发给执行线程。- 执行线程:
- 首先,它随机选择一个上游服务器并打开与该服务器的连接。如果服务器无了,返回502。
- 然后循环从客户端读取请求,客户端可以在一个连接上发送任何数量的请求,而
balancebeam会将每个请求转发到上游服务器。如果客户端发送了一个错误的请求,会有一些错误处理。 - 一旦请求被读取,
balancebeam就会添加一个X-Forwarded-For HTTP头,以便上游服务器能够知道客户端的IP地址。(这对理解并不特别重要;它只是一个事实上的标准头。) - 接下来,
balancebeam将请求转发给上游服务器。如果在传输请求时有错误,它就会通知客户端。 - 接下来,
balancebeam试图从上游服务器读取响应。如果响应被破坏或在接收时有其他问题,它将通知客户端。 - 最后,
balancebeam将响应转发给客户。
然后是封装库 request.rs response.rs,就像 project 1 里面的 gimili wrapper 一样,又臭又长。分别用来基于 TCP 字节流来处理 HTTP 请求和响应。分别提供了 read_from_stream 和 write_to_stream 这两个接口供 main 处理两个 TCP 链接( Client HTTP req -> Proxy HTTP req -> Server, Server HTTP resp -> Proxy HTTP resp -> Client)。具体的里面的接口我也没细看,等到 Milestone 2 需要修改的时候再说吧。
Milestone 1
讲义上没有提出明确的实现目标,简单的把代码改成多线程而已。主要就是把 state 用 Arc 给共享掉(反正是不可变借用,十分的安全)。
ThreadPool 和 std::thread 没啥太大区别,都封装的很好了,直接看一下 doc.rs 里面的例子就行了。