use cline and prepare to test the project for further development
Some checks failed
build container / build-container (push) Has been cancelled
Some checks failed
build container / build-container (push) Has been cancelled
This commit is contained in:
46
memory-bank/systemPatterns.md
Normal file
46
memory-bank/systemPatterns.md
Normal file
@ -0,0 +1,46 @@
|
||||
# 系统架构与设计模式
|
||||
|
||||
`cache-proxy` 的系统设计遵循了几个关键的模式和原则,以实现其高性能和高可用性的目标。
|
||||
|
||||
## 核心架构
|
||||
|
||||
系统可以分为三个主要部分:
|
||||
|
||||
1. **HTTP 服务器层**: 负责接收客户端请求,并使用中间件进行日志记录、错误恢复等通用处理。
|
||||
2. **缓存处理层**: 检查请求的文件是否存在于本地缓存中,并根据缓存策略决定是直接提供缓存文件还是向上游请求。
|
||||
3. **上游选择与下载层**: 这是系统的核心,负责并发地从多个上游服务器获取数据,并管理下载过程。
|
||||
|
||||
## 关键设计模式
|
||||
|
||||
### 1. 竞争式请求 (Racing Requests)
|
||||
|
||||
这是实现“选择最快”功能的核心模式。
|
||||
|
||||
- `fastesUpstream` 函数为每个上游服务器创建一个 goroutine。
|
||||
- 所有 goroutine 并发地向上游服务器发送请求。
|
||||
- 使用 `sync.Once` 来确保只有一个 goroutine 能够“胜出”并成为最终的数据源。
|
||||
- 一旦有 goroutine 胜出,它会调用 `context.CancelFunc` 来通知所有其他 goroutine 停止工作,从而避免不必要的资源消耗。
|
||||
|
||||
### 2. 生产者-消费者模式 (Producer-Consumer)
|
||||
|
||||
在文件下载过程中,使用了生产者-消费者模式。
|
||||
|
||||
- **生产者**: `tryUpstream` 函数中的 goroutine 负责从上游服务器读取数据块(chunk),并将其放入一个 `chan Chunk` 中。
|
||||
- **消费者**: `streamOnline` 函数中的代码从 `chan Chunk` 中读取数据,并执行两个操作:
|
||||
1. 将数据写入 `bytes.Buffer`,供后续的请求者使用。
|
||||
2. 将数据写入本地临时文件,用于持久化缓存。
|
||||
|
||||
### 3. 并发访问控制 (Mutex for Concurrent Access)
|
||||
|
||||
为了处理多个客户端同时请求同一个文件的情况,系统使用了 `sync.Mutex` 和一个 `map[string]*StreamObject`。
|
||||
|
||||
- 当第一个请求到达时,它会获得一个锁,并创建一个 `StreamObject` 来代表这个正在进行的下载任务。
|
||||
- 后续对同一文件的请求会发现 `StreamObject` 已存在,它们不会再次向上游发起请求,而是会等待并从这个共享的 `StreamObject` 中读取数据。
|
||||
- 下载完成后,`StreamObject` 会从 map 中移除。
|
||||
|
||||
### 4. 中间件 (Middleware)
|
||||
|
||||
项目使用了 Go 的标准 `http.Handler` 接口和中间件模式来构建请求处理链。
|
||||
|
||||
- `pkgs/middleware` 目录中定义了可重用的中间件,如 `httplog` 和 `recover`。
|
||||
- 这种模式使得在不修改核心业务逻辑的情况下,可以轻松地添加或删除日志、认证、错误处理等功能。
|
Reference in New Issue
Block a user