ограничение скорости
This commit is contained in:
parent
50383b5cab
commit
acb7585e84
@ -33,7 +33,7 @@ Select
|
|||||||
Тикеры (повторения) (Tickers)
|
Тикеры (повторения) (Tickers)
|
||||||
Пулы воркеров (Worker Pools)
|
Пулы воркеров (Worker Pools)
|
||||||
WaitGroups
|
WaitGroups
|
||||||
Rate Limiting
|
Ограничение скорости (Rate Limiting)
|
||||||
Atomic Counters
|
Atomic Counters
|
||||||
Mutexes
|
Mutexes
|
||||||
Stateful Goroutines
|
Stateful Goroutines
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
// <em>[Rate limiting](http://en.wikipedia.org/wiki/Rate_limiting)</em>
|
// <em>[Ограничение скорости](http://en.wikipedia.org/wiki/Rate_limiting)</em>
|
||||||
// is an important mechanism for controlling resource
|
// является важным механизмом контроля использования ресурсов и
|
||||||
// utilization and maintaining quality of service. Go
|
// поддержания качества обслуживания. Go элегантно поддерживает
|
||||||
// elegantly supports rate limiting with goroutines,
|
// ограничение скорости с помощью горутин, каналов и [тикеров](tickers).
|
||||||
// channels, and [tickers](tickers).
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -13,52 +12,54 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// First we'll look at basic rate limiting. Suppose
|
// Сначала мы рассмотрим базовое ограничение скорости.
|
||||||
// we want to limit our handling of incoming requests.
|
// Предположим, мы хотим ограничить нашу обработку
|
||||||
// We'll serve these requests off a channel of the
|
// входящих запросов. Мы будем обслуживать эти запросы
|
||||||
// same name.
|
// с одноименного канала.
|
||||||
requests := make(chan int, 5)
|
requests := make(chan int, 5)
|
||||||
for i := 1; i <= 5; i++ {
|
for i := 1; i <= 5; i++ {
|
||||||
requests <- i
|
requests <- i
|
||||||
}
|
}
|
||||||
close(requests)
|
close(requests)
|
||||||
|
|
||||||
// This `limiter` channel will receive a value
|
// Канал `limiter` будет получать значение каждые
|
||||||
// every 200 milliseconds. This is the regulator in
|
// 200мс. Это то, что регулирует скорость в нашей
|
||||||
// our rate limiting scheme.
|
// схеме.
|
||||||
limiter := time.Tick(200 * time.Millisecond)
|
limiter := time.Tick(200 * time.Millisecond)
|
||||||
|
|
||||||
// By blocking on a receive from the `limiter` channel
|
// Блокируя прием от канала `limiter` перед
|
||||||
// before serving each request, we limit ourselves to
|
// обслуживанием каждого запроса, мы ограничиваем себя
|
||||||
// 1 request every 200 milliseconds.
|
// одним запросом каждые 200 миллисекунд.
|
||||||
for req := range requests {
|
for req := range requests {
|
||||||
<-limiter
|
<-limiter
|
||||||
fmt.Println("request", req, time.Now())
|
fmt.Println("request", req, time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may want to allow short bursts of requests in
|
// Мы можем разрешить короткие всплески запросов в
|
||||||
// our rate limiting scheme while preserving the
|
// нашей схеме ограничения скорости при сохранении
|
||||||
// overall rate limit. We can accomplish this by
|
// общего ограничения скорости. Мы можем сделать это
|
||||||
// buffering our limiter channel. This `burstyLimiter`
|
// путем буферизации нашего канала ограничения. Этот
|
||||||
// channel will allow bursts of up to 3 events.
|
// канал `burstyLimiter` будет позволять делать до
|
||||||
|
// 3 событий.
|
||||||
burstyLimiter := make(chan time.Time, 3)
|
burstyLimiter := make(chan time.Time, 3)
|
||||||
|
|
||||||
// Fill up the channel to represent allowed bursting.
|
// Заполняем канал, чтобы предоставить возможность
|
||||||
|
// ускорить.
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
burstyLimiter <- time.Now()
|
burstyLimiter <- time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every 200 milliseconds we'll try to add a new
|
// Каждые 200мс мы будем пытаться добавлять новое
|
||||||
// value to `burstyLimiter`, up to its limit of 3.
|
// значение в `burstyLimiter`, до своего предела
|
||||||
|
// в 3 значения.
|
||||||
go func() {
|
go func() {
|
||||||
for t := range time.Tick(200 * time.Millisecond) {
|
for t := range time.Tick(200 * time.Millisecond) {
|
||||||
burstyLimiter <- t
|
burstyLimiter <- t
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Now simulate 5 more incoming requests. The first
|
// Теперь смоделируем еще 5 входящих запросов. Первые
|
||||||
// 3 of these will benefit from the burst capability
|
// 3 из них получат выгоду от вместимости `burstyLimiter`.
|
||||||
// of `burstyLimiter`.
|
|
||||||
burstyRequests := make(chan int, 5)
|
burstyRequests := make(chan int, 5)
|
||||||
for i := 1; i <= 5; i++ {
|
for i := 1; i <= 5; i++ {
|
||||||
burstyRequests <- i
|
burstyRequests <- i
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Running our program we see the first batch of requests
|
# При запуске нашей программы мы видим, что первая
|
||||||
# handled once every ~200 milliseconds as desired.
|
# партия запросов обрабатывается каждые ~200мс.
|
||||||
$ go run rate-limiting.go
|
$ go run rate-limiting.go
|
||||||
request 1 2012-10-19 00:38:18.687438 +0000 UTC
|
request 1 2012-10-19 00:38:18.687438 +0000 UTC
|
||||||
request 2 2012-10-19 00:38:18.887471 +0000 UTC
|
request 2 2012-10-19 00:38:18.887471 +0000 UTC
|
||||||
@ -7,9 +7,10 @@ request 3 2012-10-19 00:38:19.087238 +0000 UTC
|
|||||||
request 4 2012-10-19 00:38:19.287338 +0000 UTC
|
request 4 2012-10-19 00:38:19.287338 +0000 UTC
|
||||||
request 5 2012-10-19 00:38:19.487331 +0000 UTC
|
request 5 2012-10-19 00:38:19.487331 +0000 UTC
|
||||||
|
|
||||||
# For the second batch of requests we serve the first
|
# Для второго пула запросов мы обслуживаем первые
|
||||||
# 3 immediately because of the burstable rate limiting,
|
# 3 сразу из-за использования ограничения скорости,
|
||||||
# then serve the remaining 2 with ~200ms delays each.
|
# затем обслуживаем оставшиеся 2 с задержками ~200мс
|
||||||
|
# каждый.
|
||||||
request 1 2012-10-19 00:38:20.487578 +0000 UTC
|
request 1 2012-10-19 00:38:20.487578 +0000 UTC
|
||||||
request 2 2012-10-19 00:38:20.487645 +0000 UTC
|
request 2 2012-10-19 00:38:20.487645 +0000 UTC
|
||||||
request 3 2012-10-19 00:38:20.487676 +0000 UTC
|
request 3 2012-10-19 00:38:20.487676 +0000 UTC
|
||||||
|
Loading…
x
Reference in New Issue
Block a user