跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Connection: keep-alive 迷一样的东西
未分類
9 9 月 2020

Connection: keep-alive 迷一样的东西

Connection: keep-alive 迷一样的东西

資深大佬 : supermoonie 5

用 netty 写了一个 http & https 代理,在将服务器响应的发送到客户端(浏览器)后,如果不手动关闭代理与服务器的连接以及客户端的连接,netty 就会重用之前的连接,这样的话,整个网站(比如 youtobe )的流量都只通过一个连接通道进行传输,看视频卡得一批。当响应发送到客户端后就关闭 Channel,哇,整个世界都舒服了,网速直接满载,连接的通道也多了,再加上二级代理,youtube 1080p 妥妥的

大佬有話說 (21)

  • 資深大佬 : ysc3839

    这是你网络的问题吧?针对单连接进行了限速。如果是 HTTP/2 的话,你这种操作就没用了,一个服务器的所有请求都是使用单个连接的。

  • 資深大佬 : est

    @ysc3839 这个是 chrome 的特性。h2 协议本身可以多路复用 m:n 来并发传输 chunk

  • 主 資深大佬 : supermoonie

    @ysc3839 限速应该不会有,因为网络在测试期间没有变动,而且测试了很多次。HTTP/2 的话会进行降级处理。单个连接是没问题,如果 keep-alive  的话,新的请求就会使用现有的连接,那么这个连接的传输能力岂不是就会很慢吗?现在通过手动关闭,就有机会创建多个连接,是不是就会快了很多?以上只是猜想,我还需要更多的测试进行验证才能找到问题所在

  • 主 資深大佬 : supermoonie

    @est 看了下协议的版本,是 HTTP/1.1,应该是 Chrome 对 keep-alive 做了处理,现在就测试的现象来看,主动关闭客户端( Chrome )的通道,网速就上去了,可能是我代理服务器的连接重用机制需要调整,我去查一下 netty 关于连接复用的处理细节再测试看看

  • 資深大佬 : Mohanson

    估计你处理完一个 http 请求后没有接着从该 tcp 通道继续读取 http 请求,导致浏览器重用通道后发的请求会喂了狗然后等待几秒时间后重试,和 persistent connection 没关系。另外 http 代理的 persistent connection 在 firefox 上有 bug

  • 主 資深大佬 : supermoonie

    @Mohanson 应该不是没有继续读取 http 请求的问题,因为 netty 每次的 channelRead 事件,我都有日志打印跟踪,最终都会与服务器的连接通道发出去,还是觉得 Chrome 在处理 keep-alive 的时候,有点迷。如果不主动关闭 Chrome 的 channel,Chrome 就会一直转圈圈,也不会失败,而是等很久才加载出来。现在代理的线程池配置是处理客户端 channel 的固定 16 个线程,处理服务器端 channel 也是固定 16 个线程,所以我在想是不是因为 channel 重用导致线程池被耗尽了

  • 資深大佬 : domosekai

    youtube 的视频(googlevideo)本来就是单连接,打开 F12 看看卡在哪儿了

  • 主 資深大佬 : supermoonie

    @domosekai 卡在了 pending ……

  • 資深大佬 : domosekai

    pending 表示现有连接被占用,那我的猜测和#5 类似,你的代理因为某种原因让 chrome 无法复用连接,导致卡死超时后再重新连接,虽然你主动断开看上去也可以,但不一定适用于其他网站,我试了下 youtube 的视频在 chrome 使用代理和直连的情况下都是单连接复用

  • 主 資深大佬 : supermoonie

    @domosekai 待我今天晚上再验证下

  • 主 資深大佬 : supermoonie

    @ysc3839
    @est
    @Mohanson
    @domosekai

    感谢各位,确实是代码的问题,在处理 EmptyLastHttpContent 的时候有客户端连接状态的判断,如果没建立连接的话,EmptyLastHttpContent 就会被丢弃掉,导致发送到目标服务器的请求迟迟不能结束,所以造成了客户端请求的 pending 。

  • 資深大佬 : arloor

    按道理来说,youtube 现在应该是 http2 的了
    即使走了 http 代理,也会使用 connect 隧道,在这种情况下,仍然应该是 http2

    另外,你的这个项目应该可以在一定程度上对比下这个 https://github.com/arloor/HttpProxy

    既然你提到 EmptyLastHttpContent,应该和这个项目的实现差不多

  • 主 資深大佬 : supermoonie

    @arloor youtube 现在确实是 h2 的协议了,不过代理会对其进行降级,目前还没深入研究,后面再细细研究下 h2 。确实和那个项目差不多,不过我现在写的提供了 HttpRequest 、HttpResponse 的拦截器,动态二级代理支持,黑白名单,远程及本地映射以及即将实现的网络信息统计、自定义 DNS 、限速、vmess 协议、ss 协议等。另外基于拦截器做了一个类似 Charles 的单页面应用,基本上和 Charles 的功能一样,只不过我把请求和响应保存到 sqllite 数据库中了,可以进行查询。另外的打算可能是做插件管理,比如某盘的嗅探多线程下载插件。感觉可以做的很多。。。

  • 資深大佬 : arloor

    @supermoonie 其实我觉得还是 http 代理本身比较有意义,其他的其实并不是很有意义

    友情提醒一下,代理这种场景中需要注意控制背压,不然会有 outofDerectMemory

  • 主 資深大佬 : supermoonie

    @arloor 现在还没遇到过,等做完了做下各种网络测试。GlobalChannelTrafficShapingHandler 这个 handler 应该能解决很多问题,特别是请求堆积造成的内存泄漏

  • 資深大佬 : monkeyWie

    @supermoonie 跟我这个很像啊,另外还实现了 https 的中间人攻击,https://github.com/monkeyWie/proxyee

  • 主 資深大佬 : supermoonie

    @monkeyWie 哎呦,大佬大佬,确实是参考了你的那个项目,没想到碰到作者了,只不过我重新写了一遍,加了一些以及需要的功能,另外用 vue 写了一个抓包的界面

  • 資深大佬 : monkeyWie

    @supermoonie 哈哈,巧了,抓包最麻烦的地方就是要处理大响应,比如上传文件和下载文件,搞不好就 OOM 了

  • 主 資深大佬 : supermoonie

    @monkeyWie 大的请求和响应,是不是可以通过 Content-Length 判断下,然后超过一定的阈值,先序列化到本地文件中,再通过 Buffer 分块读取,这只是我的猜想,不知道可不可行

  • 資深大佬 : monkeyWie

    @supermoonie 我也是这样考虑的,不过 chunked 编码的还要特殊处理下,因为拿不到 Content-Length

  • 主 資深大佬 : supermoonie

    @monkeyWie 能拿到 FullHttpRequest 以及 FullHttpResponse 中的 content 吧,然后根据这个 content 获取 content-lenght,可还行?等我这周末测试下大的请求 /响应,看看能不能找到解决方法

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具