在 Go 使用 Thrift ,HttpStatus 为什么会是 413?|Go主题月

413 阅读1分钟

在使用 Sync.pool 管理调用 Thrift 的 goroutine,减少创建及销毁 goroutine 开销,c 为调用client。

c := pool.Get()
defer pool.Put(c)
以下为调用逻辑....

问题现象

主要表现为:Client 端在通过 Thrift 协议调用 Server 端时,只有 HTTP Status 返回 413,但是无其他任何有用信息,body 也是空。

问题原因

那接下来,需要根据上述的问题现象,分析出问题的根因。

  • 先看看 HttpStatus 413是什么意思?

 HTTP Status 413 (请求实体过大),而针对该问题也主要为header过大。

 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。

PS: 这里请求实体过大的意思是包括 header 和 body(一开始定位时只定位了 body,就进坑了- -)

  • 因为在使用 Thrift 作为 RPC 框架时,会设置 header(使用的是以下 Addheader 方法)。但对于存在于 pool 中的 goroutine,通过以下代码,p.header.Add(key, value) 得知,如果调用 Addheader 会不断增加 header 中的内容。所以导致请求实体过大。
// Set the HTTP Header for this specific Thrift Transport
// It is important that you first assert the TTransport as a THttpClient type
// like so:
// httpTrans := trans.(THttpClient)
// httpTrans.SetHeader("User-Agent","Thrift Client 1.0")
func (p \*THttpClient) SetHeader(key string, value string) {
    p.header.Add(key, value)
}

解决方案

那知道问题根因之后,则需要解决该类问题,而推荐的解决方案有以下几种:

  • 自己继承后重新实现(推荐)

  • 修改 thrfit 包中 SetHeader/Flush方法,增加重置 header 逻辑

  • 每次都重新创建 Thrift 连接

环境

  • Go:1.5

  • Linux:Linux version 2.6.32-279.el6.x86_64 (gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

  • OS:CentOS release 6.3 (Final) 2.6.32-279.el6.x86_64

  • CPU:12

  • Mem:8G

  • 网络协议:Thrift