关于传输协议 gRPC 的一些疑惑,望解答。
最近看到一个关于主动探测“23 3 3”相关的 issue ,在社区目前还未有结论时,想先暂时切换到 gRPC 模式使用。但现在有几个疑问如下,望大家解惑。
问题 1:gRPC 模式下带宽跑不起来
首先不得不说 gRPC 传输协议相比其他协议,握手响应是真滴快!无论什么多图多元素的页面,基本都是秒开。有时恍惚了还以为在使用 IPLC 节点忘记换了。不过遇到了也是唯一的个问题——带宽跑不起来。
有两条线路,分别是电信 500Mb/30Mb 宽带与移动 200Mb 专线,服务器位于美西电信 CN2 GIA 机房。使用 VLESS+xTLS 、 VLESS+TLS 或 VLESS+TLS+WebSocket 时,均能跑满上下行带宽。但是切换到 gRPC 模式后,下行在 50Mb 左右,上行在 5Mb 左右。虽说日常上网看视频什么的足够了,但是觉得这样的带宽表现肯定是“不正常”的。
服务端的配置试过 Nginx:443 --> Xray(gRPC) --> free ;
也试过配置 Xray:443 --> Nginx --> Xray(gRPC) --> free 。
但是没什么区别,还是一样的情况。感觉应该是 Nginx 的配置问题(接下来排查的方向)。
问题 2 :~~关于 Nginx 的配置~~(已解决)
如果不使用 Xray-examples gRPC 配置范例中推荐的 Nginx 参数及值(如下),而使用默认值或其他值时,是否会影响到 gRPC 传输协议工作时的带宽表现?
server {
listen ... so_keepalive=on;
client_header_timeout 1071906480m;
keepalive_timeout 1071906480m;
location /gRPC_name {
client_max_body_size 0;
client_body_timeout 1071906480m;
grpc_read_timeout 1071906480m;
grpc_pass ...
}
}
我的 Nginx 服务器预设值
client_header_timeout 10;
keepalive_timeout 65;
client_max_body_size 8M;
client_body_timeout 10;
问题 3 :~~普通模式与 Multi 模式的区别~~(已解决)
官方文档 GRPCObject 里只提到了“Multi 模式”比“普通模式”有一定的性能提升,但没有描述两者工作方式的差异。希望有人能用几句话简单概括下两者工作方式有什么不同,感谢!
官方文档中提到了使用 Nginx 作反向代理时,普通模式与 Multi 模式需要使用不同的 location path 设置: 普通模式:
location /gRPC_name/Tun {
grpc_pass ...;
}
Multi 模式
location /gRPC_name/TunMulti {
grpc_pass ...;
}
但实际使用中发现 location path 设置为 /gRPC_name 也能工作,想知道其中的具体区别。
location /gRPC_name {
grpc_pass ...;
}
另外,还想再确认下:
- 使用 gRPC 的普通模式时,是否 client.json 中的
"multiMode": false、 nginx.conf 中的location /gRPC_name/Tun、 ~~server.json 中的"multiMode": false~~ 三者缺一不可? - 使用 gRPC 的 Multi 模式时,是否 client.json 中的
"multiMode": true、 nginx.conf 中的location /gRPC_name/TunMulti、 ~~server.json 中的"multiMode": true~~ 三者缺一不可?
目前的配置
client.json
{
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "xxx.com",
"port": 443,
"users": [
{
"id": "UUID-UUID-UUID-UUID",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "grpc",
"security": "tls",
"grpcSettings": {
"serviceName": "gRPC_name",
"multiMode": true
}
}
}
]
}
server.json
{
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "UUID-UUID-UUID-UUID"
}
],
"decryption": "none",
"fallbacks": [
{
"alpn": "h2",
"dest": "/.../h2c.sock",
"xver": 1
},
{
"dest": "/.../default.sock",
"xver": 1
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"alpn": [
"h2",
"http/1.1"
],
"certificates": [
{
"certificateFile": "/.../xxx.com.crt",
"keyFile": "/.../xxx.com.key"
}
]
}
}
},
{
"listen": "/.../grpc.sock",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "UUID-UUID-UUID-UUID"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "grpc",
"grpcSettings": {
"serviceName": "gRPC_name",
"multiMode": true
}
}
}
]
}
nginx.conf
server {
listen unix:/.../default.sock proxy_protocol;
listen unix:/.../h2c.sock http2 proxy_protocol;
server_name xxx.com;
# reverse proxy for gRPC
location /gRPC_name/TunMulti {
grpc_pass unix:/.../grpc.sock;
}
... ...
}
client_max_body_size 不设 0 连接会意外关闭。比如 浏览器下载文件
grpc_read_timeout 不设较大值 Nginx error.log 会有 timeout
client_header_timeout & keepalive_timeout & client_body_timeout 不设较大值,如果 没有数据传输 连接会在 60/75秒 时关闭,客户端会重新连接,反复。
关于部分线路 gRPC 过 Nginx 后 降速问题 可能的原因。 可能是因为 Ngimx 不回复 大量的 h2 ping,而 线路差 需要一直调窗口大小,而调 窗口大小 需要 h2 ping。
location 默认是 模糊匹配。
location = 是全字匹配。
multiMode 默认是 false 即 普通模式( Tun )
关于部分线路 gRPC 过 Nginx 后 降速问题 可能的原因。 可能是因为 Ngimx 不回复 大量的 h2 ping,而 线路差 需要一直调窗口大小,而调 窗口大小 需要 h2 ping。
可以尝试不经过 Nginx。
client_header_timeout&keepalive_timeout&client_body_timeout不设较大值,如果 没有数据传输 连接会在 60/75秒 时关闭,客户端会重新连接,反复。
@xqzr 非常感谢你的回复。 Nginx 服务器有在跑正常 Web 业务,如下的 nginx.conf 参数如果设置为 官方 gRPC 配置范例 中的推荐值 1071906480m ,担心会引起一些不可预知的问题。比如正常的 Web 会话无法及时释放、加重服务器负载之类的。
client_body_timeout 3600;
client_header_timeout 3600;
client_max_body_size 0;
keepalive_timeout 3600;
考虑到正常 Web 业务与“科学”上网兼顾的话,将超时阈值设置为 1 小时,根据您的经验,这样会不会有改善或者还需要设置更大的值?
location默认是 模糊匹配。location =是全字匹配。
谢谢,明白了。
multiMode默认是false即 普通模式(Tun)
gRPC 传输协议要使用性能更好“Multi 模式”,配置是否应该是这样?
client.json > "multiMode": true
nginx.conf > location /gRPC_name/TunMulti or location = /gRPC_name/TunMulti
server.json > "multiMode": true
关于部分线路 gRPC 过 Nginx 后 降速问题 可能的原因。 可能是因为 Ngimx 不回复 大量的 h2 ping,而 线路差 需要一直调窗口大小,而调 窗口大小 需要 h2 ping。
可以尝试不经过 Nginx。
担心 gRPC 服务存在被主动探测的风险。
gRPC 传输协议要使用性能更好“Multi 模式”,配置是否应该是这样? client.json >
"multiMode": truenginx.conf >location /gRPC_name/TunMultiorlocation = /gRPC_name/TunMultiserver.json >"multiMode": true
location /gRPC_name 即可兼容两种模式
gRPC 传输协议要使用性能更好“Multi 模式”,配置是否应该是这样? client.json >
"multiMode": truenginx.conf >location /gRPC_name/TunMultiorlocation = /gRPC_name/TunMultiserver.json >"multiMode": true
location /gRPC_name即可兼容两种模式
(๑•̀ㅂ•́)و✧❤
再多问一句,"multiMode": true 是客户端与服务端都需要设置,还是说服务端自适应(可以不用设置)?
@xqzr 非常感谢你的回复。 Nginx 服务器有在跑正常 Web 业务,如下的 nginx.conf 参数如果设置为 官方 gRPC 配置范例 中的推荐值
1071906480m,担心会引起一些不可预知的问题。比如正常的 Web 会话无法及时释放、加重服务器负载之类的。client_body_timeout 3600; client_header_timeout 3600; client_max_body_size 0; keepalive_timeout 3600;考虑到正常 Web 业务与“科学”上网兼顾的话,将超时阈值设置为 1 小时,根据您的经验,这样会不会有改善或者还需要设置更大的值?
可以尝试新值 https://github.com/XTLS/Xray-examples/blob/97af2eb5ef019b873b899db83ed58f83f8a9796e/VLESS-GRPC/README.md#nginx
再多问一句,
"multiMode": true是客户端与服务端都需要设置,还是说服务端自适应(可以不用设置)?
仅 客户端
担心 gRPC 服务存在被主动探测的风险。
临时试一下 ~没事的吧~
刚才试了下服务端不通过 Nginx 反代而直接监听 443 端口,下行带宽没什么变化还是 50Mb 左右。不过上行带宽提高了,也到 50Mb 左右。看来终端到服务器的 CN2 GIA 线路上使用 gRPC 协议也只能这样子了。
再多问一句,
"multiMode": true是客户端与服务端都需要设置,还是说服务端自适应(可以不用设置)?仅 客户端
明白了,谢谢。
听说 client_body_buffer_size 调大 可以提升 上传速率,可以试试 设为 512k
https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
听说
client_body_buffer_size调大 可以提升 上传速率,可以试试 设为512khttps://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
o( ̄▽ ̄)d 上行速度提升到了接近 20Mb,增幅超过 200% !感谢!
@xqzr 另外 nginx.conf 中监听项的 so_keepalive=on 需要保留吗?
server {
listen ... so_keepalive=on;
...
}
@xqzr 另外 nginx.conf 中监听项的
so_keepalive=on需要保留吗?server { listen ... so_keepalive=on; ... }
需要 不然一堆“死连接”
另外 想了解下 你的 sendfile 值
grep sendfile /etc/nginx/nginx.conf
另外 想了解下 你的
sendfile值grep sendfile /etc/nginx/nginx.conf
sendfile on;
刚才又重新测试了几台不同地区不同线路的服务器。发现使用了 client_body_buffer_size 512k; 之后,客户端下行带宽能从原来的总带宽 15% 提升到 60% 左右;客户端上行带宽能从原来的总带宽 15% 提升到 30% 左右。
@xqzr 另外 nginx.conf 中监听项的
so_keepalive=on需要保留吗?server { listen ... so_keepalive=on; ... }需要 不然一堆“死连接”
因为没有使用端口使用的是 unix domain socket ,也不知道那种用法是对的 -_-''
server {
listen unix:/dev/shm/h2c.sock http2 so_keepalive=on proxy_protocol;
...
}
server {
listen unix:/dev/shm/h2c.sock http2 proxy_protocol so_keepalive=on;
...
}
刚才又重新测试了几台不同地区不同线路的服务器。发现使用了
client_body_buffer_size 512k;之后,客户端下行带宽能从原来的总带宽 15% 提升到 60% 左右;客户端上行带宽能从原来的总带宽 15% 提升到 30% 左右。
thx 想请你帮忙测试一下 把 client_body_buffer_size 替换为 grpc_buffer_size 看看效果
server { listen unix:/dev/shm/h2c.sock http2 so_keepalive=on proxy_protocol; ... }server { listen unix:/dev/shm/h2c.sock http2 proxy_protocol so_keepalive=on; ... }
看漏了...没有监听端口(TCP)的话 不需要 可以去掉
刚才又重新测试了几台不同地区不同线路的服务器。发现使用了
client_body_buffer_size 512k;之后,客户端下行带宽能从原来的总带宽 15% 提升到 60% 左右;客户端上行带宽能从原来的总带宽 15% 提升到 30% 左右。thx 想请你帮忙测试一下 把
client_body_buffer_size替换为grpc_buffer_size看看效果
将 client_body_buffer_size 512k; 替换成了 grpc_buffer_size 512k; ,测了五、六次,平均算下来上下行带宽跟前面测出来的结果差不多:
刚才又重新测试了几台不同地区不同线路的服务器。发现使用了
client_body_buffer_size 512k;之后,客户端下行带宽能从原来的总带宽 15% 提升到 60% 左右;客户端上行带宽能从原来的总带宽 15% 提升到 30% 左右。
@xqzr ~~上面是 Win64 的客户端测试结果;但如果是在软路由 Arm64 平台的客户端测试,下行少到只有总带宽的 10% 左右,上行带宽却翻倍了,能到 50~60% 。~~(失误了,忘记监听全端口了,Speedtest 测速使用的是非常规端口 O(∩_∩)O哈哈~ 实测结果与 Windows 客户端一致。)
将
client_body_buffer_size 512k;替换成了grpc_buffer_size 512k;,测了五、六次,平均算下来上下行带宽跟前面测出来的结果差不多:
辛苦 ~~如果都去掉呢?~~ 我自测 加与不加都差不多 Linux amd64(可能我带宽小)
再多问一句,
"multiMode": true是客户端与服务端都需要设置,还是说服务端自适应(可以不用设置)?仅 客户端
@xqzr 建议更新官方文档 GRPCObject 文档,为 multiMode 描述添加像 idle_timeout 样的描述文字,如“仅需在客户端配置”。
client_body_buffer_size 512k; grpc_buffer_size 512k;
如果都 加上 效果如何?
client_body_buffer_size 512k;grpc_buffer_size 512k;如果都 加上 效果如何?
nginx.conf 添加 client_body_buffer_size 512k; 使用相同测速节点测速三次;(CPU 未满载)
移动 200Mb 专线
- 168 ms / 114.87 Mb / 46.91 Mb
- 173 ms / 118.00 Mb / 60.24 Mb
- 172 ms / 121.60 Mb / 58.99 Mb
电信 500Mb/30Mb 宽带
- 137 ms / 145.53 Mb / 30.14 Mb
- 135 ms / 146.81 Mb / 30.01 Mb
- 138 ms / 139.05 Mb / 29.78 Mb
nginx.conf 添加 client_body_buffer_size 512k; 和 grpc_buffer_size 512k; 使用相同测速节点测速三次。(CPU 未满载)
移动 200Mb 专线(延时变高了,看了下路由,没有直接进到省内的电信 CN2 ,绕路了。)
- 225 ms / 91.94 Mb / 16.27 Mb
- 226 ms / 92.85 Mb / 38.09 Mb
- 226 ms / 95.92 Mb / 58.86 Mb
电信 500Mb/30Mb 宽带
- 137 ms / 149.41 Mb / 29.47 Mb
- 137 ms / 136.87 Mb / 30.14 Mb
- 138 ms / 123.98 Mb / 30.09 Mb
nginx.conf 添加
client_body_buffer_size 512k;使用相同测速节点测速三次;(CPU 未满载)移动 200Mb 专线
- 168 ms / 114.87 Mb / 46.91 Mb
- 173 ms / 118.00 Mb / 60.24 Mb
- 172 ms / 121.60 Mb / 58.99 Mb
电信 500Mb/30Mb 宽带
- 137 ms / 145.53 Mb / 30.14 Mb
- 135 ms / 146.81 Mb / 30.01 Mb
- 138 ms / 139.05 Mb / 29.78 Mb
nginx.conf 添加
client_body_buffer_size 512k;和grpc_buffer_size 512k;使用相同测速节点测速三次。(CPU 未满载)移动 200Mb 专线(延时变高了,看了下路由,没有直接进到省内的电信 CN2 ,绕路了。)
- 225 ms / 91.94 Mb / 16.27 Mb
- 226 ms / 92.85 Mb / 38.09 Mb
- 226 ms / 95.92 Mb / 58.86 Mb
电信 500Mb/30Mb 宽带
- 137 ms / 149.41 Mb / 29.47 Mb
- 137 ms / 136.87 Mb / 30.14 Mb
- 138 ms / 123.98 Mb / 30.09 Mb
感谢!看来 client_body_buffer_size 512k; 很重要 有必要添加
关于部分线路 gRPC 过 Nginx 后 降速问题 可能的原因。 可能是因为 Ngimx 不回复 大量的 h2 ping,而 线路差 需要一直调窗口大小,而调 窗口大小 需要 h2 ping。
可以尝试不经过 Nginx。
@xqzr 你好,想问下目前 Xray 支持设置 window size 吗?
我看软路由 SSR Plus+ 组件设置里有这一项,但是官方文档里没看到有相关的 cvar 介绍。如果支持的话, cvar 是什么?值设置多少合适?