mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-30 15:22:07 +00:00
app: add vm_concurrent_
metrics for visibility in concurrency limiters for vminsert and vmselect
This commit is contained in:
parent
1258c9ef10
commit
8e05758ff5
2 changed files with 49 additions and 9 deletions
|
@ -32,6 +32,17 @@ func Init() {
|
||||||
func Do(f func() error) error {
|
func Do(f func() error) error {
|
||||||
// Limit the number of conurrent f calls in order to prevent from excess
|
// Limit the number of conurrent f calls in order to prevent from excess
|
||||||
// memory usage and CPU trashing.
|
// memory usage and CPU trashing.
|
||||||
|
select {
|
||||||
|
case ch <- struct{}{}:
|
||||||
|
err := f()
|
||||||
|
<-ch
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
// All the workers are busy.
|
||||||
|
// Sleep for up to waitDuration.
|
||||||
|
concurrencyLimitReached.Inc()
|
||||||
t := timerpool.Get(waitDuration)
|
t := timerpool.Get(waitDuration)
|
||||||
select {
|
select {
|
||||||
case ch <- struct{}{}:
|
case ch <- struct{}{}:
|
||||||
|
@ -41,9 +52,19 @@ func Do(f func() error) error {
|
||||||
return err
|
return err
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
timerpool.Put(t)
|
timerpool.Put(t)
|
||||||
concurrencyLimitErrors.Inc()
|
concurrencyLimitTimeout.Inc()
|
||||||
return fmt.Errorf("the server is overloaded with %d concurrent inserts; either increase -maxConcurrentInserts or reduce the load", cap(ch))
|
return fmt.Errorf("the server is overloaded with %d concurrent inserts; either increase -maxConcurrentInserts or reduce the load", cap(ch))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var concurrencyLimitErrors = metrics.NewCounter(`vm_concurrency_limit_errors_total`)
|
var (
|
||||||
|
concurrencyLimitReached = metrics.NewCounter(`vm_concurrent_insert_limit_reached_total`)
|
||||||
|
concurrencyLimitTimeout = metrics.NewCounter(`vm_concurrent_insert_limit_timeout_total`)
|
||||||
|
|
||||||
|
_ = metrics.NewGauge(`vm_concurrent_insert_capacity`, func() float64 {
|
||||||
|
return float64(cap(ch))
|
||||||
|
})
|
||||||
|
_ = metrics.NewGauge(`vm_concurrent_insert_current`, func() float64 {
|
||||||
|
return float64(len(ch))
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
|
@ -80,18 +80,37 @@ func main() {
|
||||||
|
|
||||||
var concurrencyCh chan struct{}
|
var concurrencyCh chan struct{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
concurrencyLimitReached = metrics.NewCounter(`vm_concurrent_select_limit_reached_total`)
|
||||||
|
concurrencyLimitTimeout = metrics.NewCounter(`vm_concurrent_select_limit_timeout_total`)
|
||||||
|
|
||||||
|
_ = metrics.NewGauge(`vm_concurrent_select_capacity`, func() float64 {
|
||||||
|
return float64(cap(concurrencyCh))
|
||||||
|
})
|
||||||
|
_ = metrics.NewGauge(`vm_concurrent_select_current`, func() float64 {
|
||||||
|
return float64(len(concurrencyCh))
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
||||||
// Limit the number of concurrent queries.
|
// Limit the number of concurrent queries.
|
||||||
// Sleep for a while until giving up. This should resolve short bursts in requests.
|
|
||||||
t := timerpool.Get(*maxQueueDuration)
|
|
||||||
select {
|
select {
|
||||||
case concurrencyCh <- struct{}{}:
|
case concurrencyCh <- struct{}{}:
|
||||||
timerpool.Put(t)
|
|
||||||
defer func() { <-concurrencyCh }()
|
defer func() { <-concurrencyCh }()
|
||||||
case <-t.C:
|
default:
|
||||||
timerpool.Put(t)
|
// Sleep for a while until giving up. This should resolve short bursts in requests.
|
||||||
httpserver.Errorf(w, "cannot handle more than %d concurrent requests", cap(concurrencyCh))
|
concurrencyLimitReached.Inc()
|
||||||
return true
|
t := timerpool.Get(*maxQueueDuration)
|
||||||
|
select {
|
||||||
|
case concurrencyCh <- struct{}{}:
|
||||||
|
timerpool.Put(t)
|
||||||
|
defer func() { <-concurrencyCh }()
|
||||||
|
case <-t.C:
|
||||||
|
timerpool.Put(t)
|
||||||
|
concurrencyLimitTimeout.Inc()
|
||||||
|
httpserver.Errorf(w, "cannot handle more than %d concurrent requests", cap(concurrencyCh))
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
path := r.URL.Path
|
path := r.URL.Path
|
||||||
|
|
Loading…
Reference in a new issue