MST

星途 面试题库

面试题:Go语言context在微服务请求链中的超时控制

假设你正在构建一个由多个微服务组成的系统,其中每个微服务之间存在请求链关系。在使用Go语言的context管理请求上下文时,如何精确控制每个微服务的处理超时时间,并且当某个微服务超时时,如何优雅地取消整个请求链后续的操作?请结合代码示例说明。
12.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 控制每个微服务处理超时时间并优雅取消后续操作的思路
    • 在Go语言中,context包提供了控制超时和取消操作的能力。
    • 当创建一个新的微服务调用时,基于传入的父context创建一个带有超时的子context
    • 当某个微服务超时时,通过context的取消机制通知后续微服务停止操作。
  2. 代码示例
package main

import (
    "context"
    "fmt"
    "time"
)

// 模拟一个微服务
func microservice(ctx context.Context, name string, duration time.Duration) error {
    select {
    case <-time.After(duration):
        fmt.Printf("%s 执行完成\n", name)
        return nil
    case <-ctx.Done():
        fmt.Printf("%s 被取消: %v\n", name, ctx.Err())
        return ctx.Err()
    }
}

func main() {
    // 创建一个父context
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    // 模拟请求链,调用多个微服务
    err := microservice(ctx, "微服务1", 1*time.Second)
    if err != nil {
        return
    }

    err = microservice(ctx, "微服务2", 2*time.Second)
    if err != nil {
        return
    }

    err = microservice(ctx, "微服务3", 4*time.Second)
    if err != nil {
        return
    }
}

在上述代码中:

  • microservice函数模拟一个微服务,它接受一个context和执行时长。通过select语句监听ctx.Done()通道来判断是否被取消。
  • main函数中,创建了一个带有3秒超时的context,然后依次调用三个微服务。如果某个微服务超时而导致ctx.Done()通道被关闭,后续的微服务调用将被取消并输出相应的取消信息。