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