fix(scheduler): enable profiling (#23642)

* fix(scheduler): enable profiling

* feat(scheduler): cache NetworkAdditionalWire
This commit is contained in:
Zexi Li
2025-10-31 10:19:24 +08:00
committed by GitHub
parent b4fd2eb122
commit 357a0f22e3
8 changed files with 162 additions and 9 deletions
+2 -5
View File
@@ -34,6 +34,7 @@ import (
"yunion.io/x/onecloud/pkg/scheduler/data_manager/cloudregion"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/netinterface"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/network"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/network_additional_wire"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/sku"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/zone"
schedmodels "yunion.io/x/onecloud/pkg/scheduler/models"
@@ -634,11 +635,7 @@ func (b *BaseHostDesc) fillNetworks(host *computemodels.SHost, netGetter *networ
nets := make([]computemodels.SNetwork, 0)
allNets := network.Manager.GetStore().GetAll()
for _, net := range allNets {
netAdditionalWireIds, err := computemodels.NetworkAdditionalWireManager.FetchNetworkAdditionalWireIds(net.Id)
if err != nil {
log.Errorf("NetworkAdditionalWireManager.FetchNetworkAdditionalWireIds %s error %s", net.Id, err)
netAdditionalWireIds = []string{}
}
netAdditionalWireIds := network_additional_wire.FetchNetworkAdditionalWireIds(net.Id)
if wireIds.Has(net.WireId) || wireIds.HasAny(netAdditionalWireIds...) {
nets = append(nets, net)
}
+7 -1
View File
@@ -224,7 +224,13 @@ func (s *ResourceStore[O]) GetByPrefix(prefixId string) []O {
}
func (s *ResourceStore[O]) GetAll() []O {
ret := make([]O, 0)
// To avoid repeated slice growth during append, count first and preallocate capacity
count := 0
s.dataMap.Range(func(key, value any) bool {
count++
return true
})
ret := make([]O, 0, count)
s.dataMap.Range(func(key, value any) bool {
ret = append(ret, value.(O))
return true
@@ -0,0 +1 @@
package network_additional_wire // import "yunion.io/x/onecloud/pkg/scheduler/data_manager/network_additional_wire"
@@ -0,0 +1,95 @@
package network_additional_wire
import (
"context"
"sync"
"time"
"yunion.io/x/log"
"yunion.io/x/pkg/util/wait"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/compute/models"
)
var (
manager *networkAdditionalWireManager
)
func Start(ctx context.Context, refreshInterval time.Duration) {
manager = &networkAdditionalWireManager{
dataMap: newNawMap(),
refreshInterval: refreshInterval,
}
manager.sync()
}
type nawList []*models.SNetworkAdditionalWire
type nawMap struct {
*sync.Map
}
func newNawMap() *nawMap {
return &nawMap{
Map: new(sync.Map),
}
}
func (m *nawMap) GetByNetworkId(id string) nawList {
value, ok := m.Load(id)
if ok {
return value.(nawList)
}
return nil
}
func (m *nawMap) Add(item *models.SNetworkAdditionalWire) {
items := m.GetByNetworkId(item.NetworkId)
if items == nil {
items = make([]*models.SNetworkAdditionalWire, 0)
}
items = append(items, item)
m.Store(item.NetworkId, items)
}
type networkAdditionalWireManager struct {
dataMap *nawMap
refreshInterval time.Duration
}
func (m *networkAdditionalWireManager) syncOnce() {
log.Infof("NetworkAdditionalWireManager start sync")
startTime := time.Now()
q := models.NetworkAdditionalWireManager.Query()
ret := make([]models.SNetworkAdditionalWire, 0)
err := db.FetchModelObjects(models.NetworkAdditionalWireManager, q, &ret)
if err != nil {
log.Errorf("NetworkAdditionalWireManager fetch err: %v", err)
return
}
m.dataMap = newNawMap()
for i := range ret {
obj := &ret[i]
m.dataMap.Add(obj)
}
log.Infof("NetworkAdditionalWireManager end sync, consume %s", time.Since(startTime))
}
func (m *networkAdditionalWireManager) sync() {
wait.Forever(m.syncOnce, m.refreshInterval)
}
func (m *networkAdditionalWireManager) GetByNetworkId(networkId string) []*models.SNetworkAdditionalWire {
list := m.dataMap.GetByNetworkId(networkId)
return list
}
func FetchNetworkAdditionalWireIds(networkId string) []string {
naws := manager.GetByNetworkId(networkId)
wires := make([]string, len(naws))
for i := range naws {
wires[i] = naws[i].WireId
}
return wires
}
+2 -1
View File
@@ -35,12 +35,13 @@ import (
// InstallHandler is an interface that registes route and
// handles scheduler's services.
func InstallHandler(r *gin.Engine) {
func InstallHandler(r *gin.Engine, enableProfiling bool) {
r.POST("/scheduler", timer(scheduleHandler))
r.POST("/scheduler/:action", timer(schedulerActionHandler))
r.POST("/scheduler/:action/:ident", timer(schedulerActionIdentHandler))
InstallPingHandler(r)
InstallVersionHandler(r)
InstallProfiling(r, enableProfiling)
}
func timer(f gin.HandlerFunc) gin.HandlerFunc {
+40
View File
@@ -0,0 +1,40 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package handler
import (
"net/http/pprof"
gin "github.com/gin-gonic/gin"
)
// InstallProfiling 在 gin 引擎上注册 pprof 相关路由。
// 路由与 appsrv 中保持一致:/debug/pprof, /cmdline, /profile, /symbol, /trace
func InstallProfiling(r *gin.Engine, enableProfiling bool) {
if !enableProfiling {
return
}
base := "/debug/pprof"
// 与 net/http/pprof 的默认注册保持一致
r.GET(base, gin.WrapF(pprof.Index))
r.GET(base+"/", gin.WrapF(pprof.Index))
r.GET(base+"/cmdline", gin.WrapF(pprof.Cmdline))
r.GET(base+"/profile", gin.WrapF(pprof.Profile))
r.GET(base+"/symbol", gin.WrapF(pprof.Symbol))
r.POST(base+"/symbol", gin.WrapF(pprof.Symbol))
r.GET(base+"/trace", gin.WrapF(pprof.Trace))
}
+3 -1
View File
@@ -42,6 +42,7 @@ import (
"yunion.io/x/onecloud/pkg/scheduler/data_manager/cloudregion"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/netinterface"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/network"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/network_additional_wire"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/schedtag"
skuman "yunion.io/x/onecloud/pkg/scheduler/data_manager/sku"
"yunion.io/x/onecloud/pkg/scheduler/data_manager/wire"
@@ -119,6 +120,7 @@ func StartService() error {
ctx := context.Background()
go skuman.Start(ctx, utils.ToDuration(o.Options.SkuRefreshInterval))
go schedtag.Start(ctx, utils.ToDuration("30s"))
go network_additional_wire.Start(ctx, utils.ToDuration("30m"))
for _, f := range []func(ctx context.Context){
cloudregion.Manager.Start,
@@ -151,7 +153,7 @@ func startHTTP(app *appsrv.Application, opt *o.SchedulerOptions) error {
router.Use(middleware.KeystoneTokenVerifyMiddleware())
// prometheus.InstallHandler(router)
schedhandler.InstallHandler(router)
schedhandler.InstallHandler(router, opt.EnableAppProfiling)
server := appsrv.InitHTTPServer(app, net.JoinHostPort(opt.Address, strconv.Itoa(int(opt.Port))))
server.Handler = router
+12 -1
View File
@@ -31,7 +31,18 @@ const (
func KeystoneTokenVerifyMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// hack
escapeAuth := []string{"ping", "version", "metrics", "k8s/predicates", "k8s/priorities"}
escapeAuth := []string{
"ping",
"version",
"metrics",
"k8s/predicates",
"k8s/priorities",
"debug/pprof",
"debug/pprof/cmdline",
"debug/pprof/profile",
"debug/pprof/symbol",
"debug/pprof/trace",
}
for _, s := range escapeAuth {
if strings.HasSuffix(c.Request.URL.Path, s) {
c.Next()