V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 22 页 / 共 62 页
回复总数  1238
1 ... 18  19  20  21  22  23  24  25  26  27 ... 62  
2023-09-14 00:36:47 +08:00
回复了 shaoyie 创建的主题 程序员 c++多线程实现反向代理 QPS 达到 Haproxy/Nginx 的 3 倍
#115

man 手册离的是那是 `The suggested way`, 因为 ET 数据没读完、没有新数据到来是不会再触发可读的、如果用户解析处理逻辑有 bug 并且不继续读和处理就可能僵尸连接了。
但请你看清楚,那 `You must do it`,所以 `必须要读到返回 errno=EAGAIN` 这说法也是不准确的。

->

man 手册里的那是 `The suggested way`, 因为 ET 数据没读完、没有新数据到来是不会再触发可读的、如果用户解析处理逻辑有 bug 并且不继续读和处理就可能僵尸连接了。
但请你看清楚,那不是 `You must do it`,没人强迫你必须读到 EAGAIN ,也不是只有 event loop 里才能进行读、其他地方就不能读了,所以 `必须要读到返回 errno=EAGAIN` 这说法也是不准确的。
2023-09-14 00:33:19 +08:00
回复了 shaoyie 创建的主题 程序员 c++多线程实现反向代理 QPS 达到 Haproxy/Nginx 的 3 倍
> 1. man 7 epoll 说的很清楚
> The suggested way to use epoll as an edge-triggered (EPOLLET) interface is as follows:
> a) with nonblocking file descriptors; and
> b) by waiting for an event only after read(2) or write(2) return EAGAIN.
> 你必须要读到返回 errno=EAGAIN ,如果我是水平模式,不没必要

> 2. 你这属于抬杠,在多少情况是 socket 缓冲区暴满了?要考虑大部分情况的代码分支走向
> 1 )程序处理的慢,读不过来,堆积了
> 2 )业务类型就是客户端不停的 send (也得看处理的快慢)
> 这都不是关键问题,多路复用同步的读取 你可以把 recv buf 搞得很大,因为它是共享的,不存在浪费内存的问题。

你好像没看懂我在说什么,我说的是你当前这个 LT 单次 event 不读完的实现,与 ET 单次读完的区别,我没说你 bug 啊也没说你一定需要读完啊,你再看下 #111

> 你这属于抬杠,在多少情况是 socket 缓冲区暴满了?要考虑大部分情况的代码分支走向

单次读完相比于你当前的 LT 单次不一定读完,也并不多浪费什么代码,也就循环里多个 if EAGAIN 的判断。而且我也没说必须这样做,只是分析你的 LT 实现与 ET 的区别,没说你这个实现就影响性能了或是怎么样,而是说 `这样未必最优`,我可不是说你这样一定不如单次读完啊。

你这么容易觉得我在抬杠,没必要。人在觉得发现新大陆、搞了大进步的时候最容易自我陶醉、也最容易听不进去跟自己不同的观点,很正常。
你可以先让自己冷静下来再看看,或许能吸收些新东西。


另外:
> 你必须要读到返回 errno=EAGAIN

并不是必须这样的,自己想做流控的话,可以自行选择读多少、什么时候继续读,比如 golang ,有数据来了 net.TCPConn 就可读,但是你应用层没有调用 net.TCPConn.Read 也没关系啊,你什么时候想读直接能读就醒了,如果当前没数据不可读、阻塞在那等 runtime event 来了唤醒就可以了

man 手册离的是那是 `The suggested way`, 因为 ET 数据没读完、没有新数据到来是不会再触发可读的、如果用户解析处理逻辑有 bug 并且不继续读和处理就可能僵尸连接了。
但请你看清楚,那 `You must do it`,所以 `必须要读到返回 errno=EAGAIN` 这说法也是不准确的。


> 另外,我回复中写的是 EAGAIN ,不是 EINTER 。

我上面说的不是你回复其他人的 EAGAIN ,而是说你源码中的这块,我上面漏贴了代码链接:
https://github.com/shaovie/niubix/blob/main/src/io_handle.cpp#L24

> 3. 是不完整,我惊讶的是给我的性能发挥空间还很大啊,如果只是性能超过 haproxy 20%,那我就没啥好惊讶的,等我完善 完善 可能这 20%就被抹平了

那可以惊讶的事情可真是太多了,你继续加油提高性能天花板吧

> 我说的读的情况多一次 syscall ,指的是 read ,不是 epoll_ctl

读的时候,ET 怎么就可能比 LT 多一次 syscall 了呢?同样一次读事件到来,同样的 read buf 。
你是不是又搞混了什么。。
2023-09-13 23:02:16 +08:00
回复了 shaoyie 创建的主题 程序员 c++多线程实现反向代理 QPS 达到 Haproxy/Nginx 的 3 倍
#111 编辑的时候窜行了,更正下

> 这个可能不太准确:Edo while 条件+ONESHOT 需要重新添加事件,这种才会需要更多 syscall ,如果都是单次读完当前数据的话,ET 和 LT 是一样的。

更正为:

> 这个可能不太准确:ET+ONESHOT 需要重新添加事件,这种才会需要更多 syscall ,如果都是单次读完当前数据的话,ET 和 LT 是一样的。
2023-09-13 22:40:38 +08:00
回复了 shaoyie 创建的主题 程序员 c++多线程实现反向代理 QPS 达到 Haproxy/Nginx 的 3 倍
@shaoyie #97

> 减少 syscall 次数,而且有了这个前提 大部分情况 ET 模式反而会浪费一次 syscall

这个可能不太准确:Edo while 条件+ONESHOT 需要重新添加事件,这种才会需要更多 syscall ,如果都是单次读完当前数据的话,ET 和 LT 是一样的。

> 而在水平模式下,读出来的数量小于你的 buf 长度 就可以了,不需要再尝试一次

除非你的读 buf 长度大于 socket 设置的读缓冲区 size ,否则不管 ET 还是 LT ,读本身是没法保障单次读出来的数量小于 buf 长度的,因为有可能 socket 读缓冲区数据量大于读 buf 长度

这里的 do while 条件也不是尽量读完,例如 socket 读缓冲区有 33k 数据,buf 是 32k ,本次读到 32k ,则不满足你的 (ret == -1 && errno == EINTR) 条件。
但这也不能算 bug ,因为你默认用的是 LT ,即使本次没读完、下一轮 event loop 也会继续触发读,只是相比于单次读完,这样需要内核在下一轮 event loop 继续派发可读事件、这样未必最优。

> 庆幸,昨晚程序能跑起来后我就第一时间做了对比测试,数据很惊讶

niubix 实现的功能本身就不是完整 http 相关功能、比 nginx 、haproxy 的逻辑少很多,所以比它们快也应该是意料之中,OP 为此惊讶这件事让我感到狠惊讶!
2023-09-13 17:24:54 +08:00
回复了 shaoyie 创建的主题 程序员 c++多线程实现反向代理 QPS 达到 Haproxy/Nginx 的 3 倍
@shaoyie #85

1/3/4: 既然是这样,就不要用 qps x3 nginx 、haproxy 这种标题了,完全没有可比性,至少标题指明用于特定场景优化会好些。
nginx 的行业地位比自定制的玩具 demo 稳多了,这样标题、大家看了第一感觉就是你在碰瓷 nginx 、吹牛+踩 nginx 弱鸡,就像突然蹦出个民科一顿言论吊打数学家科学家一样。
goev 的帖子也是如此。

> 2. splice 是限于 pipe 。ZEROCOPY 是异步的增加复杂度了,buf 机制也要改,整体提升非常有限

按现在的功能,如果只是转发 backend 给 client ,应该不需要改太多
2023-09-13 16:34:37 +08:00
回复了 shaoyie 创建的主题 程序员 c++多线程实现反向代理 QPS 达到 Haproxy/Nginx 的 3 倍
简单扫了几眼代码,没全看,大概明白为啥 niubix 性能这么高了,只扫了几分钟、不保证我说的是准确的,如果有误,OP 和各位多多指正。

1. 对 client 端请求的处理
https://github.com/shaovie/niubix/blob/main/src/http_conn.cpp#L168
这里的 http request 处理,目测似乎并没有做完整的 http 协议解析所以也没有请求合法性校验之类的,也没有 nginx 那些完善的对请求进行中间处理的功能,主要是添加 realip/x-forward-for

2. 对 backend 端的处理
https://github.com/shaovie/niubix/blob/main/src/backend_conn.cpp#L74
看这里是对 backend 读取到的数据直接转发给 client 、没有进行 http 协议的中间处理。但 nginx 是有处理功能的、比如开了 gzip ,backend 没开 gzip ,nginx 是会自己加上 gzip 逻辑的,也包括其他通用功能的处理。
另外啊,如果只是需要盲转发数据,其实用 splice 这种 zero copy 的 syscall 性能更好。

所以综合下来看,相比于 nginx 完善的功能,niubix 目前版本对 client 、backend 的处理都是功能不完善的、还属于 demo 级代码,或许适用于自家特定业务的优化,不适合作为通用功能的反代。

这种 demo 级的测试,跟商业级稳定大项目来对比性能本身就是不合理的,就像我之前给 OP 说的那样:拿不完整功能的 http server 去参加 TechEmpower Plaintext 没意义。
@mengdodo #14 网页回复随便打打字,见笑了,我下次注意!😋😋
@assiadamo #12

游戏的单服务在线量不会太大,举几个例子:
1. MMORPG 同屏/同地图 CPU 计算量大、通常要分区限制单个区人数,所以单个游戏服在线也不会很大
2. MOBA/FPS 类也是 CPU 计算量大但没有大地图的广播消耗,单局游戏/单个房间也是玩家数量不大、最多也就 10 个、几十个,所以战斗服务器横向扩展堆机器就够用了
3. 反倒是那些轻量游戏,比如休闲类的、弱单机轻状态的游戏,玩家之间的互动性较少,也是可以横向扩容堆机器,但是这种对 CPU 消耗不高,所以如果用 Poller 来节省协程数量的话,单个服务能承载很多玩家在线、节省服务器软硬件资源


所以除非是做上面的 3 中这一类,否则单个游服没多大在线量。普通在线量的场景,自己搞 epoll 这些框架的响应性能并不如标准库方案,因为通常需要 IO 与逻辑协程分离,跨协程的变量逃逸、变量生命周期不容易 pool 复用优化,还有其他一些细节,各种因素加起来,响应性能不如标准库方案。
所以如果只是为了游戏服务性能、并且不是上面的 3 ,建议 OP 不用研究这个问题了,自己感兴趣倒是可以继续深入
2023-09-11 22:03:35 +08:00
回复了 Hystrix13 创建的主题 程序员 裸辞一年且饿不死健身是否可行?
建议前半年报健身班+考证,后半年直接入职健身教练,健身、工作两不误,一年后如果收入不行再考虑换工作
绝大多数人处理的连接数都不算大、用标准库足够了。

@coderxy #3
@voidmnwzp #7
少量人需要处理海量连接、节约硬件、提高服务稳定性,nbio 简单压测 4c2g 跑 10w qps
https://www.v2ex.com/t/945827
标准库方案,差不多得 10g 左右内存了,cpu 核心数也得多些否则 gc 压力大、stw 不友好、稳定性低

另外 nbio 本身支持 http 、websocket 的连接采用标准库 Conn 、阻塞模式,只是用 nbio 的解析器,性能好、占用平衡

@securityCoding #4 gnet 自己支持的东西太少了,扩展起来也比较难,欢迎 pk (性能、功能、易用性都可以 pk )
2023-09-09 14:43:45 +08:00
回复了 wesleyqiu 创建的主题 Python 孩子学编程是不是首选 C++
如果是亲爹,不至于对孩子这么狠!
如果不是亲爹,不至于这么卖力培养孩子!

所以我迷惑,到底是不是亲爹行为?
2023-09-07 02:32:55 +08:00
回复了 097ecom 创建的主题 Rust 字节卖的 Rust 课一字不动抄袭《Rust 程序设计语言》
看到 cloudwego ,我来凑个热闹,我这也有 rpc 和 poller 框架:
https://github.com/lesismal/arpc
https://github.com/lesismal/nbio

related:
https://colobu.com/2022/07/31/2022-rpc-frameworks-benchmarks
https://www.v2ex.com/t/945827

@Grayan 欢迎来试试我的库啊 :joy:
2023-09-04 13:16:31 +08:00
回复了 inSpring 创建的主题 程序员 求推荐低代码平台?
@murmur 有道理!不过现在这经济状况,估计国内低代码平台离 aws 也不会太远了
2023-09-04 02:29:21 +08:00
回复了 inSpring 创建的主题 程序员 求推荐低代码平台?
不推荐这玩意,可参考 “一个潮流的终结?推出仅 3 年后,亚马逊宣布终止低代码 Honeycode 服务,前员工爆料:长期没有顾客!”:
https://www.infoq.cn/article/IddZNuobV3BLkWyAM3tZ
2023-08-24 09:57:43 +08:00
回复了 voidmnwzp 创建的主题 程序员 一个有意思的现象: 关于逻辑运算符的求值顺序
@voidmnwzp 是的。go 和 c 的编译器还不是特别智能,如果是 cpp 编译器、很多不这么明显的逻辑也会优化得更屌
2023-08-23 23:56:12 +08:00
回复了 voidmnwzp 创建的主题 程序员 一个有意思的现象: 关于逻辑运算符的求值顺序
表达式里含有子表达式这种,通常是要先计算子表达式吧,如果多个子表达式、c 里好像是不规定多个子表达式的先后顺序而是依赖编译器厂商实现。
go 的表达式规则我没细看,但是 OP 这段代码如果按照先计算子表达式,并且编译器推断那就是对比 a==a ,所以编译器直接可以优化了,看下反汇编的代码就优化掉了的:
https://gist.github.com/lesismal/71a96904de3a878c6ff27dd36e8fd4af
明明是 golang 的 if err 更适合错误处理、鲁棒性,一帮习惯了 java 的人喷 golang if err 。
2023-08-13 17:56:28 +08:00
回复了 SoftTime 创建的主题 程序员 六年 c++游戏后端的迷茫与转行求建议
也可以转 go ,游戏行业也有不少团队用 go ,关键是 go 转 web 开发、cloud 、devops 各种都比较方便。

继续深挖 cpp 也可以,看运气了
2023-08-13 17:55:19 +08:00
回复了 SoftTime 创建的主题 程序员 六年 c++游戏后端的迷茫与转行求建议
@zerone0086 我猜 1 楼是知道你说的措辞技巧的,因为他已经用 “有个朋友” 开局了 😄
他 git 提交的 username 是 zhaoxiaojiebj01
他 github 用户名是 zhaoxiaojie0415

Contributors 是按照 git 提交的 username 统计,两个不一样、而且 github 上没有 zhaoxiaojiebj01 ,所以不行

linus 喷 github 这个好像不只一次了。随便伪造个 xx 的提交
1 ... 18  19  20  21  22  23  24  25  26  27 ... 62  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5921 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 34ms · UTC 02:20 · PVG 10:20 · LAX 18:20 · JFK 21:20
Developed with CodeLauncher
♥ Do have faith in what you're doing.