複製請求 程序正在處理 用戶的HTTP請求, 或者檢索一個數據塊。你可以將請求分發到多個處理程序(無論是 goroutine ,進程, 還是服務器),其中一個將比其他 處理程序返回更快,可以 立即返回結果。 下面例子 在 單個進程中, 使用多個goroutine 作爲處理程序。 goroutine 將隨機休眠一段時間以模擬不同的負載,
func main() {
doWork := func(done <-chan interface{}, id int, wg *sync.WaitGroup, result chan <- int) {
started := time.Now()
defer wg.Done()
//模擬隨機負載
simulatedLoadTime := time.Duration(1 + rand.Intn(5))*time.Second
select{
case <-done:
case <-time.After(simulatedLoadTime):
}
select{
case <-done:
case result <- id:
}
took := time.Since(started)
//顯示處理程序需要多長時間
if took < simulatedLoadTime{
took = simulatedLoadTime
}
fmt.Printf("%v took %v\n", id, took)
}
done := make(chan interface{})
result := make(chan int)
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i<10; i++{
go doWork(done, i, &wg, result)
}
firstReturned := <- result
close(done)
wg.Wait()
fmt.Printf("Received an answer from #%v\n", firstReturned)
}
//6 took 1.002598933s
//0 took 1.002687636s
//9 took 2s
//2 took 5s
//3 took 1.002655195s
//4 took 3s
//5 took 2s
//1 took 3s
//8 took 4s
//7 took 2s
//Received an answer from #6
所有的處理程序 都應該是儘可能 等價的,有相同的機會處理請求。 建立和維護這樣一套系統 有很大的代價, 但如果你追求的是響應速度, 那是一種非常有價值的架構。這種方式天然提供了容錯 和 可擴展性。