Stay hungry, Stay foolish

0%

HTTP持久化

背景

  • 使用Spring Cloud Gateway做网关,需要确认网关的上下流连接情况——是否持久连接?
  • RemoveHopByHopHeadersFilter会过滤掉KeepAlive,为什么?

持久连接

优点

持久连接的优点是可以利用TCP连接,省去三次握手和四次挥手的开销

HTTP/1.0

HTTP/1.0的持久连接是通过keep-alive实现的,这只是个实验性的,但是到目前为止很多客户端和服务器仍然在使用

实现

客户端发起和服务器响应都有Connection:Keep-Alive,不然就会关闭连接

问题

Keep-Alive与哑代理

如果代理不对Connnection进行处理的话,客户端和服务端都为对方保持了大量的TCP连接,造成不必要的资源浪费

解决

HTTP hop-by-hop

HTTP协议将HTTP头分为了两类:end-to-end和hop-by-hop
hop-by-hop的header头只能用于单次传输层连接,不能被缓存以及转发

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade

以上这几个都属于hop-by-hop,剩下的都是end-to-end

从这个我们可以得知:

  • Spring Cloud Gateway默认有个RemoveHopByHopHeadersFilter过滤这些header头
  • 这里有个比较熟悉的Upgrade,webscoket会用到,如果前面有代理层,不管多少,都要加上Upgrade

HTTP/1.1

http/1.1与http/1.0相比最大的区别就在于对持久化的支持,即

  • 默认就是持久连接
  • 关闭需要显式使用Connection:Close

测试

客户端 服务端 header 持久连接
curl 远程gateway - N
postman/chrome 远程gateway - Y
本地gateway 远程微服务 无keep-alive Y
本地gateway 远程微服务 有keep-alive Y
本地gateway 远程微服务 Connection:close N

上两张图:

  • 非持久连接

这个是没有保持持久连接的请求,可以看到在完成请求后立即进行了四次挥手操作

  • 持久连接

参考

据说打赏我的人,代码没有BUG