Skip to content

Commit 1c27790

Browse files
authored
Merge branch 'master' into meiji163/skip-host
2 parents 2dab05c + f987bf1 commit 1c27790

File tree

4 files changed

+45
-20
lines changed

4 files changed

+45
-20
lines changed

doc/http.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Notes:
4949
- `/throttle-app/archive/ttl/30/ratio/1`: completely refuse `/check/archive/*` requests for a duration of `30` minutes
5050
- `/throttle-app/archive/ttl/30/ratio/0.9`: _mostly_ refuse `/check/archive/*` requests for a duration of `30` minutes. On average (random dice roll), `9` out of `10` requests (i.e. `90%`) will be denied, and one approved.
5151
- `/throttle-app/archive/ttl/30/ratio/0.5`: refuse `50%` of `/check/archive/*` requests for a duration of `30` minutes
52-
52+
5353
- `/throttle-app/<app-name>/ttl/<ttlMinutes>`:
5454

5555
- If app is already throttled, modify TTL portion only, without changing the ratio.
@@ -65,7 +65,8 @@ Notes:
6565

6666
Same as calling `/throttle-app/<app-name>/ttl/60/ratio/1`. Provided as convenience endpoint.
6767

68-
- `/unthrottle-app/<app-name>`: remove any imposed throttling constraint from given app. Example:
68+
- `/throttle-app` can take a query parameter `store_name` to throttle the app only on one store (i.e. MySQL cluster). For example `/throttle-app/archive?store_name=mycluster` refuses `/check/archive/mysql/mycluster` requests for `1` hour.
69+
6970

7071
`/unthrottle-app/archive` will re-allow the `archive` app to get valid response from `/check/archive/*` requests.
7172

pkg/http/api.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,21 @@ func (api *APIImpl) MetricsHealth(w http.ResponseWriter, r *http.Request, ps htt
238238

239239
// ThrottleApp forcibly marks given app as throttled. Future requests by this app may be denied.
240240
func (api *APIImpl) ThrottleApp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
241-
appName := ps.ByName("app")
241+
storeName := r.URL.Query().Get("store_name")
242+
var appName string
243+
if storeName != "" {
244+
// limit throttling to this store
245+
appName = fmt.Sprintf("%s/%s", ps.ByName("app"), storeName)
246+
} else {
247+
// default is throttle app globally
248+
appName = ps.ByName("app")
249+
}
250+
242251
var expireAt time.Time // default zero
243252
var ttlMinutes int64
244253
var ratio float64
245254
var err error
255+
246256
if ps.ByName("ttlMinutes") == "" {
247257
ttlMinutes = 0
248258
} else if ttlMinutes, err = strconv.ParseInt(ps.ByName("ttlMinutes"), 10, 64); err != nil {
@@ -266,12 +276,21 @@ response:
266276
api.respondGeneric(w, r, err)
267277
}
268278

269-
// ThrottleApp unthrottles given app.
279+
// UnthrottleApp unthrottles given app.
270280
func (api *APIImpl) UnthrottleApp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
271281
appName := ps.ByName("app")
272-
err := api.consensusService.UnthrottleApp(appName)
273-
274-
api.respondGeneric(w, r, err)
282+
appWithStorePrefix := appName + "/"
283+
284+
for app := range api.consensusService.ThrottledAppsMap() {
285+
if app == appName || strings.HasPrefix(app, appWithStorePrefix) {
286+
err := api.consensusService.UnthrottleApp(app)
287+
if err != nil {
288+
api.respondGeneric(w, r, err)
289+
return
290+
}
291+
}
292+
}
293+
api.respondGeneric(w, r, nil)
275294
}
276295

277296
// ThrottledApps returns a snapshot of all currently throttled apps

pkg/throttle/check.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func (check *ThrottlerCheck) checkAppMetricResult(appName string, storeType stri
4848
}
4949
}
5050
//
51-
metricResult, threshold := check.throttler.AppRequestMetricResult(appName, metricResultFunc, denyApp)
51+
metricResult, threshold := check.throttler.AppRequestMetricResult(appName, storeName, metricResultFunc, denyApp)
5252
if flags.OverrideThreshold > 0 {
5353
threshold = flags.OverrideThreshold
5454
}

pkg/throttle/throttler.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -541,16 +541,21 @@ func (throttler *Throttler) UnthrottleApp(appName string) {
541541
throttler.throttledApps.Delete(appName)
542542
}
543543

544-
func (throttler *Throttler) IsAppThrottled(appName string) bool {
545-
if object, found := throttler.throttledApps.Get(appName); found {
546-
appThrottle := object.(*base.AppThrottle)
547-
if appThrottle.ExpireAt.Before(time.Now()) {
548-
// throttling cleanup hasn't purged yet, but it is expired
549-
return false
550-
}
551-
// handle ratio
552-
if rand.Float64() < appThrottle.Ratio {
553-
return true
544+
func (throttler *Throttler) IsAppThrottled(appName, storeName string) bool {
545+
appWithStore := fmt.Sprintf("%s/%s", appName, storeName)
546+
keys := []string{appWithStore, appName}
547+
// check if app is throttled for this store or globally
548+
for _, key := range keys {
549+
if object, found := throttler.throttledApps.Get(key); found {
550+
appThrottle := object.(*base.AppThrottle)
551+
if appThrottle.ExpireAt.Before(time.Now()) {
552+
// throttling cleanup hasn't purged yet, but it is expired
553+
continue
554+
}
555+
// handle ratio
556+
if rand.Float64() < appThrottle.Ratio {
557+
return true
558+
}
554559
}
555560
}
556561
return false
@@ -642,11 +647,11 @@ func (throttler *Throttler) metricsHealthSnapshot() base.MetricHealthMap {
642647
return snapshot
643648
}
644649

645-
func (throttler *Throttler) AppRequestMetricResult(appName string, metricResultFunc base.MetricResultFunc, denyApp bool) (metricResult base.MetricResult, threshold float64) {
650+
func (throttler *Throttler) AppRequestMetricResult(appName string, storeName string, metricResultFunc base.MetricResultFunc, denyApp bool) (metricResult base.MetricResult, threshold float64) {
646651
if denyApp {
647652
return base.AppDeniedMetric, 0
648653
}
649-
if throttler.IsAppThrottled(appName) {
654+
if throttler.IsAppThrottled(appName, storeName) {
650655
return base.AppDeniedMetric, 0
651656
}
652657
return metricResultFunc()

0 commit comments

Comments
 (0)