有对 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 模块做改造吗?还是有其他更好的解决办法?麻烦各位老哥赐教。

6148 次点击
所在节点    NGINX
75 条回复
Weixiao0725
2022-12-02 00:42:32 +08:00
我觉得,这问题真的是匪夷所思。你应该缓存的是所有参数相同的请求,跟客户没有关系。如果有第 1001 个客户请求用相同的参数请求数据,就不走缓存了? 第二点是,专业的人干专业的事,nginx 被设计出来就不是干缓存的,要不然要 memcached, redis 是干啥的?
PolarBears
2022-12-02 07:47:11 +08:00
没必要执着在 nginx 里做 tcp 的协议识别和缓存吧,不如直接用别的高级语言实现一个 tcp 转发+缓存功能来的更快,
反正都是在一台服务器上跑的。
liuguangxuan
2022-12-02 08:38:21 +08:00
@des 老哥,非公网,内部网络,没有 cdn 。😂

@Weixiao0725 已经有了一个类似 redis 的缓存服务了,我的疑问点是 nginx 到缓存服务( redis ),这一段,地图数据的流量太大了,如果每连上一个客户端,就要 nginx 向 redis 请求一次的话,网络压力很大。又因为地图数据对每个客户端来说都是一样的,怎么样能把 nginx 到 redis 这一段给只请求一次,然后 nginx 就可以转发给下面所有的客户端。


@PolarBears 老哥,您提到的这个“不如直接用别的高级语言实现一个 tcp 转发+缓存功能来的更快”,我们已经自己写了这样的一个后台服务,类似于网关,现在呢,又多了一些 B/S 的后台服务,所以有了 http 的流量,我们想把 http 的流量和 tcp 的流量统一入口。所以才有了我的提问。
julyclyde
2022-12-02 09:16:41 +08:00
把控制流放在自定义协议里
资源用 http 另一个通道来传输就行了呗
要善用现有的基础设施
不要重复发明问题
0ZXYDDu796nVCFxq
2022-12-02 09:25:31 +08:00
散了吧,我总结出 OP 的问题其实是
我的历史包袱很重,我的架构不能动,你们看有什么东西能帮我实现,明天上线!
ysjdx
2022-12-02 09:33:45 +08:00
@liuguangxuan nginx+lua 用共享内存做一次缓存不就行了?
Ansen
2022-12-02 09:42:54 +08:00
统一入口后,是否可以区分一下流量?比如:tcp==>缓存服务,http ==>缓存服务转发==>后台服务
fengfisher3
2022-12-02 09:46:38 +08:00
还没这方面的经验,希望楼主有合理的方案后,帮不上忙。整理分享一下,谢谢。
lostsquirrelX
2022-12-02 09:57:19 +08:00
有没有可能这个 X-Y Problem
duckyrain
2022-12-02 10:16:30 +08:00
你们是不是该考虑使用 UDP 协议了
GBdG6clg2Jy17ua5
2022-12-02 10:38:35 +08:00
你纠结的 nginx 到地图服务器之间的流量。
你原来就有一个 tcp 缓存代理。
但你又想用 nginx 统一 http 和这个 tcp 。
那你不如把原来的 tcp 缓存代理和 nginx 部署在同一个服务器。nginx 在代理去旧的 tcp 缓存代理。可解决内部网络流量大,http 和 tcp 统一整合。
kiddingU
2022-12-02 15:26:51 +08:00
丢共享内存可以,丢外部 cache 也行,比如 redis, lua redis 连接池,开销也不大
PolarBears
2022-12-02 16:55:59 +08:00
@liuguangxuan #63 统一一个入口的意思是想要端口复用吗?如果是想端口复用的话 haproxy 能做到。
ouyangjun
2022-12-04 01:31:43 +08:00
@liuguangxuan 给我你的微信或者 tg 帐号?
liuguangxuan
2022-12-04 12:25:03 +08:00
@ouyangjun #74 绿色:Z3Vhbmd4dWFubGl1

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

https://ex.noerr.eu.org/t/899278

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

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

© 2021 V2EX