面试题答案
一键面试实现思路
- 创建一个带有超时的
Context
。这个Context
会被传递到所有下游服务的调用中。 - 使用
Go
的goroutine
并发调用各个下游服务。 - 每个
goroutine
都监听Context
的取消信号。如果在下游服务响应之前Context
被取消(超时),则该goroutine
应停止操作并返回。 - 使用
sync.WaitGroup
来等待所有goroutine
完成,或者在超时时提前结束等待。
代码示例
package main
import (
"context"
"fmt"
"sync"
"time"
)
// 模拟下游服务调用
func downstreamService(ctx context.Context, name string, duration time.Duration, resultChan chan string) {
select {
case <-time.After(duration):
resultChan <- fmt.Sprintf("%s service completed", name)
case <-ctx.Done():
resultChan <- fmt.Sprintf("%s service cancelled", name)
}
}
func main() {
// 创建一个带有超时的Context
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var wg sync.WaitGroup
resultChan := make(chan string, 3)
// 启动多个goroutine调用下游服务
services := []struct {
name string
duration time.Duration
}{
{"Service1", 2 * time.Second},
{"Service2", 4 * time.Second},
{"Service3", 1 * time.Second},
}
for _, service := range services {
wg.Add(1)
go func(s struct {
name string
duration time.Duration
}) {
defer wg.Done()
downstreamService(ctx, s.name, s.duration, resultChan)
}(service)
}
go func() {
wg.Wait()
close(resultChan)
}()
// 收集结果
for result := range resultChan {
fmt.Println(result)
}
}
在上述代码中:
downstreamService
函数模拟下游服务调用,它接收Context
、服务名称、模拟的响应时间以及结果通道。它会在Context
取消或等待指定时间后向结果通道发送结果。- 在
main
函数中,创建了一个 3 秒超时的Context
。 - 启动多个
goroutine
并发调用downstreamService
,每个goroutine
对应一个下游服务。 - 使用
sync.WaitGroup
等待所有goroutine
完成,并在所有goroutine
完成后关闭结果通道。 - 最后通过遍历结果通道来获取每个下游服务的执行结果,若某个服务超时,
Context
取消,对应的goroutine
会收到取消信号并停止操作。