Skip to content

Conversation

@W0n9
Copy link
Contributor

@W0n9 W0n9 commented Dec 13, 2024

Found some issues in the staging environment:

  1. Under high load, occasional deadlocks occur, causing the program to fail to respond normally, and user requests are backlogged in the buffer.
    微信截图_20241210000852
    Solution:
  2. Introduce a new dynamically expandable connection pool, replacing the existing pre-filled connection pool, attempting to solving the deadlock problem existing in the old connection pool.
  3. Introduce the testing of req.Body() to avoid req.Body() being cleared.
  4. Upgrade the version of xerrors.

在预发环境中发现一些问题:

  1. 高负载下偶发死锁,导致程序无法正常响应,用户请求积压在缓冲区
    微信截图_20241210000852

解决方案:

  1. 引入新的动态扩展的连接池,代替现有的预填充的连接池,同时解决了现有连接池存在的死锁问题
  2. 增加对req.Body()的测试,避免req.Body()被清空
  3. 升级xerrors版本(更改为去除xerrors依赖)

@magickong
Copy link

@MonkeyCode-AI review

Copy link

@MonkeyCode-AI MonkeyCode-AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request 概述

这个 PR 主要引入了一个新的连接池实现,用于管理 t1k-go 库中的 TCP 连接。主要变更包括:

  1. 添加了 ChannelPool 实现,具有连接管理功能,如空闲超时、最大连接数和连接复用。
  2. 引入了 ConnectionFactory 接口及 TcpFactory 实现,用于创建和管理 TCP 连接。
  3. 更新了错误处理,使用自定义的错误包装实现替换 golang.org/x/xerrors。
  4. 添加了 Dependabot 配置以实现自动依赖更新。
  5. 更新了 GitHub Actions 工作流中的 Go 版本,从 1.17/1.20 升级到 1.23/1.24。
  6. 修改了 detect.go 中的检测逻辑,以正确处理请求体读取。
  7. 添加了使用连接池的新示例文件。
  8. 为新连接池功能添加了测试。

Pull Request 变更详情

文件路径 变更类型 变更内容
.github/dependabot.yml 添加 添加了 Dependabot 配置
.github/workflows/go.yml 修改 更新了 Go 版本
channel.go 添加 实现了 ChannelPool
channel_test.go 添加 添加了 ChannelPool 的测试
detect.go 修改 修改了检测逻辑
detect_test.go 修改 更新了检测逻辑的测试
examples/new_connection_pool.go 添加 添加了连接池使用示例
factory.go 添加 实现了 ConnectionFactory 接口
go.mod 修改 更新了依赖项
go.sum 修改 更新了依赖项校验和
misc/errors.go 添加 添加了自定义错误处理
pool.go 添加 实现了连接池接口
vendor/* 添加/修改 添加或更新了 vendored 依赖

// ConnectionFactory 连接工厂
type ConnectionFactory interface {
//生成连接的方法
Factory() (interface{}, error)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

factory.go 中,ConnectionFactory 接口的 Factory() 方法缺少注释说明。建议为该方法添加注释,说明其功能和返回值。

Suggested change
Factory() (interface{}, error)
// Factory 生成连接的方法
Factory() (interface{}, error)


// PoolConfig 连接池相关配置
type PoolConfig struct {
//连接池初始连接数

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pool.go 中,PoolConfig 结构体的字段缺少注释。建议为每个字段添加注释,说明其用途。

Suggested change
//连接池初始连接数
type PoolConfig struct {
// InitialCap 连接池初始连接数
InitialCap int
// MaxCap 最大并发存活连接数
MaxCap int
// MaxIdle 最大空闲连接
MaxIdle int
// Factory 连接工厂
Factory ConnectionFactory
// IdleTimeout 连接最大空闲时间,超过该时间则将失效
IdleTimeout time.Duration
}

)

// wrapError 结构体用于包装错误信息
type wrapError struct {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

misc/errors.go 中,wrapError 结构体的字段已经有注释,但建议统一注释格式。例如,使用 // message 错误消息 而不是 // 错误消息

Suggested change
type wrapError struct {
type wrapError struct {
// message 错误消息
message string
// next 原始错误
next error
// pc 程序计数器,用于存储调用栈信息
pc uintptr
// file 源文件名
file string
// line 行号
line int
// pkgPath 包路径
pkgPath string
// funcName 函数名
funcName string
}

run: go test -v ./...

- name: Build new_connection_pool.go
run: mv ./examples/new_connection_pool.go ./examples/main.go && go build -v ./examples/main.go

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.github/workflows/go.yml 中,新增的构建和测试步骤会覆盖原始的 main.go 文件。这可能会导致原始示例文件丢失。建议使用不同的文件名或在构建后恢复原始文件。

Suggested change
run: mv ./examples/new_connection_pool.go ./examples/main.go && go build -v ./examples/main.go
# 可以考虑创建一个临时目录进行构建,避免覆盖原始文件
- name: Build new_connection_pool.go
run: mkdir -p temp && cp ./examples/new_connection_pool.go ./temp/main.go && go build -v ./temp/main.go
# 或者在构建后恢复原始文件
- name: Build new_connection_pool.go
run: cp ./examples/main.go ./examples/main.go.bak && mv ./examples/new_connection_pool.go ./examples/main.go && go build -v ./examples/main.go && mv ./examples/main.go.bak ./examples/main.go

"github.com/chaitin/t1k-go"
)

func initDetect(addr string) *t1k.ChannelPool {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

examples/new_connection_pool.go 中,initDetect 函数在初始化连接池失败时返回 nil。建议返回具体的错误信息,以便更好地调试。

Suggested change
func initDetect(addr string) *t1k.ChannelPool {
func initDetect(addr string) (*t1k.ChannelPool, error) {
pc := &t1k.PoolConfig{
InitialCap: 1,
MaxIdle: 16,
MaxCap: 32,
Factory: &t1k.TcpFactory{Addr: addr},
IdleTimeout: 30 * time.Second,
}
server, err := t1k.NewChannelPool(pc)
if err != nil {
return nil, err
}
return server, nil
}

@MonkeyCode-AI
Copy link

⏳ MonkeyCode-AI 正在分析,请稍等片刻...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants