修复请求错误消息上报问题

This commit is contained in:
2026-05-13 18:07:44 +08:00
parent ccbc6f0b67
commit 80f04c92ec
2 changed files with 16 additions and 65 deletions

View File

@@ -1,60 +1,13 @@
## TODO ## TODO
### 接口并发问题 提取代理:
- 网关修改问题
#### 找可用网关 & 找可用端点 - 在提取流程中如果网关被修改,有可能导致数据不一致
*(注:找端点依赖于网关状态,二者先后执行,但在并发控制上统一处理)* - 提供读写锁,在提取流程中获取读锁,在修改网关时获取写锁
- 端口悬空问题
**下线并发问题** - 在提取流程中如果发生异常,可能导致端口被占用但通道信息没有被写入数据库,配置以及端口将无法解除
* 提供指定网关的可重入读写锁A。 - 提交删除任务时,带上配置信息,无需再查数据库且接口总是会被正确清理
* 整个提取期间锁定A直到提取结束。 - 异常情况下,将只清理网关端口,而无法解除节点连接,这个问题需要额外处理
* 网关可以并发下线但是不允许在锁A清空前进行删除或修改。
#### 找可用节点
##### 找本地
**并发筛选问题**
多个提取请求筛选到同一个节点,只有一个请求可以占用该节点,其他请求会直接失败。
**处理方案:**
* 提供占用锁,持续到提交配置后。
* 筛选出节点后,锁定该节点,如果锁定失败说明该节点已被占用(包括云端节点)。
* 如果被占用则等待占用结束后重新筛选(如果在结束前就重新筛选,可能还是会筛选到同样的节点,再次导致失败)。
* 提取时可能要求多个节点,因此锁定节点时,需要一个 lua 脚本同步锁定同一批节点。
##### 找云端
**重复筛选问题**
云端接口不会自动过滤已连接的节点,有可能筛选到已经连接甚至配置的节点。
**处理(缓解)方案:**
* 优先筛选今日未分配的节点,如果没有可用节点,再分配已用节点,这个方案暂时缓解问题。
#### 整理配置信息
* 该环节**不会有并发问题**。
#### 开通通道
*(注:包含以下三个独立操作,主要关注其执行的原子性与最终一致性保证)*
##### 提交异步关闭任务
**后续失败问题:**
* 不考虑回滚,执行时需要考虑后续数据不全的情况。
* 提交需要 `proxy``batch` 参数,端口取用是独占的,因此在归还端口前,一定不会有其他连接使用端口。任务信息中需要包含足够的信息以在没有数据库信息时解除配置。
* 解除连接与归还端口全部成功才算成功。
##### 提交配置到云端
* 该环节**不会有并发问题**。
##### 保存到数据库
**一致性处理:**
* 保存失败后,只会存在孤立占用。异步任务会自动重试,能够实现最终一致性。
---
- 并发扣减问题
- 代理选择通过查 redis 实现
- 重新考虑取用流程设计,是否可以分离端口归还与通道断开。端口归还后通道即使没有断开,未来也会被其他请求占用,能够实现最终一致性
--- ---

View File

@@ -22,6 +22,9 @@ func ApplyMiddlewares(app *fiber.App) {
EnableStackTrace: true, EnableStackTrace: true,
})) }))
// metric
app.Use(otelfiber.Middleware())
// logger // logger
app.Use(logger.New(logger.Config{ app.Use(logger.New(logger.Config{
Next: func(c *fiber.Ctx) bool { Next: func(c *fiber.Ctx) bool {
@@ -29,8 +32,7 @@ func ApplyMiddlewares(app *fiber.App) {
}, },
})) }))
// metric // 补充 otel span attr
app.Use(otelfiber.Middleware())
app.Use(func(c *fiber.Ctx) error { app.Use(func(c *fiber.Ctx) error {
err := c.Next() err := c.Next()
@@ -39,16 +41,12 @@ func ApplyMiddlewares(app *fiber.App) {
return err return err
} }
status := c.Response().StatusCode() str := ""
body := []byte{} if err != nil {
if status < 200 || status >= 300 { str = err.Error()
body = c.Response().Body()
if len(body) > 1024 {
body = body[:1024]
}
} }
span.SetAttributes(attribute.String("http.response.error", string(body))) span.SetAttributes(attribute.String("http.response.error", str))
return err return err
}) })