Skip to content
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

大老您好,请教下和fasthttp的结合 #380

Closed
ericjing83 opened this issue Jan 3, 2024 · 7 comments
Closed

大老您好,请教下和fasthttp的结合 #380

ericjing83 opened this issue Jan 3, 2024 · 7 comments
Labels

Comments

@ericjing83
Copy link

大老您好,
我想请教下您,nbio这个库和fasthttp/websocket结合的可能性。我想在以下操作结合fasthttp:

1.在TLS握手阶段,用fasthttp代替您的库的默认操作。
2.当握手成功后,请求被升级到websocket后,按您的库的默认操作进行,所有的事件循环、多路复用机制都依赖nbio不变。但是,收发消息的函数替换为fasthttp/websocket库里的conn.ReadMessage()和conn.WriteMessage(),这两个方法是阻塞的。

思路是,fasthttp/websocket 负责提供 WebSocket 协议级别的支持,而 netpoll 负责提供底层的 I/O 事件通知。我想知道这样结合有没有可能性,能否提升性能?

@lesismal
Copy link
Owner

lesismal commented Jan 3, 2024

感谢关注!

fasthttp/websocket是fork gorilla/websocket然后略有改动的,性能跟gorilla基本一致。
这里有各个websocket框架的benchmark可以参考下,fasthttp/gorilla 不算是最快的,并且它们默认的 ReadMessage 性能比较差的,benchmark 里是对它们的读使用了优化的:
https://github.com/lesismal/go-websocket-benchmark
https://github.com/lesismal/go-websocket-benchmark/blob/main/frameworks/fasthttp/server.go

普通在线数,nbio的non-blocking模式用poller的响应性是不如直接使用标准库阻塞接口的方式的,所以nbio也支持blocking模式,nbio好处是可以使用mixed模式让低在线时响应性好、高在线时占用低更稳定

如果想在fasthttp里使用nbio的websocket,好像是可以把fasthttp那个转换成标准库request/response然后给nbio的websocket来Upgrade

@ericjing83
Copy link
Author

感谢大佬指点。

官方的fasthttp/websocket由于没法多路复用,确实没法实现百万级并发。如果nbio收发消息的性能和fasthttp/websocket差不多,我觉得还是直接用nbio比较好,所以我想了解下以下两个性能相关的问题:

1.如果fasthttp在TLS握手,把https请求升级成websocket的过程中,性能和nbio差不多,我觉得就让nbio用默认的方式处理TLS握手和upgrader的操作。nbio和fasthttp在这个阶段的操作中,哪个性能好点?
2.如果fasthttp/websocket里websocket的bench是为了跑分经过了特殊优化的,这种优化如果不能大范围在生产环境里用,那么我觉得可能ReadMessage的性能不是很好。我同样想请教下,fasthttp/websocket的writeMessage的性能,在100万级别用户连接数的情况下,性能和nbio如何?

@lesismal
Copy link
Owner

lesismal commented Jan 3, 2024

1.如果fasthttp在TLS握手,把https请求升级成websocket的过程中,性能和nbio差不多,我觉得就让nbio用默认的方式处理TLS握手和upgrader的操作。nbio和fasthttp在这个阶段的操作中,哪个性能好点? 2.如果fasthttp/websocket里websocket的bench是为了跑分经过了特殊优化的,这种优化如果不能大范围在生产环境里用,那么我觉得可能ReadMessage的性能不是很好。我同样想请教下,fasthttp/websocket的writeMessage的性能,在100万级别用户连接数的情况下,性能和nbio如何?

TLS的流程是相当于传输层、是在HTTP之前进行握手的,nbio的tls是基于标准哭魔改支持异步,nbio websocket IOModBlocking的Conn也可以基于标准库net.Conn、标准库tls.Conn
IOModBlocking:nbio用标准库的连接、没有用nbio自己的epoll管理连接,标准库和nbio的tls性能基本一致,nbio Conn和标准库TCPConn性能也一个水平没太大差别
IOModNonBlocking:nbio的poller管理连接,普通连接数场景下响应性能不如标准库连接。如果是海量连接,nbio占用低、稳定

不管哪种,压测上有差距、但对于单个连接、性能应该都足够了,实际性能需求要根据你们的业务情况进行软硬件的细节优化,例如你们的每个连接是否高频收发数据、这本身就对系统消耗是不一样的、都在一个桌上吃饭、每个连接消耗多少资源也都会影响整个系统的其他连接。

2.如果fasthttp/websocket里websocket的bench是为了跑分经过了特殊优化的,这种优化如果不能大范围在生产环境里用,那么我觉得可能ReadMessage的性能不是很好。

多数人默认用的ReadMsg,包括其他一些基于gorilla的框架,比如melody:
olahol/melody#87

我同样想请教下,fasthttp/websocket的writeMessage的性能,在100万级别用户连接数的情况下,性能和nbio如何?

fasthttp自己的协程池好象是25w还是多少来着,所以fasthttp处理http的话单个进程最多处理25w这么多、需要处理http百万连接是用的fork、多进程的方案。
但是websocket upgrade后如果你们用新的协程去处理ws连接读写,则应该会释放协程还给fasthttp自己的协程池,所以应该也能处理百万ws连接,这个我没试过、你可以测试下看看。

基于标准库连接的方案能处理百万连接,但需要较高硬件配置,100w在线,至少百万个协程,如果需要广播、避免单个连接阻塞导致for-loop中其他连接被阻塞,就要为每个连接单独的写协程。不管是不是单独写协程,百万级的协程数量、目前比较新版本的协程栈好像默认是8k,8k×1M=8G基础内存,加上其他的,内存消耗就更大,而且对应的gc压力也巨大,可能会运行不稳定,gc时候STW会比较明显。硬件规格太高比较费钱,而且不管怎样gc压力都让人头疼,想用标准库连接的方案处理百万连接仍然需要优化细节去降低STW时长。
nbio也正是为了解决这个内存占用、gc压力大的问题。
在这种海量连接数的情况下,nbio仍然能比较稳定、响应性能也还不错,因为基于标准库连接的方案已经不是很稳定了、所以与基于标准库连接的方案也没有太大对比的必要了

具体的性能指标,要看你们实际的业务代码逻辑,如果需要更多细节优化也好有的放矢。

@ericjing83
Copy link
Author

好的。我知道nbio可以支持百万并发连接,并且保持稳定。
我对底层的网络库不是很懂,我就随便问下有没有进一步优化的可能,如果nbio直接用内部的epoll库暴露在端口上对外提供服务,会产生兼容性问题吗?比如,网页上用javascript创建websocket的连接客户端,可以连接到nbio直接用内部的epoll库对外提供的websocket服务端口吗?

Copy link

github-actions bot commented Feb 3, 2024

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Feb 3, 2024
@lesismal
Copy link
Owner

lesismal commented Feb 3, 2024

好的。我知道nbio可以支持百万并发连接,并且保持稳定。 我对底层的网络库不是很懂,我就随便问下有没有进一步优化的可能,如果nbio直接用内部的epoll库暴露在端口上对外提供服务,会产生兼容性问题吗?比如,网页上用javascript创建websocket的连接客户端,可以连接到nbio直接用内部的epoll库对外提供的websocket服务端口吗?

没收到github提示,才看到这个。
ws网络协议本身都是数据流交互的规则,只要数据流格式符合协议、无所谓对端使用什么语言。所以网页js ws兼容性本身不是个问题

Copy link

This issue was closed because it has been inactive for 14 days since being marked as stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants