mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-12-29 17:26:35 +08:00
实现基础的智能调度
This commit is contained in:
@@ -12,7 +12,8 @@ import (
|
||||
type DNSTaskType = string
|
||||
|
||||
const (
|
||||
DNSTaskTypeClusterChange DNSTaskType = "clusterChange"
|
||||
DNSTaskTypeClusterChange DNSTaskType = "clusterChange" // 集群节点、服务发生变化
|
||||
DNSTaskTypeClusterNodesChange DNSTaskType = "clusterNodesChange" // 集群中节点发生变化
|
||||
DNSTaskTypeClusterRemoveDomain DNSTaskType = "clusterRemoveDomain" // 从集群中移除域名
|
||||
DNSTaskTypeNodeChange DNSTaskType = "nodeChange"
|
||||
DNSTaskTypeServerChange DNSTaskType = "serverChange"
|
||||
|
||||
@@ -52,7 +52,9 @@ const (
|
||||
|
||||
MessageTypeReportNodeInactive MessageType = "ReportNodeInactive" // 区域监控节点节点不活跃
|
||||
MessageTypeReportNodeActive MessageType = "ReportNodeActive" // 区域监控节点活跃
|
||||
MessageTypeConnectivity MessageType = "Connectivity"
|
||||
MessageTypeConnectivity MessageType = "Connectivity" // 连通性
|
||||
MessageTypeNodeSchedule MessageType = "NodeSchedule" // 节点调度信息
|
||||
MessageTypeNodeOfflineDay MessageType = "NodeOfflineDay" // 节点到下线日期
|
||||
)
|
||||
|
||||
type MessageDAO dbs.DAO
|
||||
|
||||
63
internal/db/models/node_action_dao.go
Normal file
63
internal/db/models/node_action_dao.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
NodeActionStateEnabled = 1 // 已启用
|
||||
NodeActionStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type NodeActionDAO dbs.DAO
|
||||
|
||||
func NewNodeActionDAO() *NodeActionDAO {
|
||||
return dbs.NewDAO(&NodeActionDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeNodeActions",
|
||||
Model: new(NodeAction),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*NodeActionDAO)
|
||||
}
|
||||
|
||||
var SharedNodeActionDAO *NodeActionDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedNodeActionDAO = NewNodeActionDAO()
|
||||
})
|
||||
}
|
||||
|
||||
// EnableNodeAction 启用条目
|
||||
func (this *NodeActionDAO) EnableNodeAction(tx *dbs.Tx, id uint64) error {
|
||||
_, err := this.Query(tx).
|
||||
Pk(id).
|
||||
Set("state", NodeActionStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// DisableNodeAction 禁用条目
|
||||
func (this *NodeActionDAO) DisableNodeAction(tx *dbs.Tx, id int64) error {
|
||||
_, err := this.Query(tx).
|
||||
Pk(id).
|
||||
Set("state", NodeActionStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// FindEnabledNodeAction 查找启用中的条目
|
||||
func (this *NodeActionDAO) FindEnabledNodeAction(tx *dbs.Tx, id int64) (*NodeAction, error) {
|
||||
result, err := this.Query(tx).
|
||||
Pk(id).
|
||||
State(NodeActionStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*NodeAction), err
|
||||
}
|
||||
6
internal/db/models/node_action_dao_test.go
Normal file
6
internal/db/models/node_action_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
32
internal/db/models/node_action_model.go
Normal file
32
internal/db/models/node_action_model.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
// NodeAction 节点智能调度设置
|
||||
type NodeAction struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
NodeId uint64 `field:"nodeId"` // 节点ID
|
||||
Role string `field:"role"` // 角色
|
||||
IsOn bool `field:"isOn"` // 是否启用
|
||||
Conds dbs.JSON `field:"conds"` // 条件
|
||||
Action dbs.JSON `field:"action"` // 动作
|
||||
Duration dbs.JSON `field:"duration"` // 持续时间
|
||||
Order uint32 `field:"order"` // 排序
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type NodeActionOperator struct {
|
||||
Id any // ID
|
||||
NodeId any // 节点ID
|
||||
Role any // 角色
|
||||
IsOn any // 是否启用
|
||||
Conds any // 条件
|
||||
Action any // 动作
|
||||
Duration any // 持续时间
|
||||
Order any // 排序
|
||||
State any // 状态
|
||||
}
|
||||
|
||||
func NewNodeActionOperator() *NodeActionOperator {
|
||||
return &NodeActionOperator{}
|
||||
}
|
||||
1
internal/db/models/node_action_model_ext.go
Normal file
1
internal/db/models/node_action_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -1550,7 +1550,7 @@ func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId i
|
||||
Attr("isOn", true).
|
||||
Attr("isUp", true).
|
||||
Attr("isInstalled", isInstalled).
|
||||
Result("id", "name", "dnsRoutes", "isOn").
|
||||
Result("id", "name", "dnsRoutes", "isOn", "offlineDay", "actionStatus", "isBackupForCluster", "isBackupForGroup", "backupIPs", "clusterId", "groupId").
|
||||
DescPk().
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
@@ -1575,7 +1575,7 @@ func (this *NodeDAO) FindEnabledNodeDNS(tx *dbs.Tx, nodeId int64) (*Node, error)
|
||||
one, err := this.Query(tx).
|
||||
State(NodeStateEnabled).
|
||||
Pk(nodeId).
|
||||
Result("id", "name", "dnsRoutes", "clusterId", "isOn").
|
||||
Result("id", "name", "dnsRoutes", "clusterId", "isOn", "offlineDay", "isBackupForCluster", "isBackupForGroup", "actionStatus").
|
||||
Find()
|
||||
if one == nil {
|
||||
return nil, err
|
||||
|
||||
@@ -18,3 +18,8 @@ func (this *NodeDAO) loadServersFromCluster(tx *dbs.Tx, clusterId int64, serverI
|
||||
func (this *NodeDAO) composeExtConfig(tx *dbs.Tx, config *nodeconfigs.NodeConfig, clusterIds []int64, cacheMap *utils.CacheMap) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckNodeIPAddresses 检查节点IP地址
|
||||
func (this *NodeDAO) CheckNodeIPAddresses(tx *dbs.Tx, node *Node) (shouldSkip bool, shouldOverwrite bool, ipAddressStrings []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -43,6 +43,12 @@ type Node struct {
|
||||
DnsResolver dbs.JSON `field:"dnsResolver"` // DNS解析器
|
||||
EnableIPLists bool `field:"enableIPLists"` // 启用IP名单
|
||||
ApiNodeAddrs dbs.JSON `field:"apiNodeAddrs"` // API节点地址
|
||||
OfflineDay string `field:"offlineDay"` // 下线日期YYYYMMDD
|
||||
OfflineIsNotified bool `field:"offlineIsNotified"` // 下线是否已通知
|
||||
IsBackupForCluster bool `field:"isBackupForCluster"` // 是否为集群备用节点
|
||||
IsBackupForGroup bool `field:"isBackupForGroup"` // 是否为分组备用节点
|
||||
BackupIPs dbs.JSON `field:"backupIPs"` // 备用IP
|
||||
ActionStatus dbs.JSON `field:"actionStatus"` // 当前动作配置
|
||||
}
|
||||
|
||||
type NodeOperator struct {
|
||||
@@ -85,6 +91,12 @@ type NodeOperator struct {
|
||||
DnsResolver any // DNS解析器
|
||||
EnableIPLists any // 启用IP名单
|
||||
ApiNodeAddrs any // API节点地址
|
||||
OfflineDay any // 下线日期YYYYMMDD
|
||||
OfflineIsNotified any // 下线是否已通知
|
||||
IsBackupForCluster any // 是否为集群备用节点
|
||||
IsBackupForGroup any // 是否为分组备用节点
|
||||
BackupIPs any // 备用IP
|
||||
ActionStatus any // 当前动作配置
|
||||
}
|
||||
|
||||
func NewNodeOperator() *NodeOperator {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
@@ -16,7 +17,7 @@ func (this *Node) DecodeInstallStatus() (*NodeInstallStatus, error) {
|
||||
if len(this.InstallStatus) == 0 {
|
||||
return NewNodeInstallStatus(), nil
|
||||
}
|
||||
status := &NodeInstallStatus{}
|
||||
var status = &NodeInstallStatus{}
|
||||
err := json.Unmarshal(this.InstallStatus, status)
|
||||
if err != nil {
|
||||
return NewNodeInstallStatus(), err
|
||||
@@ -37,7 +38,7 @@ func (this *Node) DecodeStatus() (*nodeconfigs.NodeStatus, error) {
|
||||
if len(this.Status) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
status := &nodeconfigs.NodeStatus{}
|
||||
var status = &nodeconfigs.NodeStatus{}
|
||||
err := json.Unmarshal(this.Status, status)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -47,7 +48,7 @@ func (this *Node) DecodeStatus() (*nodeconfigs.NodeStatus, error) {
|
||||
|
||||
// DNSRouteCodes 所有的DNS线路
|
||||
func (this *Node) DNSRouteCodes() map[int64][]string {
|
||||
routes := map[int64][]string{} // domainId => routes
|
||||
var routes = map[int64][]string{} // domainId => routes
|
||||
if len(this.DnsRoutes) == 0 {
|
||||
return routes
|
||||
}
|
||||
@@ -61,7 +62,7 @@ func (this *Node) DNSRouteCodes() map[int64][]string {
|
||||
|
||||
// DNSRouteCodesForDomainId DNS线路
|
||||
func (this *Node) DNSRouteCodesForDomainId(dnsDomainId int64) ([]string, error) {
|
||||
routes := map[int64][]string{} // domainId => routes
|
||||
var routes = map[int64][]string{} // domainId => routes
|
||||
if len(this.DnsRoutes) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -80,7 +81,7 @@ func (this *Node) DNSRouteCodesForDomainId(dnsDomainId int64) ([]string, error)
|
||||
|
||||
// DecodeConnectedAPINodeIds 连接的API
|
||||
func (this *Node) DecodeConnectedAPINodeIds() ([]int64, error) {
|
||||
apiNodeIds := []int64{}
|
||||
var apiNodeIds = []int64{}
|
||||
if IsNotNull(this.ConnectedAPINodes) {
|
||||
err := json.Unmarshal(this.ConnectedAPINodes, &apiNodeIds)
|
||||
if err != nil {
|
||||
@@ -214,3 +215,8 @@ func (this *Node) DecodeAPINodeAddrs() []*serverconfigs.NetworkAddressConfig {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// CheckIsOffline 检查是否已经离线
|
||||
func (this *Node) CheckIsOffline() bool {
|
||||
return len(this.OfflineDay) > 0 && this.OfflineDay < timeutil.Format("Ymd")
|
||||
}
|
||||
|
||||
9
internal/db/models/node_model_ext_schdule.go
Normal file
9
internal/db/models/node_model_ext_schdule.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package models
|
||||
|
||||
// HasScheduleSettings 检查是否设置了调度
|
||||
func (this *Node) HasScheduleSettings() bool {
|
||||
return false
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package stats
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
@@ -84,7 +84,9 @@ func (this *NodeTrafficDailyStatDAO) IncreaseDailyStat(tx *dbs.Tx, clusterId int
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
// 触发钩子
|
||||
return this.increaseDailyStatHook(tx, role, nodeId)
|
||||
}
|
||||
|
||||
// FindDailyStats 获取日期之间统计
|
||||
14
internal/db/models/node_traffic_daily_stat_dao_ext.go
Normal file
14
internal/db/models/node_traffic_daily_stat_dao_ext.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
// 增加日统计Hook
|
||||
func (this *NodeTrafficDailyStatDAO) increaseDailyStatHook(tx *dbs.Tx, role nodeconfigs.NodeRole, nodeId int64) error {
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package stats
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
@@ -1,4 +1,4 @@
|
||||
package stats
|
||||
package models
|
||||
|
||||
// NodeTrafficDailyStat 总的流量统计(按天)
|
||||
type NodeTrafficDailyStat struct {
|
||||
1
internal/db/models/node_traffic_daily_stat_model_ext.go
Normal file
1
internal/db/models/node_traffic_daily_stat_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -37,11 +37,15 @@ func init() {
|
||||
|
||||
// CreateValue 创建值
|
||||
func (this *NodeValueDAO) CreateValue(tx *dbs.Tx, clusterId int64, role nodeconfigs.NodeRole, nodeId int64, item string, valueJSON []byte, createdAt int64) error {
|
||||
if len(valueJSON) == 0 {
|
||||
return errors.New("'valueJSON' should not be nil")
|
||||
}
|
||||
|
||||
var day = timeutil.FormatTime("Ymd", createdAt)
|
||||
var hour = timeutil.FormatTime("YmdH", createdAt)
|
||||
var minute = timeutil.FormatTime("YmdHi", createdAt)
|
||||
|
||||
return this.Query(tx).
|
||||
err := this.Query(tx).
|
||||
InsertOrUpdateQuickly(maps.Map{
|
||||
"clusterId": clusterId,
|
||||
"role": role,
|
||||
@@ -55,6 +59,17 @@ func (this *NodeValueDAO) CreateValue(tx *dbs.Tx, clusterId int64, role nodeconf
|
||||
}, maps.Map{
|
||||
"value": valueJSON,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 触发钩子
|
||||
err = this.nodeValueHook(tx, role, nodeId, item, valueJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clean 清除数据
|
||||
@@ -324,7 +339,7 @@ func (this *NodeValueDAO) SumNodeClusterValues(tx *dbs.Tx, role string, clusterI
|
||||
|
||||
// FindLatestNodeValue 获取最近一条数据
|
||||
func (this *NodeValueDAO) FindLatestNodeValue(tx *dbs.Tx, role string, nodeId int64, item string) (*NodeValue, error) {
|
||||
fromMinute := timeutil.FormatTime("YmdHi", time.Now().Unix()-int64(60))
|
||||
var fromMinute = timeutil.FormatTime("YmdHi", time.Now().Unix()-int64(60))
|
||||
|
||||
one, err := this.Query(tx).
|
||||
Attr("role", role).
|
||||
|
||||
14
internal/db/models/node_value_dao_ext.go
Normal file
14
internal/db/models/node_value_dao_ext.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
// 节点值变更Hook
|
||||
func (this *NodeValueDAO) nodeValueHook(tx *dbs.Tx, role nodeconfigs.NodeRole, nodeId int64, item nodeconfigs.NodeValueItem, valueJSON []byte) error {
|
||||
return nil
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package stats
|
||||
Reference in New Issue
Block a user