fix service api (#556)

* fix service api

* update ServiceResponseItem

* fix: ddns lock
This commit is contained in:
UUBulb
2024-12-05 21:00:02 +08:00
committed by GitHub
parent 2234cff5eb
commit 040c8df02e
10 changed files with 124 additions and 53 deletions

View File

@@ -19,6 +19,7 @@ var (
DDNSCache map[uint64]*model.DDNSProfile
DDNSCacheLock sync.RWMutex
DDNSList []*model.DDNSProfile
DDNSListLock sync.RWMutex
)
func initDDNS() {
@@ -52,6 +53,9 @@ func UpdateDDNSList() {
DDNSCacheLock.RLock()
defer DDNSCacheLock.RUnlock()
DDNSListLock.Lock()
defer DDNSListLock.Unlock()
DDNSList = make([]*model.DDNSProfile, 0, len(DDNSCache))
for _, p := range DDNSCache {
DDNSList = append(DDNSList, p)

View File

@@ -14,6 +14,7 @@ var (
NATIDToDomain = make(map[uint64]string)
NATList []*model.NAT
NATListLock sync.RWMutex
)
func initNAT() {
@@ -55,6 +56,9 @@ func UpdateNATList() {
NATCacheRwLock.RLock()
defer NATCacheRwLock.RUnlock()
NATListLock.Lock()
defer NATListLock.Unlock()
NATList = make([]*model.NAT, 0, len(NATCache))
for _, n := range NATCache {
NATList = append(NATList, n)

View File

@@ -24,8 +24,9 @@ var (
NotificationListSorted []*model.Notification
NotificationGroup map[uint64]string // [NotificationGroupID] -> [NotificationGroupName]
NotificationsLock sync.RWMutex
NotificationGroupLock sync.RWMutex
NotificationsLock sync.RWMutex
NotificationSortedLock sync.RWMutex
NotificationGroupLock sync.RWMutex
)
// InitNotification 初始化 GroupID <-> ID <-> Notification 的映射
@@ -81,6 +82,9 @@ func UpdateNotificationList() {
NotificationsLock.RLock()
defer NotificationsLock.RUnlock()
NotificationSortedLock.Lock()
defer NotificationSortedLock.Unlock()
NotificationListSorted = make([]*model.Notification, 0, len(NotificationMap))
for _, n := range NotificationMap {
NotificationListSorted = append(NotificationListSorted, n)

View File

@@ -3,12 +3,14 @@ package singleton
import (
"fmt"
"log"
"sort"
"slices"
"strings"
"sync"
"time"
"github.com/jinzhu/copier"
"github.com/nezhahq/nezha/model"
"github.com/nezhahq/nezha/pkg/utils"
pb "github.com/nezhahq/nezha/proto"
)
@@ -18,6 +20,12 @@ const (
var ServiceSentinelShared *ServiceSentinel
type serviceResponseItem struct {
model.ServiceResponseItem
service *model.Service
}
type ReportData struct {
Data *pb.TaskResult
Reporter uint64
@@ -45,7 +53,7 @@ func NewServiceSentinel(serviceSentinelDispatchBus chan<- model.Service) {
Services: make(map[uint64]*model.Service),
tlsCertCache: make(map[uint64]string),
// 30天数据缓存
monthlyStatus: make(map[uint64]*model.ServiceResponseItem),
monthlyStatus: make(map[uint64]*serviceResponseItem),
dispatchBus: serviceSentinelDispatchBus,
}
// 加载历史记录
@@ -104,12 +112,14 @@ type ServiceSentinel struct {
lastStatus map[uint64]int
tlsCertCache map[uint64]string
ServicesLock sync.RWMutex
Services map[uint64]*model.Service
ServicesLock sync.RWMutex
ServiceListLock sync.RWMutex
Services map[uint64]*model.Service
ServiceList []*model.Service
// 30天数据缓存
monthlyStatusLock sync.Mutex
monthlyStatus map[uint64]*model.ServiceResponseItem
monthlyStatus map[uint64]*serviceResponseItem
}
type indexStore struct {
@@ -157,17 +167,21 @@ func (ss *ServiceSentinel) Dispatch(r ReportData) {
ss.serviceReportChannel <- r
}
func (ss *ServiceSentinel) GetServiceList() []*model.Service {
func (ss *ServiceSentinel) UpdateServiceList() {
ss.ServicesLock.RLock()
defer ss.ServicesLock.RUnlock()
var services []*model.Service
ss.ServiceListLock.Lock()
defer ss.ServiceListLock.Unlock()
ss.ServiceList = make([]*model.Service, 0, len(ss.Services))
for _, v := range ss.Services {
services = append(services, v)
ss.ServiceList = append(ss.ServiceList, v)
}
sort.SliceStable(services, func(i, j int) bool {
return services[i].ID < services[j].ID
slices.SortFunc(ss.ServiceList, func(a, b *model.Service) int {
return utils.Compare(a.ID, b.ID)
})
return services
}
// loadServiceHistory 加载服务监控器的历史状态信息
@@ -198,16 +212,19 @@ func (ss *ServiceSentinel) loadServiceHistory() {
ss.serviceCurrentStatusData[services[i].ID] = make([]*pb.TaskResult, _CurrentStatusSize)
ss.serviceStatusToday[services[i].ID] = &_TodayStatsOfService{}
}
ss.ServiceList = services
year, month, day := time.Now().Date()
today := time.Date(year, month, day, 0, 0, 0, 0, Loc)
for i := 0; i < len(services); i++ {
ServiceSentinelShared.monthlyStatus[services[i].ID] = &model.ServiceResponseItem{
Service: services[i],
Delay: &[30]float32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Up: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Down: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
ServiceSentinelShared.monthlyStatus[services[i].ID] = &serviceResponseItem{
service: services[i],
ServiceResponseItem: model.ServiceResponseItem{
Delay: &[30]float32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Up: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Down: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
}
@@ -250,11 +267,13 @@ func (ss *ServiceSentinel) OnServiceUpdate(m model.Service) error {
Cron.Remove(ss.Services[m.ID].CronJobID)
} else {
// 新任务初始化数据
ss.monthlyStatus[m.ID] = &model.ServiceResponseItem{
Service: &m,
Delay: &[30]float32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Up: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Down: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
ss.monthlyStatus[m.ID] = &serviceResponseItem{
service: &m,
ServiceResponseItem: model.ServiceResponseItem{
Delay: &[30]float32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Up: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Down: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
ss.serviceCurrentStatusData[m.ID] = make([]*pb.TaskResult, _CurrentStatusSize)
ss.serviceStatusToday[m.ID] = &_TodayStatsOfService{}
@@ -290,7 +309,9 @@ func (ss *ServiceSentinel) OnServiceDelete(ids []uint64) {
}
}
func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceResponseItem {
func (ss *ServiceSentinel) LoadStats() map[uint64]*serviceResponseItem {
ss.ServicesLock.RLock()
defer ss.ServicesLock.RUnlock()
ss.serviceResponseDataStoreLock.RLock()
defer ss.serviceResponseDataStoreLock.RUnlock()
ss.monthlyStatusLock.Lock()
@@ -298,7 +319,7 @@ func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceResponseItem {
// 刷新最新一天的数据
for k := range ss.Services {
ss.monthlyStatus[k].Service = ss.Services[k]
ss.monthlyStatus[k].service = ss.Services[k]
v := ss.serviceStatusToday[k]
// 30 天在线率,
@@ -325,6 +346,24 @@ func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceResponseItem {
return ss.monthlyStatus
}
func (ss *ServiceSentinel) CopyStats() map[uint64]model.ServiceResponseItem {
var stats map[uint64]*serviceResponseItem
copier.Copy(&stats, ss.LoadStats())
sri := make(map[uint64]model.ServiceResponseItem)
for k, service := range stats {
if !service.service.EnableShowInService {
delete(stats, k)
continue
}
service.ServiceName = service.service.Name
sri[k] = service.ServiceResponseItem
}
return sri
}
// worker 服务监控的实际工作流程
func (ss *ServiceSentinel) worker() {
// 从服务状态汇报管道获取汇报的服务数据