【问题标题】:Golang get request outside the handler functionGolang 在处理函数之外获取请求
【发布时间】:2020-04-08 14:58:09
【问题描述】:

是否有任何选项可以在 http.HandlerFunc 之外获取当前请求对象(结构)?我面临的问题是,我只需要每个请求唯一的随机哈希,我不能使用全局变量,因为如果我的应用程序同时处理 2 个或更多请求,每个请求都会覆盖全局变量值。

我发现我可以像这样使用上下文:

func Init() Middleware {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
            ctx := context.WithValue(request.Context(), "requestId", GetRequestHash())

            next.ServeHTTP(writer, request.WithContext(ctx))
        })
    }
}

然后在 HandlerFunc 中我可以得到这个唯一的哈希

request.Context().Value("requestId")

但问题是我在我的应用程序中非常非常需要这个值,我不能只通过参数传递这个哈希值。我已经编写了许多处理程序,并且这个处理程序调用了调用另一个处理程序的函数...我需要在 HandlerFunc 之外的某个地方使用类似 http.GetCurrentRequest 的东西来获取请求上下文,最后获取 requestId(每个请求的唯一哈希)。

显然我不能只将此哈希值保存为全局变量,因为它将被其他请求覆盖...

【问题讨论】:

  • 这就是上下文的用途。您需要传递上下文。
  • "是否有任何选项可以在 http.HandlerFunc 之外获取当前请求对象(结构)?"不。做你发现的,它有效。
  • 好吧,但我仍然需要将上下文传递给我在处理函数 func 中使用的函数,然后这些函数需要将上下文传递给其他函数...
  • 是的,这就是您使用上下文的方式。它包含值和取消。如果您对取消通知无能为力,您可以只传递值。

标签: go


【解决方案1】:

我认为您正在寻找 Go 不支持的 threadlocal equivalent。有一些包可以完成线程本地存储,但我不想推荐它们,因为 Go 团队推荐使用上下文(见下面的链接)。

一些替代(不一定是好的)选项

  • 将哈希存储在一些 go 代码中(对并发场景使用适当的锁)。
  • 改为使用数据存储(如 Redis)来存储这些值。

首选选项 - 使用 context

go developer blog 中,context 包是专门为这种情况设计的。它允许开发人员传递值(如线程中提到的哈希),以及当请求对于特定用例而言太长时取消上下文(从而取消底层 goroutine)的能力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    相关资源
    最近更新 更多