-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v2ray 的流量统计功能会使裸协议的 ReadV 和 WriteV 同时失效的说明 #416
Comments
这确实是一段迷案.因为各种协议组合在开启各种姿势的统计时,表现非常不一致,历时良久终于破案. 补充一些测试数据和结论如下:
一些结论为:
|
且待缓缓...再行验证..... |
依数据看来readV和writeV对性能影响很大,尤其readV,是很值得保持的优化. 顺便:之前有说VMess over TCP+ TLS 不如 VMess(AES) over TCP,也算破案了,也是因为readV/writeV |
是的,这项研究破了很多性能迷案,非常值得认真看完,有助于加深对很多方面的理解。 比如之前有不少测试表明 v2 的 TCP TLS AES 不如 TCP VMess AES,其实是因为后者有 ReadV & WriteV 加持,其中 ReadV 更重要。 如果你在用非裸协议,则开对应出/入站的流量统计的影响很小,否则影响很大(如桌面平台开裸协议出/入站的流量统计)。 特别地,对于 VLESS XTLS Direct Mode 客户端,特殊实现了 ReadV 和流量统计数据收集,开 outbound 的流量统计几乎没有影响。 重点是,现在我们知道了这些原理,以及优化的方向,以后就能更好地针对性能。 而对于 v2ray 整体框架的性能问题,我和 @badO1a5A90 已经确定了另一处关键(此处不指 pipe)。 |
备忘:有空时魔改出性能优化版 TLS。 |
需要说明,即使有 ReadV 和 WriteV,仍未实现 zero-copy,即数据仍要拷贝一次,经过 v2ray 的内存,也产生了 CPU 切换的开销。 现在的 Go 语言中,如果直接 但对于 v2ray,出入站是分离且透明的,数据靠自己的 buffer 来传输,拿不到另一边的原始 socket,就暂时无法实现 zero-copy。 |
This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days |
这个问题是研究 ReadV 时发现的,感谢 @badO1a5A90 的多次测试。
裸协议指 over TCP,如任意门、Socks、VLESS、VMess(可带加密)等,且不带 HTTP 伪装等额外的东西。
--
是否用 ReadV,取决于断言
v2ray-core/common/buf/io.go
Lines 61 to 71 in 2952492
是否用 WriteV(WriteTo 内有断言)
v2ray-core/common/buf/writer.go
Line 50 in 2952492
--
对于刚刚定义的“裸协议”,这里的断言会成功,就可以用到 ReadV 和 WriteV。
现在存在的问题是,流量统计等功能普遍是通过套一层 Conn 来实现的,这也会导致断言失败,从而失去这两项优化。
以客户端下载(上传同理)的场景举例,配置为 任意门 inbound + VLESS outbound:
开启了 outbound 的流量统计时,VLESS 读取服务端返回的数据时就无法 ReadV,性能大打折扣
开启了 inbound 的流量统计时,任意门 往回写数据时就无法 WriteV,性能大打折扣
根据多次测试的数据,这两个“性能大打折扣”不会叠加,而是 取瓶颈,其中失去 ReadV 比失去 WriteV 更不利。
(顺便一提,流量统计的相关文档有些模糊,存在非预期行为,需要完善。API 的也需要补充)
解决方案:流量统计的数据收集放到 buf.Copy 等处,不套一层 Conn。
--
其它说明:
对于非裸协议,比如加个 HTTP 伪装(理论上可以解决)、WS、TLS 等,大概率没有这两项优化,XTLS Direct Mode 是特例。
对于 PROXY protocol,回落的是我手写的,无此问题。而入站的
acceptProxyProtocol
会套一层 Conn,但很可能本来就有 WS。尚未测试 v2 的常规 ReadV 是否拒绝了 DS,且它现在只对桌面平台开放,详见 #373 (comment)
最后,做这种测试时,“选定数据流向”及“检查配置没错”很重要。
The text was updated successfully, but these errors were encountered: