xiaohanliang
Network
Network
  • hi
  • LOWER
    • 0. arp决定下一跳
    • 1. dns决定终点
    • 2. [WIP]dns是不是真的有这些层级
  • MIDDLE
    • 0. 如何理解tcp握手的设计
    • 1. 诡异的tcp拆包现象
    • 2. tcp是一种高效的协议吗
    • 3. 为什么说没有人可以裸用tcp
    • 4. 尝试理解tcp的设计
    • 5. 连接建立@tcp调优
    • 6. 连接断开@tcp调优
    • 7. [WIP]拥塞控制@tcp调优
    • 8. 不需要这些花里胡哨的东西
    • 9. 怎么又是socket又是tcp
  • UPPER
    • 0. 为什么大家都用http
    • 1. [WIP]为什么http也keep-alive
    • 2. 如何保证pipeline的顺序到达
    • 3. 如何保证http的安全性
    • 4. 只不过https基于tls连接
    • 5. 怎么理解get/post
    • 6. http2为什么更快
    • 7. [WIP]内置加速的http3
    • 8. 怎样制造出实时效果-ws
    • 9. kcp是如何榨干你的带宽的
  • DEVICES
    • [302] 跳转到Linux网络设备
  • KUBERNETES NETWORK
    • [302] 跳转到容器网络
Powered by GitBook
On this page
  • 乱序现在怎么搞
  • 必须给我按序响应
  • 那怎么办呢?

Was this helpful?

  1. UPPER

2. 如何保证pipeline的顺序到达

乱序现在怎么搞

你背书也背过, ok从HTTP1.1开始我们支持了KeepAlive, 允许你复用TCP连接, 然后又允许你搞Pipelining. 我们可以把好多条消息一并发出去了. 这种玩法实际上到处都是(TCP的滑动窗口/Redis-Pipeline), 听起来不错

设想一个问题, 如果真的有这么神的玩法, 为什么1.0的时候你不这么玩? 我就可以搞3个TCP连接, 一人发一个包, 我也能实现pipeline, 为什么你一定坚持要在同一个TCP连接上这么玩? 回顾一下这个玩法的过程: ok, 假设我们按照顺序一次push出去了1/2/3三个包, 但1号包却是最后到的, 现在怎么搞?

如果是TCP, 好办, 我有ACK序号, 重传快回传怎么搞都行. 如果是HTTP呢? 如果你使用同一个TCP链接, 那你还是可以依赖底层的ACK序号实现重组. 但如果你使用了三个TCP链接呢? 抱歉没辙, 现在绝对没办法知道这三者的顺序了, 自然也不可能实现重组了

必须给我按序响应

现在我能保证: 你按照什么顺序发, 对方就能按照什么顺序收到. 但如果你发的顺序就是乱的, 对方收到的一定也是乱的, 换句话说你如果发的231, 对方就一定收到231, 你如果发123, 对方就一定收到123

而按照pipeline的要求, 必须是我按照什么顺序发给你, 你就应该按照什么顺序响应我. 因此在上面的例子中, 我在pipeline里拿到了三个请求并起了三个协程处理, 但如果23好了, 1因为某些原因没好, 延迟了, 我们也不能先响应23. 像这种三个消息构成一个队列, 队头卡住了, 我们叫它 head-of-line blocking问题

那怎么办呢?

仅仅因为1不能发, 从而搞的23也不能发, 说到底还是因为HTTP没有序号搞的, 如果消息都有序号了, 我们也能先发23, 最后发1, 到了那边对方重排一下完事了, HTTP2就搞出了一个序号的概念:

  1. 一个TCP链接划分成好几个"stream"

  2. 把一个请求/一个响应叫做"消息"

  3. 一个消息拆成好几个"帧", 每个帧都有自己的序号

如果帧有序号, 这样消息也就有序号了, 说明对端就可以靠这个序号重新排序了, 这种情况下, 就算先收到23, 最后收到1, 我们也能靠消息序号实现重排了

Previous1. [WIP]为什么http也keep-aliveNext3. 如何保证http的安全性

Last updated 4 years ago

Was this helpful?