用go http官方库开发api gateway的一些坑

http client

1.MaxIdleConnsPerHost

同一个客户端(tcp连接)qps比较大时需要调大MaxIdleConnsPerHost和MaxIdleConn,否则默认一个host只能保持两个连接,导致一直创建新的tcp使得连接数暴涨,都是TIME_WAIT状态。

2.请求读取的resp.body

请求回来无论是否读取都需要先把resp.body内容全部读取出来,然后再close,否则直接close将不会把连接放入空闲状态复用,也会导致大量TIME_WAIT。

3.req.withContext()

使用req.withContext()来控制请求取消时,如果需要主动取消ctx,则也要先读取出resp.Body的内容,否则也不会复用连接(比如超时的ctx有时会在调用成功后马上cancel(),此时body内数据没有被读取)。

http server

1.设置超时

记得设置read和write等timeout值,否则对于任意一个客户端没有关闭的空闲tcp(比如telnet后不发数据)都不会主动关闭其连接,shutdown时会无限等待下去。

2.全局带上serverHttp的req传入的Context

这个context在客户端主动取消请求时会被cancel,这样避免了一些无用的对后端的请求(请求耗时长时比较明显)。

配合k8s实现无损重启,发布。

节点下线

k8s开启健康检查,服务各配置加载完毕后再对外显示健康,k8s默认在服务健康后连续3次(这个值可修改)健康检查都不是200-399之间后才会在节点中移除,移除之前都会有请求进来,所以需要和运维确认这个值后,在节点退出时确保节点下线再停止接受服务请求。

注:本文章基于go1.10和k8s 1.8

发表评论

邮箱地址不会被公开。 必填项已用*标注

请输入正确的验证码