fix: 移除隧道连接时检测是否正在使用

This commit is contained in:
meilin.huang
2025-05-26 22:33:51 +08:00
parent d6280ea280
commit e0c01d4561
19 changed files with 314 additions and 161 deletions

View File

@@ -9,6 +9,7 @@ import (
_ "mayfly-go/internal/db/dbm/oracle"
_ "mayfly-go/internal/db/dbm/postgres"
_ "mayfly-go/internal/db/dbm/sqlite"
"mayfly-go/internal/machine/mcm"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/pool"
)
@@ -17,6 +18,25 @@ var (
poolGroup = pool.NewPoolGroup[*dbi.DbConn]()
)
func init() {
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
items := poolGroup.AllPool()
for _, v := range items {
if v.Stats().TotalConns == 0 {
continue // 连接池中没有连接,跳过
}
conn, err := v.Get(context.Background())
if err != nil {
continue // 获取连接失败,跳过
}
if conn.Info.SshTunnelMachineId == machineId {
return true
}
}
return false
})
}
// GetDbConn 从连接池中获取连接信息
func GetDbConn(ctx context.Context, dbId uint64, database string, getDbInfo func() (*dbi.DbInfo, error)) (*dbi.DbConn, error) {
connId := dbi.GetDbConnId(dbId, database)

View File

@@ -8,6 +8,7 @@ import (
"mayfly-go/internal/es/domain/repository"
"mayfly-go/internal/es/esm/esi"
"mayfly-go/internal/es/imsg"
"mayfly-go/internal/machine/mcm"
"mayfly-go/internal/pkg/consts"
tagapp "mayfly-go/internal/tag/application"
tagdto "mayfly-go/internal/tag/application/dto"
@@ -40,6 +41,25 @@ var _ Instance = &instanceAppImpl{}
var poolGroup = pool.NewPoolGroup[*esi.EsConn]()
func init() {
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
items := poolGroup.AllPool()
for _, v := range items {
if v.Stats().TotalConns == 0 {
continue // 连接池中没有连接,跳过
}
conn, err := v.Get(context.Background())
if err != nil {
continue // 获取连接失败,跳过
}
if conn.Info.SshTunnelMachineId == machineId {
return true
}
}
return false
})
}
type instanceAppImpl struct {
base.AppImpl[*entity.EsInstance, repository.EsInstance]
@@ -234,6 +254,8 @@ func (app *instanceAppImpl) Delete(ctx context.Context, instanceId uint64) error
return errorx.NewBiz("db instnace not found")
}
poolGroup.Close(fmt.Sprintf("es-%d", instanceId))
return app.Tx(ctx, func(ctx context.Context) error {
// 删除该实例
return app.DeleteById(ctx, instanceId)

View File

@@ -9,6 +9,27 @@ var (
poolGroup = pool.NewPoolGroup[*Cli]()
)
func init() {
AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
// 遍历所有redis连接实例若存在redis实例使用该ssh隧道机器则返回true表示还在使用中...
items := poolGroup.AllPool()
for _, v := range items {
if v.Stats().TotalConns == 0 {
continue // 连接池中没有连接,跳过
}
cli, err := v.Get(context.Background())
if err != nil {
continue // 获取连接失败,跳过
}
sshTunnelMachine := cli.Info.SshTunnelMachine
if sshTunnelMachine != nil && sshTunnelMachine.Id == uint64(machineId) {
return true
}
}
return false
})
}
// 从缓存中获取客户端信息,不存在则回调获取机器信息函数,并新建。
// @param 机器的授权凭证名
func GetMachineCli(ctx context.Context, authCertName string, getMachine func(string) (*MachineInfo, error)) (*Cli, error) {
@@ -39,7 +60,7 @@ func DeleteCli(id uint64) {
continue
}
if conn.Info.Id == id {
pool.Close()
poolGroup.Close(conn.Info.AuthCertName)
}
}
}

View File

@@ -10,10 +10,15 @@ import (
"mayfly-go/pkg/utils/netx"
"net"
"sync"
"time"
"golang.org/x/crypto/ssh"
)
// type SshTunnelAble interface {
// GetSshTunnelMachineId() int
// }
var (
// 所有检测ssh隧道机器是否被使用的函数
checkSshTunnelMachineHasUseFuncs []CheckSshTunnelMachineHasUseFunc
@@ -132,7 +137,20 @@ func GetSshTunnelMachine(ctx context.Context, machineId int, getMachine func(uin
logx.Infof("connect to the ssh tunnel machine for the first time[%d][%s:%d]", machineId, mi.Ip, mi.Port)
return stm, err
})
}, pool.WithIdleTimeout[*SshTunnelMachine](50*time.Minute), pool.WithOnConnClose(func(conn *SshTunnelMachine) error {
mid := int(conn.mi.Id)
logx.Debugf("periodically check if the ssh tunnel machine [%d] is still in use...", mid)
for _, checkUseFunc := range checkSshTunnelMachineHasUseFuncs {
// 如果一个在使用则返回不关闭,不继续后续检查
if checkUseFunc(mid) {
return fmt.Errorf("ssh tunnel machine [%s] is still in use", conn.mi.Name)
}
}
return nil
}))
if err != nil {
return nil, err
}
@@ -142,18 +160,19 @@ func GetSshTunnelMachine(ctx context.Context, machineId int, getMachine func(uin
// 关闭ssh隧道机器的指定隧道
func CloseSshTunnelMachine(machineId uint64, tunnelId string) {
//sshTunnelMachine := mcIdPool[machineId]
//if sshTunnelMachine == nil {
// return
//}
//
//sshTunnelMachine.mutex.Lock()
//defer sshTunnelMachine.mutex.Unlock()
//t := sshTunnelMachine.tunnels[tunnelId]
//if t != nil {
// t.Close()
// delete(sshTunnelMachine.tunnels, tunnelId)
//}
sshTunnelMachinePool, ok := tunnelPoolGroup.Get(fmt.Sprintf("machine-tunnel-%d", machineId))
if !ok {
return
}
sshTunnelMachine, err := sshTunnelMachinePool.Get(context.Background())
if err != nil {
return
}
t := sshTunnelMachine.tunnels[tunnelId]
if t != nil {
t.Close()
delete(sshTunnelMachine.tunnels, tunnelId)
}
}
type Tunnel struct {

View File

@@ -2,6 +2,7 @@ package mgm
import (
"context"
"mayfly-go/internal/machine/mcm"
"mayfly-go/pkg/pool"
)
@@ -9,6 +10,25 @@ var (
poolGroup = pool.NewPoolGroup[*MongoConn]()
)
func init() {
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
items := poolGroup.AllPool()
for _, v := range items {
if v.Stats().TotalConns == 0 {
continue // 连接池中没有连接,跳过
}
conn, err := v.Get(context.Background())
if err != nil {
continue // 获取连接失败,跳过
}
if conn.Info.SshTunnelMachineId == machineId {
return true
}
}
return false
})
}
// 从缓存中获取mongo连接信息, 若缓存中不存在则会使用回调函数获取mongoInfo进行连接并缓存
func GetMongoConn(ctx context.Context, mongoId uint64, getMongoInfo func() (*MongoInfo, error)) (*MongoConn, error) {
pool, err := poolGroup.GetCachePool(getConnId(mongoId), func() (*MongoConn, error) {

View File

@@ -2,16 +2,34 @@ package rdm
import (
"context"
"mayfly-go/internal/machine/mcm"
"mayfly-go/pkg/pool"
)
func init() {
}
var (
poolGroup = pool.NewPoolGroup[*RedisConn]()
)
func init() {
mcm.AddCheckSshTunnelMachineUseFunc(func(machineId int) bool {
// 遍历所有redis连接实例若存在redis实例使用该ssh隧道机器则返回true表示还在使用中...
items := poolGroup.AllPool()
for _, v := range items {
if v.Stats().TotalConns == 0 {
continue // 连接池中没有连接,跳过
}
rc, err := v.Get(context.Background())
if err != nil {
continue // 获取连接失败,跳过
}
if rc.Info.SshTunnelMachineId == machineId {
return true
}
}
return false
})
}
// 从缓存中获取redis连接信息, 若缓存中不存在则会使用回调函数获取redisInfo进行连接并缓存
func GetRedisConn(ctx context.Context, redisId uint64, db int, getRedisInfo func() (*RedisInfo, error)) (*RedisConn, error) {
p, err := poolGroup.GetCachePool(getConnId(redisId, db), func() (*RedisConn, error) {