-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
sla.go
112 lines (101 loc) · 3.72 KB
/
sla.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
Copyright 2020 The Knative Authors
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 main
import (
"net/http"
"time"
tpb "github.com/google/mako/clients/proto/analyzers/threshold_analyzer_go_proto"
mpb "github.com/google/mako/spec/proto/mako_go_proto"
vegeta "github.com/tsenart/vegeta/v12/lib"
"knative.dev/pkg/ptr"
"knative.dev/pkg/test/mako"
)
// This function constructs an analyzer that validates the p95 aggregate value of the given metric.
func new95PercentileLatency(name, valueKey string, min, max time.Duration) *tpb.ThresholdAnalyzerInput {
return &tpb.ThresholdAnalyzerInput{
Name: ptr.String(name),
Configs: []*tpb.ThresholdConfig{{
Min: bound(min),
Max: bound(max),
DataFilter: &mpb.DataFilter{
DataType: mpb.DataFilter_METRIC_AGGREGATE_PERCENTILE.Enum(),
PercentileMilliRank: ptr.Int32(95000),
ValueKey: ptr.String(valueKey),
},
}},
CrossRunConfig: mako.NewCrossRunConfig(10),
}
}
// This analyzer validates that the p95 latency hitting a Knative Service
// going through JUST the queue-proxy falls in the +10ms range.
func newQueue95PercentileLatency(valueKey string) *tpb.ThresholdAnalyzerInput {
return new95PercentileLatency("Queue p95 latency", valueKey, 100*time.Millisecond, 110*time.Millisecond)
}
// This analyzer validates that the p95 latency hitting a Knative Service
// going through BOTH the activator and queue-proxy falls in the +10ms range.
func newActivator95PercentileLatency(valueKey string) *tpb.ThresholdAnalyzerInput {
return new95PercentileLatency("Activator p95 latency", valueKey, 100*time.Millisecond, 110*time.Millisecond)
}
var (
// Map the above to our benchmark targets.
targets = map[string]struct {
target vegeta.Target
stat string
estat string
analyzers []*tpb.ThresholdAnalyzerInput
}{
"queue-proxy": {
target: vegeta.Target{
Method: http.MethodGet,
URL: "http://queue-proxy.default.svc.cluster.local?sleep=100",
},
stat: "q",
estat: "qe",
analyzers: []*tpb.ThresholdAnalyzerInput{newQueue95PercentileLatency("q")},
},
"queue-proxy-with-cc": {
target: vegeta.Target{
Method: http.MethodGet,
URL: "http://queue-proxy-with-cc.default.svc.cluster.local?sleep=100",
},
stat: "qc",
estat: "qce",
// We use the same threshold analyzer, since we want Breaker to exert minimal latency impact.
analyzers: []*tpb.ThresholdAnalyzerInput{newQueue95PercentileLatency("qc")},
},
"activator": {
target: vegeta.Target{
Method: http.MethodGet,
URL: "http://activator.default.svc.cluster.local?sleep=100",
},
stat: "a",
estat: "ae",
analyzers: []*tpb.ThresholdAnalyzerInput{newActivator95PercentileLatency("a")},
},
"activator-with-cc": {
target: vegeta.Target{
Method: http.MethodGet,
URL: "http://activator-with-cc.default.svc.cluster.local?sleep=100",
},
stat: "ac",
estat: "ace",
// We use the same threshold analyzer, since we want Throttler/Breaker to exert minimal latency impact.
analyzers: []*tpb.ThresholdAnalyzerInput{newActivator95PercentileLatency("ac")},
},
}
)
// bound is a helper for making the inline SLOs more readable by expressing
// them as durations.
func bound(d time.Duration) *float64 {
return ptr.Float64(d.Seconds())
}