mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix(scheduler): enable profiling (#23642)
* fix(scheduler): enable profiling * feat(scheduler): cache NetworkAdditionalWire
This commit is contained in:
+2
-5
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user