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