v2ray / v2ray-core

A platform for building proxies to bypass network restrictions.
https://www.v2ray.com/
MIT License
45.24k stars 8.93k forks source link

什么时候能解决cpu99+ 打游戏延迟999ms的问题啊 #2565

Closed 1265578519 closed 4 years ago

1265578519 commented 4 years ago

感觉这个问题都没人关注,很多人都有提出过,我在几年前也说过,,,3年过去了,依旧没有开发者来修复

1265578519 commented 4 years ago

包括这些问题,其实都是这个BUG引起的,其实而不是核心无法利用多核的问题,当然,,v2现在确实是单核心,能多核心运算更好,特别是vps服务器上进行 https://github.com/v2ray/v2ray-core/issues/2548 https://github.com/v2ray/discussion/issues/558

Kylejustknows commented 4 years ago

我估计,开发的朋友,现在都不知道这个Bug出在什么地方,不知道从什么地方开始修。

因为代码看起来没问题;这个问题又挺难复现的。(无法通过访问某个特定网站之类的方法让它准确发生;我服务器上的v2ray进程有时一跑就是几个月不重启,几年了,至今也没见这个问题发生过一次)

我不是否认说没有这个Bug,只是说它之影响一部分特定用户,并且似乎只发生在某些特定平台上,给我感觉更像是针对操作系统平台的“编译器”有某些隐藏的bug,而不像是V2Ray的代码有Bug。

1265578519 commented 4 years ago

这个问题可以轻易百分百复现。。是属于必现。要复现随时都可以进行

Kylejustknows commented 4 years ago

这个问题可以轻易百分百复现。。是属于必现。要复现随时都可以进行

这也是奇怪的地方之一。 你知道v2ray是有人用来开机场的。一个机场服务器连接几百人在用,这几百人连接服务器干啥玩意的都有,却没见机场的进程炸过。

但无论如何,我等会照你另一个帖子写的,开Netch连接CoD Infinite Warfare (我只有这个)玩一会看看(或者你能再给我列几个其它容易炸的游戏)。进程有没有炸我会告诉你,至少我们这样能知道,是属于“某些系统环境下才会出现的问题”还是属于“V2Ray本身处理某些数据流的问题”

zhj9709 commented 4 years ago

客户端使用socks5 udp也会出现cpu占用高的情况

1265578519 commented 4 years ago

@Kylejustknows pubg,这些fps的游戏都百分百必现 @zhj9709 对的。。v2ray提供的s5也是一样会出问题,只要是经过了v2ray就有这毛病

xqzr commented 4 years ago

所以 我直接换$$了

1265578519 commented 4 years ago

等个写代码的大佬提交下代码修复这个毛病

Kylejustknows commented 4 years ago

@Kylejustknows pubg,这些fps的游戏都百分百必现 @zhj9709 对的。。v2ray提供的s5也是一样会出问题,只要是经过了v2ray就有这毛病

我刚刚,顶着200+的延迟(我的服务器允许UDP但不是为游戏优化的)玩了一局COD,一局CSGO,一局Dota2。总共大约2小时。 用的是Netch的进程白名单模式。游戏期间只要死了,我就切出来看一下CPU。

V2ray的进程CPU占用率一直在0%,偶尔跳到2%,但从没超过2%

然后为了测试,用iperf超最大限速收发UDP包(特意制作大量UDP包和大量丢包),在收发UDP包跑满网速的情况下,V2ray的CPU能偶尔才达到5%。

所以我这边情况(win10最新版, i3CPU,Netch+UDP+V2ray),死活就是无法复现V2ray占满CPU的BUG(我不是说没有这个Bug,而是针对v2ray总用户数有几百万的情况下,这个Bug真的可能只有少数用户遇到。开发的朋友也一直不回应这个Bug,估计这个Bug他们也无法复现,就忽视掉了)

能不能看看,你们的机子,是不是有什么对网络流量有审核的部件,大家汇报一下看看有没有共同点?(360有网速监控,QQ管家,xx管家等等都有软件网络流量监控、多数杀毒软件和防火墙对每个软件的网络流量也都有即时扫描和审计,我怀疑某个流量监控或流量统计软件、驱动和V2Ray冲突了)

PS: 顺便说下,Netch里带的Netfilter SDK+ Redirector真是个好东西啊,让windows实现了几乎完美的透明代理,连底层的UWP和系统进程都代理了!我这一试,就直接把用了多年的Proxifier给扔了。

1265578519 commented 4 years ago

在Netch群里,和各种身边朋友,都能轻松正常复现这个问题,而且是百分百复现。不存在无法复现的可能性。包括服务端也能轻松复现相同的问题,不仅仅是客户端 包括Netch开发者,也说了,不要用v2ray来打游戏,甚至说以后要去掉v2ray,免得有人来问cpu延迟这种问题。 至少用v2ray的所有人,都有相同的毛病,是不是你测试有问题?毕竟这是百分百能复现的 @Kylejustknows 随便搜索了下聊天记录,还有大量的聊天记录你可以进Netch群去看,都有讨论过 1 2 3 4

zhj9709 commented 4 years ago

@Kylejustknows pubg,这些fps的游戏都百分百必现 @zhj9709 对的。。v2ray提供的s5也是一样会出问题,只要是经过了v2ray就有这毛病

我刚刚,顶着200+的延迟(我的服务器允许UDP但不是为游戏优化的)玩了一局COD,一局CSGO,一局Dota2。总共大约2小时。 用的是Netch的进程白名单模式。游戏期间只要死了,我就切出来看一下CPU。

V2ray的进程CPU占用率一直在0%,偶尔跳到2%,但从没超过2%

然后为了测试,用iperf超最大限速收发UDP包(特意制作大量UDP包和大量丢包),在收发UDP包跑满网速的情况下,V2ray的CPU能偶尔才达到5%。

所以我这边情况(win10最新版, i3CPU,Netch+UDP+V2ray),死活就是无法复现V2ray占满CPU的BUG(我不是说没有这个Bug,而是针对v2ray总用户数有几百万的情况下,这个Bug真的可能只有少数用户遇到。开发的朋友也一直不回应这个Bug,估计这个Bug他们也无法复现,就忽视掉了)

能不能看看,你们的机子,是不是有什么对网络流量有审核的部件,大家汇报一下看看有没有共同点?(360有网速监控,QQ管家,xx管家等等都有软件网络流量监控、多数杀毒软件和防火墙对每个软件的网络流量也都有即时扫描和审计,我怀疑某个流量监控或流量统计软件、驱动和V2Ray冲突了)

PS: 顺便说下,Netch里带的Netfilter SDK+ Redirector真是个好东西啊,让windows实现了几乎完美的透明代理,连底层的UWP和系统进程都代理了!我这一试,就直接把用了多年的Proxifier给扔了。

我安卓上测试了,不管是用脚本,还是用v2rayNG,用到socks udp时都会出现cpu占用高的问题,我还让人也测试了,同样的问题。#2427

zhj9709 commented 4 years ago

@Kylejustknows pubg,这些fps的游戏都百分百必现 @zhj9709 对的。。v2ray提供的s5也是一样会出问题,只要是经过了v2ray就有这毛病

我刚刚,顶着200+的延迟(我的服务器允许UDP但不是为游戏优化的)玩了一局COD,一局CSGO,一局Dota2。总共大约2小时。 用的是Netch的进程白名单模式。游戏期间只要死了,我就切出来看一下CPU。 V2ray的进程CPU占用率一直在0%,偶尔跳到2%,但从没超过2% 然后为了测试,用iperf超最大限速收发UDP包(特意制作大量UDP包和大量丢包),在收发UDP包跑满网速的情况下,V2ray的CPU能偶尔才达到5%。 所以我这边情况(win10最新版, i3CPU,Netch+UDP+V2ray),死活就是无法复现V2ray占满CPU的BUG(我不是说没有这个Bug,而是针对v2ray总用户数有几百万的情况下,这个Bug真的可能只有少数用户遇到。开发的朋友也一直不回应这个Bug,估计这个Bug他们也无法复现,就忽视掉了) 能不能看看,你们的机子,是不是有什么对网络流量有审核的部件,大家汇报一下看看有没有共同点?(360有网速监控,QQ管家,xx管家等等都有软件网络流量监控、多数杀毒软件和防火墙对每个软件的网络流量也都有即时扫描和审计,我怀疑某个流量监控或流量统计软件、驱动和V2Ray冲突了) PS: 顺便说下,Netch里带的Netfilter SDK+ Redirector真是个好东西啊,让windows实现了几乎完美的透明代理,连底层的UWP和系统进程都代理了!我这一试,就直接把用了多年的Proxifier给扔了。

我安卓上测试了,不管是用脚本,还是用v2rayNG,用到socks udp时都会出现cpu占用高的问题,我还让人也测试了,同样的问题。#2427

而且我那个issue上有个PR Wanted的标签,估计还要等别人提交pr请求吧

Kylejustknows commented 4 years ago

在Netch群里,和各种身边朋友,都能轻松正常复现这个问题,而且是百分百复现。不存在无法复现的可能性。包括服务端也能轻松复现相同的问题,不仅仅是客户端

我不是说没有这个问题,但因为回音壁效应,和你共鸣的都是有这个问题的。但也许有更多的人,没有这个问题所以不回复你,你也不知道。

比如说我,其实很久之前就看到issues里有这个问题,但是在我自己的”小机场“上和各个客户端上,这个问题从来没有出现过,所以就从来没回复、没关心过这个问题。

而且我刚刚玩了几局被骂得很惨的游戏,大致证实了我的个人电脑上这个问题不存在(因为据你说,这个问题应该游戏开始后很快就复现;我差不多玩了两个小时没有出现)

我漏掉两个细节: 1,因为我的v2ray有特殊设置,所以我是自己跑v2ray,然后netch用socks5连接到本地的v2ray端口; 而不是使用netch内置的v2ray; 你那里能否试试? 2, 我突然想起我的路由器有设置每台机器的UDP发包限制,所以我上面测的数据可能不准确,等会我把QoS去掉后再试试UDP发包。

1265578519 commented 4 years ago

1.不管是直接使用netch内置的v2ray 还是netch通过127.0.0.1:10808 s5模式连接到v2rayn客户端,都会存在相同的问题,包括之前群里面有人不信有毛病,他们一测cod,也出现相同的问题了,很明显在fps游戏中,很容易出现这种情况

Kylejustknows commented 4 years ago

1.不管是直接使用netch内置的v2ray 还是netch通过127.0.0.1:10808 s5模式连接到v2rayn客户端,都会存在相同的问题,包括之前群里面有人不信有毛病,他们一测cod,也出现相同的问题了,很明显在fps游戏中,很容易出现这种情况

行,我再跑一局COD试试看。 另,UDP转发可能是有问题。我刚刚解除了QoS限制,测试海量发UDP包,V2Ray短暂地跳到30%CPU,然后就冰冻住了,直到连接超时。不一定和你的游戏是同一个Bug,但我觉得V2ray的UDP部分应该有一些不显著的Bug。

1265578519 commented 4 years ago

跳到30%CPU

你是4核心的吗?4核心利用一个核心的话,大约就在25%左右浮动,可能是同一个问题引起

Kylejustknows commented 4 years ago

跳到30%CPU

你是4核心的吗?4核心利用一个核心的话,大约就在25%左右浮动,可能是同一个问题引起

所见略同。当它跳到30%的时候,任务管理器正好在记录中,我赶紧看了一眼,那30%的峰值,是平均分配到4个核心。(电脑CPU核心4个逻辑核心都在30%左右)但V2ray的CPU使用和连接方式有关

但经过一波测试,我感觉我找到一些出错逻辑:

1,UDP瞬间发包数,当我把发包数限制为10的时候,测试总能通过。默认值发包(每秒120个UDP包左右)都产生高CPU然后失败了。(UDP数据包数量超过V2ray的vmess协议能瞬间处理的数量?) 2, 只要失败了,下面的所有UDP测试都数据挂起;重启V2ray后又能再联通。(但是在挂起的期间,我的CPU并没有持续飙高,就是不传输UDP数据了,V2ray也不显示任何错误)

1265578519 commented 4 years ago

任务管理器正好在记录中,我赶紧看了一眼,那30%的峰值,是平均分配到4个核心。(电脑CPU核心4个逻辑核心都在30%左右)

这个是Windows 10的线程优化。实际上还是单核心运行的。解决这个问题的终点不是让他利用更多的核心,而是想办法解决问题所在,让其不占用CPU,对比下ss-lbev,人家占用不超过0.5%的cpu,内存也才5MB

1265578519 commented 4 years ago

@Kylejustknows 你会写代码吗,要不要提交写修复这毛病啊

1265578519 commented 4 years ago

1 每天都有不同的人来说v2延迟问题。

hyxxsfwy commented 4 years ago

把客户端换成 Clash 试试看

1265578519 commented 4 years ago

Clash是gui还是?用的不是v2ray核心?

hyxxsfwy commented 4 years ago

Clash是gui还是?用的不是v2ray核心?

Clash 用的是自己的核心,Clash Core. Clash for Windows 也支持用 OpeVPN 的 TAP 驱动实现全局 VPN.

1265578519 commented 4 years ago

https://github.com/Dreamacro/clash/releases 这个吗?我看了下介绍,用的是v2ray的核心,不是他们自己开发的 image

hyxxsfwy commented 4 years ago

https://github.com/Dreamacro/clash/releases 这个吗?我看了下介绍,用的是v2ray的核心,不是他们自己开发的 image

你可以选择看看代码,或者装上客户端亲自试一试,而不是只看 Readme 里的鸣谢。

Lightmani commented 4 years ago

在我的Win10Pro+Netch 1.4.9的试验下,一局10分钟的CSGO,游戏中显示的延迟大概在62-70之间波动,和我节点本身的延迟并没有太大区别.

由于我没有COD,所以无法测试.但是我在GTAV,CSGO,彩虹六号中也从未遇到过CPU占用满的问题. 只有在彩虹六号里延迟比较高到了120ms....可能是因为我的节点比较垃圾吧...

所以我觉得这个问题是CoD的个例,就我本人的游戏体验来看,从未遇到过类似情况

Kylejustknows commented 4 years ago

在我的Win10Pro+Netch 1.4.9的试验下,一局10分钟的CSGO,游戏中显示的延迟大概在62-70之间波动,和我节点本身的延迟并没有太大区别.

由于我没有COD,所以无法测试.但是我在GTAV,CSGO,彩虹六号中也从未遇到过CPU占用满的问题. 只有在彩虹六号里延迟比较高到了120ms....可能是因为我的节点比较垃圾吧...

所以我觉得这个问题是CoD的个例,就我本人的游戏体验来看,从未遇到过类似情况

据我现在的经验,它和发包率有一些关系。Steam平台的游戏以较低的30pps速度发UDP包在config文件内可调,PUBG和CoD没有公开数据,但我估计为了体验可能用了超高的发包率。我自以为我的电脑没有这个bug,但当我用测试软件每秒100个UDP包发送时,我的V2ray也假死了。

问题不在于该不该玩Cod或者用Netch,关键在于,一个代理软件,你对它发送好的、坏的、大的、小的、扭曲的、合法不合法。。。的各种数据包,它都应该能合理地处理(该转发的转发,该抛弃的抛弃)。而不应该遇到自己不喜欢的数据包就立刻死给你看。

Kylejustknows commented 4 years ago

Clash是gui还是?用的不是v2ray核心?

Clash 用的是自己的核心,Clash Core. Clash for Windows 也支持用 OpeVPN 的 TAP 驱动实现全局 VPN.

应该是没用的。我这两天有空时在测试和研究怎样准确地触发这个Bug。 Netfilter来转发UDP或者SSTAP全局VPN都会触发这个Bug都试过。这个Bug和UDP数据流的“内容”有关,而与你用什么软件、什么方法把数据传给V2ray无关。

ghost commented 4 years ago

(声明:本人萌新+小白,若有纰漏,还望各位大佬海涵。) 这是一个socks中对于UDP连接的一个bug: (v2ray-core/proxy/socks/server.go line213-245)

for { 
    mpayload, err := reader.ReadMultiBuffer() 
    ... ...
    for _, payload := range mpayload { 
        ... ...
        if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() { 
            ctx = log.ContextWithAccessMessage(ctx,... ...) 
        } 
        ctx = protocol.ContextWithRequestHeader(ctx, request) 
        ... ...
    }
} 

首先,v2ray会对每一个socks连接建立一个Context(ctx),并对其添加几个Value(例如ID): https://github.com/v2ray/v2ray-core/blob/f9935d0e93eacb62df9ea9d47db685ec1d25c102/app/proxyman/inbound/worker.go#L289 对于socksClient发来的每一个UDP包,v2ray都会对ctx进行log.ContextWithAccessMessage()protocol.ContextWithRequestHeader()操作。这两个函数本质上是Context.WithValue()Context.WithValue()相关代码:

func WithValue(parent Context, key, val interface{}) Context {
    if key == nil {
        panic("nil key")
    }
    if !reflectlite.TypeOf(key).Comparable() {
        panic("key is not comparable")
    }
    return &valueCtx{parent, key, val}
}

socksClient发来的UDP包很多时,存放IDvalueCtx就是当前ctx的子n代ctx,这时从ctx中获取ID对应的Value就会极为困难:

func (c *valueCtx) Value(key interface{}) interface{} {
    if c.key == key {
        return c.val
    }
    return c.Context.Value(key)
}

ctx.Value()被调用时,ctx会疯狂调用子代的ctx.Value(),产生巨大的CPU消耗;同时,大量子代ctx占用大量的内存,与 @1265578519 的issue中的描述类似。

1265578519 commented 4 years ago

@JimHan75d8c5 感谢分析,如果是这个问题的话,不知道好修不?

ghost commented 4 years ago

应该挺好修的,在 log.ContextWithAccessMessage()protocol.ContextWithRequestHeader()里面加个判断就行🙃 🙃🙃🙃

1265578519 commented 4 years ago

@kslr 这位开发者,麻烦进来帮看看,上面有人发了修复方案

AmazingDM commented 4 years ago

image

lylyo commented 4 years ago

在我的Win10Pro+Netch 1.4.9的试验下,一局10分钟的CSGO,游戏中显示的延迟大概在62-70之间波动,和我节点本身的延迟并没有太大区别. 由于我没有COD,所以无法测试.但是我在GTAV,CSGO,彩虹六号中也从未遇到过CPU占用满的问题. 只有在彩虹六号里延迟比较高到了120ms....可能是因为我的节点比较垃圾吧... 所以我觉得这个问题是CoD的个例,就我本人的游戏体验来看,从未遇到过类似情况

据我现在的经验,它和发包率有一些关系。Steam平台的游戏以较低的30pps速度发UDP包在config文件内可调,PUBG和CoD没有公开数据,但我估计为了体验可能用了超高的发包率。我自以为我的电脑没有这个bug,但当我用测试软件每秒100个UDP包发送时,我的V2ray也假死了。

问题不在于该不该玩Cod或者用Netch,关键在于,一个代理软件,你对它发送好的、坏的、大的、小的、扭曲的、合法不合法。。。的各种数据包,它都应该能合理地处理(该转发的转发,该抛弃的抛弃)。而不应该遇到自己不喜欢的数据包就立刻死给你看。

请问用的什么测试软件

Kylejustknows commented 4 years ago

在我的Win10Pro+Netch 1.4.9的试验下,一局10分钟的CSGO,游戏中显示的延迟大概在62-70之间波动,和我节点本身的延迟并没有太大区别. 由于我没有COD,所以无法测试.但是我在GTAV,CSGO,彩虹六号中也从未遇到过CPU占用满的问题. 只有在彩虹六号里延迟比较高到了120ms....可能是因为我的节点比较垃圾吧... 所以我觉得这个问题是CoD的个例,就我本人的游戏体验来看,从未遇到过类似情况

据我现在的经验,它和发包率有一些关系。Steam平台的游戏以较低的30pps速度发UDP包在config文件内可调,PUBG和CoD没有公开数据,但我估计为了体验可能用了超高的发包率。我自以为我的电脑没有这个bug,但当我用测试软件每秒100个UDP包发送时,我的V2ray也假死了。 问题不在于该不该玩Cod或者用Netch,关键在于,一个代理软件,你对它发送好的、坏的、大的、小的、扭曲的、合法不合法。。。的各种数据包,它都应该能合理地处理(该转发的转发,该抛弃的抛弃)。而不应该遇到自己不喜欢的数据包就立刻死给你看。

请问用的什么测试软件

iperf3 , 自定义参数 -u 打开UDP测试;-l 每个UDP包大小(数字后要加上K或者多少M);-b每秒传输数据量(也要数字加K); 这两个参数组合,就可以设计出各种大小、每秒各种数量的测试包。 或者用-k参数加个数字,意思是一次性送出多少个包。

测试时一旦遇到假死数据中断,服务器那边就会等很久很久很久才会放弃,所以记得远程连上服务器随时重启服务端。

lylyo commented 4 years ago

在我的Win10Pro+Netch 1.4.9的试验下,一局10分钟的CSGO,游戏中显示的延迟大概在62-70之间波动,和我节点本身的延迟并没有太大区别. 由于我没有COD,所以无法测试.但是我在GTAV,CSGO,彩虹六号中也从未遇到过CPU占用满的问题. 只有在彩虹六号里延迟比较高到了120ms....可能是因为我的节点比较垃圾吧... 所以我觉得这个问题是CoD的个例,就我本人的游戏体验来看,从未遇到过类似情况

据我现在的经验,它和发包率有一些关系。Steam平台的游戏以较低的30pps速度发UDP包在config文件内可调,PUBG和CoD没有公开数据,但我估计为了体验可能用了超高的发包率。我自以为我的电脑没有这个bug,但当我用测试软件每秒100个UDP包发送时,我的V2ray也假死了。 问题不在于该不该玩Cod或者用Netch,关键在于,一个代理软件,你对它发送好的、坏的、大的、小的、扭曲的、合法不合法。。。的各种数据包,它都应该能合理地处理(该转发的转发,该抛弃的抛弃)。而不应该遇到自己不喜欢的数据包就立刻死给你看。

请问用的什么测试软件

iperf3 , 自定义参数 -u 打开UDP测试;-l 每个UDP包大小(数字后要加上K或者多少M);-b每秒传输数据量(也要数字加K); 这两个参数组合,就可以设计出各种大小、每秒各种数量的测试包。 或者用-k参数加个数字,意思是一次性送出多少个包。

测试时一旦遇到假死数据中断,服务器那边就会等很久很久很久才会放弃,所以记得远程连上服务器随时重启服务端。

好的,感谢提示。

xiaokangwang commented 4 years ago

(声明:本人萌新+小白,若有纰漏,还望各位大佬海涵。) 这是一个socks中对于UDP连接的一个bug: (v2ray-core/proxy/socks/server.go line213-245)

for { 
  mpayload, err := reader.ReadMultiBuffer() 
  ... ...
  for _, payload := range mpayload { 
      ... ...
      if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() { 
          ctx = log.ContextWithAccessMessage(ctx,... ...) 
      } 
      ctx = protocol.ContextWithRequestHeader(ctx, request) 
      ... ...
  }
} 

首先,v2ray会对每一个socks连接建立一个Context(ctx),并对其添加几个Value(例如ID):

https://github.com/v2ray/v2ray-core/blob/f9935d0e93eacb62df9ea9d47db685ec1d25c102/app/proxyman/inbound/worker.go#L289

对于socksClient发来的每一个UDP包,v2ray都会对ctx进行log.ContextWithAccessMessage()protocol.ContextWithRequestHeader()操作。这两个函数本质上是Context.WithValue()Context.WithValue()相关代码:

func WithValue(parent Context, key, val interface{}) Context {
  if key == nil {
      panic("nil key")
  }
  if !reflectlite.TypeOf(key).Comparable() {
      panic("key is not comparable")
  }
  return &valueCtx{parent, key, val}
}

socksClient发来的UDP包很多时,存放IDvalueCtx就是当前ctx的子n代ctx,这时从ctx中获取ID对应的Value就会极为困难:

func (c *valueCtx) Value(key interface{}) interface{} {
  if c.key == key {
      return c.val
  }
  return c.Context.Value(key)
}

ctx.Value()被调用时,ctx会疯狂调用子代的ctx.Value(),产生巨大的CPU消耗;同时,大量子代ctx占用大量的内存,与 @1265578519 的issue中的描述类似。

我尝试修修看看 https://github.com/v2fly/v2ray-core/commit/73616ab9e221850a278bd902e9cd8d759a72553f

zhj9709 commented 4 years ago

(声明:本人萌新+小白,若有纰漏,还望各位大佬海涵。) 这是一个socks中对于UDP连接的一个bug: (v2ray-core/proxy/socks/server.go line213-245)

for { 
    mpayload, err := reader.ReadMultiBuffer() 
    ... ...
    for _, payload := range mpayload { 
        ... ...
        if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() { 
            ctx = log.ContextWithAccessMessage(ctx,... ...) 
        } 
        ctx = protocol.ContextWithRequestHeader(ctx, request) 
        ... ...
    }
} 

首先,v2ray会对每一个socks连接建立一个Context(ctx),并对其添加几个Value(例如ID): https://github.com/v2ray/v2ray-core/blob/f9935d0e93eacb62df9ea9d47db685ec1d25c102/app/proxyman/inbound/worker.go#L289

对于socksClient发来的每一个UDP包,v2ray都会对ctx进行log.ContextWithAccessMessage()protocol.ContextWithRequestHeader()操作。这两个函数本质上是Context.WithValue()Context.WithValue()相关代码:

func WithValue(parent Context, key, val interface{}) Context {
    if key == nil {
        panic("nil key")
    }
    if !reflectlite.TypeOf(key).Comparable() {
        panic("key is not comparable")
    }
    return &valueCtx{parent, key, val}
}

socksClient发来的UDP包很多时,存放IDvalueCtx就是当前ctx的子n代ctx,这时从ctx中获取ID对应的Value就会极为困难:

func (c *valueCtx) Value(key interface{}) interface{} {
    if c.key == key {
        return c.val
    }
    return c.Context.Value(key)
}

, 当ctx.Value()被调用时,ctx会疯狂调用子代的ctx.Value(),产生巨大的CPU消耗;同时,大量子代ctx占用大量的内存,与 @1265578519 的issue中的描述类似。

我尝试修修看看 v2fly@73616ab

安卓上用iperf3测试了一下,cpu占用好像正常了,之前测试cpu占用可以在50%以上,现在最多也就5-6%左右 等其他人再测试看看

zhj9709 commented 4 years ago

(声明:本人萌新+小白,若有纰漏,还望各位大佬海涵。) 这是一个socks中对于UDP连接的一个bug: (v2ray-core/proxy/socks/server.go line213-245)

for { 
    mpayload, err := reader.ReadMultiBuffer() 
    ... ...
    for _, payload := range mpayload { 
        ... ...
        if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() { 
            ctx = log.ContextWithAccessMessage(ctx,... ...) 
        } 
        ctx = protocol.ContextWithRequestHeader(ctx, request) 
        ... ...
    }
} 

首先,v2ray会对每一个socks连接建立一个Context(ctx),并对其添加几个Value(例如ID): https://github.com/v2ray/v2ray-core/blob/f9935d0e93eacb62df9ea9d47db685ec1d25c102/app/proxyman/inbound/worker.go#L289

对于socksClient发来的每一个UDP包,v2ray都会对ctx进行log.ContextWithAccessMessage()protocol.ContextWithRequestHeader()操作。这两个函数本质上是Context.WithValue()Context.WithValue()相关代码:

func WithValue(parent Context, key, val interface{}) Context {
    if key == nil {
        panic("nil key")
    }
    if !reflectlite.TypeOf(key).Comparable() {
        panic("key is not comparable")
    }
    return &valueCtx{parent, key, val}
}

socksClient发来的UDP包很多时,存放IDvalueCtx就是当前ctx的子n代ctx,这时从ctx中获取ID对应的Value就会极为困难:

func (c *valueCtx) Value(key interface{}) interface{} {
    if c.key == key {
        return c.val
    }
    return c.Context.Value(key)
}

ctx.Value()被调用时,ctx会疯狂调用子代的ctx.Value(),产生巨大的CPU消耗;同时,大量子代ctx占用大量的内存,与 @1265578519 的issue中的描述类似。

我尝试修修看看 v2fly@73616ab

另一部手机测试了一下,虽然cpu占用好很多,但还是有点高

1265578519 commented 4 years ago

感谢楼上大佬提交PR,等版本发布好进行测试,不会编译,只能等现成的

zhj9709 commented 4 years ago

感谢楼上大佬提交PR,等版本发布好进行测试,不会编译,只能等现成的

我编译一份发给你试试

kslr commented 4 years ago

感谢楼上大佬提交PR,等版本发布好进行测试,不会编译,只能等现成的

https://github.com/v2fly/V2FlyBleedingEdgeBinary/releases/tag/unstable-3e13d79af700f667a8663c6f1e62a9e3d9b0558a

Lightmani commented 4 years ago

在我的Win10Pro+Netch 1.4.9的试验下,一局10分钟的CSGO,游戏中显示的延迟大概在62-70之间波动,和我节点本身的延迟并没有太大区别. 由于我没有COD,所以无法测试.但是我在GTAV,CSGO,彩虹六号中也从未遇到过CPU占用满的问题. 只有在彩虹六号里延迟比较高到了120ms....可能是因为我的节点比较垃圾吧... 所以我觉得这个问题是CoD的个例,就我本人的游戏体验来看,从未遇到过类似情况

请问v2ray什么协议能玩彩虹六号?tls + websocket + socks5,测试出fullcone,但是游戏都连不上

Vmess+Ws+TLS 这个和协议的关系不大吧?建议检查下落地机和本地环境

604909288 commented 4 years ago

感谢楼上大佬提交PR,等版本发布好进行测试,不会编译,只能等现成的

https://github.com/v2fly/V2FlyBleedingEdgeBinary/releases/tag/unstable-3e13d79af700f667a8663c6f1e62a9e3d9b0558a

这个是测试版的链接吗

1265578519 commented 4 years ago

测试了,还是没修复,不过确实有一定好转了。不过问题还存在。之前不到10分钟必爆炸的,现在能撑住20-25分钟左右才出问题,打游戏依旧还是能百分百复现这个问题 麻烦大佬们在看看代码哪里能优化吧

604909288 commented 4 years ago

测试了,还是没修复,不过确实有一定好转了。不过问题还存在。之前不到10分钟必爆炸的,现在能撑住20-25分钟左右才出问题 麻烦大佬们在看看代码哪里能优化吧

我这边感觉好多了,两个小时了,很稳定,就百分之2以下不涨了,之前一个小时就爆了

Kylejustknows commented 4 years ago

测试了。情况好转了非常多!

但看来这里有不止一个Bug.....

第一个Bug, UDP狂发包时CPU占满问题,基本解决了,CPU怎么轰炸都不会超过5%!

修正,第二个Bug,在我把服务器端也升级成测试版后,也好了!再也没遇到过。 image

每秒发超过2000个UDP包时,才开始偶尔丢包。性能非常强悍!CPU一直没超过6%。 这个BUG就这么修好了!V2ray可以正式做为游戏的主流代理软件来使用了。 建议尽快发布正式的新版更新。

第二个Bug, UDP假死问题,还是存在(Iperf跑几遍就能遇到)

主要错误显示是:v2ray.com/core/transport/internet/udp: failed to handle UDP input > io: read/write on closed pipe 这一行错误显示的瞬间,就假死了。 最麻烦的是,当假死发生后,这个UDP连接不会断掉、不会重联,而是永远保持着若有若无的连接(等了5分钟都没断,我猜如果在游戏里,就会显示999ms+的给人感觉已断网,但软件又显示没彻底断网的状况)

一直到软件关闭或者强行放弃这条UDP连接时,V2ray才会显示一条: v2ray.com/core/app/proxyman/inbound: connection ends > read tcp 127.0.0.1:1081->127.0.0.1:59585: wsarecv: An existing connection was forcibly closed by the remote host.

604909288 commented 4 years ago

大佬们牛逼,🙏🙏

1265578519 commented 4 years ago

测试了。情况好转了非常多!

但看来这里有不止一个Bug.....

第一个Bug, UDP狂发包时CPU占满问题,基本解决了,CPU怎么轰炸都不会超过5%!

第二个Bug, UDP假死问题,还是存在(Iperf跑几遍就能遇到)

主要错误显示是:v2ray.com/core/transport/internet/udp: failed to handle UDP input > io: read/write on closed pipe 这一行错误显示的瞬间,就假死了。 最麻烦的是,当假死发生后,这个UDP连接不会断掉、不会重联,而是永远保持着若有若无的连接(等了5分钟都没断,我猜如果在游戏里,就会显示999ms+的给人感觉已断网,但软件又显示没彻底断网的状况)

一直到软件关闭或者强行放弃这条UDP连接时,V2ray才会显示一条: v2ray.com/core/app/proxyman/inbound: connection ends > read tcp 127.0.0.1:1081->127.0.0.1:59585: wsarecv: An existing connection was forcibly closed by the remote host. 才结束。

可能你说的第二个问题,也会引起CPU100%。。。我这能出现 服务端我刚测了,使用vmess协议依然有问题。 包括用v2ray内置的ss,也会出现日志文件显示的和你类似。 然后一段时间后CPU直接冲到99%然后就卡死了。 内置的ss和使用v2ray vmess协议一样有相同的毛病

Kylejustknows commented 4 years ago

可能你说的第二个问题,也会引起CPU100%。。。我这能出现 服务端我刚测了,用v2ray内置的ss,也会出现日志文件显示的和你类似。然后一段时间后CPU直接冲到99%然后就卡死了。内置的ss和使用v2ray协议一样有相同的毛病

把你贴的日志文件精简一下,太长了,重复的留几行就行了。 第二个问题,我刚开始测试的时候只有本地客户端用了测试版,才出现 几分钟后,我把服务器那边的v2ray也升级了,然后就再也无法复现第二个Bug。

现在我打字的同时,我的服务器和客户端正在以每秒2000个UDP包的速度同时上传+下载,不停地跑,稳定的一笔。

你贴的日志,看起来像是shadowsocks组件出的问题。可否换回成vmess试试?现在修复后vmess的UDP性能可能比Shadowsocks协议更强悍了。