问题背景
业务方varnish 的请求需要通过网关来做路由,这就需要做为varnish的backend server,我们在配置varnish 对网关的健康检查时,就时不通过,但是对tomcat的健康检查是ok的,但是nginx对网关的健康检查时正常的。这就让我们很尴尬。
问题排查
网关是我们自己基于netty开发的,通过查看响应头等和tomcat都一样还是健康检查失败,通过tcpdump发现,varnish和tomcat的健康检查http请求头带有connection:close,http协议规定请求头带有connection:close时,服务端响应完后,必须关闭该链接,通过tcpdump也发现,tomcat 响应完后,主动发了Fin码给varnish,图如下:
varnish-fin-tomcat.jpg
图中那个Fin码是tomcat响应完后,主动发了起的。
而网关并没有关闭该链接,还是在响应头加上了connection:close,让客户端关闭即varnish自己关闭,因为我不想time await 状态在网关,通过查看varnish代码发现, varnish严格遵循http的标准,在读完数据后,等待链接的关闭,即等待服务端的fin码,而网关确等varnish关闭,这样varnish等待超时后,就关闭链接,并标记healthcheck 失败,这也是我们通过查看varnish的日志,healthcheck网关时,响应是能正常解析的。
网关发现这个情况后,通过对请求头有connection:close的请求时,主动关闭链接,重新上线后,varnish对网关的healthcheck通过,日志总算出现了happy!!
总结:
http一个小的请求头问题导致排查了一个晚上,也是协议细节不熟悉,不遵循规范导致的。
网友评论