-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: