背景
- 使用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 |
上两张图:
- 非持久连接
这个是没有保持持久连接的请求,可以看到在完成请求后立即进行了四次挥手操作
- 持久连接