有对 nginx 熟悉的老哥吗?请教一下 nginx 代理 tcp 的一个问题?

2022-12-01 11:05:23 +08:00
 liuguangxuan

背景:

使用 nginx 代理 tcp 服务,假如后端有一个 tcp 的业务服务,中间用 nginx 做代理,前面有 1000 个客户端连接,那么每当一个客户端连接 nginx 的时候,nginx 就会发起一个 tcp 连接至后端的业务服务。

问题:

假设我的那个 tcp 后端服务是负责提供下载地图数据的,对所有的 1000 个客户端来说,从地图服务器下载的数据都是一样的。那么当一个客户端连接上 nginx 的时候,nginx 发起了一个 tcp 连接至地图服务器,地图服务器把地图数据推给了 nginx ,nginx 把数据转给了客户端,这样相当于把一份地图数据在网络中走了两遍(地图服务器到 nginx ,nginx 到客户端),当地图数据比较大的时候,带来的开销就很大了。

想要达到的效果:

能否对 nginx 做改造,在 nginx 中缓存一下地图数据,当第一个客户端连接 nginx 的时候,nginx 从后端的地图服务器获取了地图数据,一直缓存在内存里,后面 999 个客户端连接的时候,nginx 就直接把地图数据推给客户端,而不再朝后端的地图服务器下载地图数据。

如果想实现上述的效果,需要对 stream 模块做改造吗?还是有其他更好的解决办法?麻烦各位老哥赐教。

5494 次点击
所在节点    NGINX
75 条回复
liuguangxuan
2022-12-01 19:25:25 +08:00
@Twan #33 是的,老哥,类似于游戏。
@ysc3839 #34 老哥,业务场景对实时性要求较高,可以想象成打 CS 。
liuguangxuan
2022-12-01 19:26:00 +08:00
@seakingii #38 多谢老哥耐心解答。
liuguangxuan
2022-12-01 19:32:54 +08:00
@rrfeng #39 老哥,你提到的“那就在 Nginx 里把你 C++ 实现的『私有协议』搞一遍就行了”,具体怎么实现呢?
我目前了解到的信息有:
方式 1:直接改造 nginx 代码,但是感觉这种难度比较大,最起码需要看懂 stream 模块的代码及变量。
方式 2:nginx 好像支持扩展模块,用 C 语言,新增自定义的 nginx 模块,但是目前还不清楚自己增加的 nginx 模块如何截获 stream 模块的流量数据,然后加上自己的私有协议。
方式 3:使用 OpenResty ,用 lua 模块重写,但是问题和方式 2 一样。

烦请老哥有空的时候帮忙解答一下疑惑。
liuguangxuan
2022-12-01 19:38:28 +08:00
@wangritian #40 go 语言不熟啊老哥。
@xhinliang #35 不能忽略不计,老哥。业务场景类似于游戏,而且地图数据特别大,如果按 1G 来计算的话,1000 个客户端同时开一局,那么这种局域网的流量也就是 1000G 。
ysc3839
2022-12-01 19:53:29 +08:00
@liuguangxuan 实时性要求高和使用 http 传输资源冲突吗? CS 都支持 http 下载地图呀。
rrfeng
2022-12-01 20:03:57 +08:00
@liuguangxuan
这得靠你自己学了
garyox64
2022-12-01 20:10:32 +08:00
我理解用啥改,你都得学 nginx 的模块和架构设计了
liuguangxuan
2022-12-01 20:27:51 +08:00
@rrfeng #46
@garyox64 #47 感谢老哥们。
wangritian
2022-12-01 21:29:15 +08:00
@liuguangxuan go 语法非常精简,容易学习,其中的精髓 goroutine 协程开发容易,并发性能也强,非常适合做网络中间件,推荐你趁机实践一下
liuguangxuan
2022-12-01 21:31:14 +08:00
@wangritian #49 多谢老哥。
maichaide
2022-12-01 21:37:09 +08:00
不能用 squid 缓存么?
ouyangjun
2022-12-01 21:49:22 +08:00
Openresty 本身的 stream 模块支持上下游连接,然后你可以在 lua 里面保存数据,对于你的需求来说应该是可以完成的,有兴趣的话我们可以聊聊细节的。
des
2022-12-01 22:10:00 +08:00
想想办法能不能改造客户端?
地图用 http 也能瓦片加载啊,你这种自定义协议就不建议在 nginx 上改了
0ZXYDDu796nVCFxq
2022-12-01 22:27:42 +08:00
HTTP 协议把地图通过 CDN 分发不更快?
HTTP2 就是个二进制协议,有啥效率问题啊
liuguangxuan
2022-12-01 22:41:17 +08:00
@maichaide #51 老哥,这个 squid 技术是针对 tcp 的吗?
liuguangxuan
2022-12-01 22:41:32 +08:00
@ouyangjun #52 老哥,怎么联系?
liuguangxuan
2022-12-01 22:44:12 +08:00
@des #53 感谢老哥,改造客户端是个办法。但是目前所有的后台服务还是以 tcp 为主,不仅仅是这一个地图服务器,目前后台服务加进来几个 web 服务,所以想统一一下所有后台服务的入口。
liuguangxuan
2022-12-01 22:45:39 +08:00
@gstqc #54 感谢老哥,目前因为历史原因,后台已有的服务还是以 tcp 为主,不仅仅是这一个地图服务器,如果改造成 http 或者 http2 的话,代价可能比改造 nginx 还大。
des
2022-12-01 22:50:49 +08:00
@liuguangxuan 如果说地图不是经常变动的话,长期来讲还是建议改客户端走 cdn
des
2022-12-01 22:51:59 +08:00
客户端一旦多了之后,你这系统就没法部署

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/899278

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX