V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
balabalaguguji
V2EX  ›  程序员

tcp 负载均衡, nginx 问题请教

  •  
  •   balabalaguguji · 2019-09-10 12:43:20 +08:00 · 3594 次点击
    这是一个创建于 1888 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有个服务,是 TCP 的,我想上行和下行分配到不同服务器去处理 ,我希望的是他们经过代理服务器分配到执行服务器后,流量不再经过代理服务器,而是重新连接到了新的服务器,在不修改客户端当前重连机制下,有什么方法可以做到? nginx 可以做到吗?

    opengps
        1
    opengps  
       2019-09-10 12:55:04 +08:00
    不能
    TCP 是直连,一旦建立连接,连接周期内,一直在同一台服务器处理收发。
    optional
        2
    optional  
       2019-09-10 12:56:34 +08:00
    『流量不再经过代理服务器』的意义是什么? nginx 之类的做 tcp 代理并不消耗多少资源。
    dorothyREN
        3
    dorothyREN  
       2019-09-10 12:58:44 +08:00
    流量不经过代理服务器的话,nginx 做不到
    可以考虑上行和下行各用一个端口,然后用 lvs 转发
    liuminghao233
        4
    liuminghao233  
       2019-09-10 12:59:49 +08:00 via iPhone
    看了半天不知道什么是 客户端当前重连机制
    wwbfred
        5
    wwbfred  
       2019-09-10 13:21:32 +08:00
    Google 的服务器网络就分内部节点和边缘节点.你可以看看他们是怎么操作的.
    如果他们都是将数据返回边缘服务器再发给客户端,那应该就是没办法了.
    novaeye
        6
    novaeye  
       2019-09-10 13:27:59 +08:00
    这需求貌似 LVS 的 DR 模式?
    wwbfred
        7
    wwbfred  
       2019-09-10 13:32:11 +08:00
    仔细想了一下如果有这个需求修改内核肯定是能做到的,就是比较麻烦.
    一个简单的代替方案可以考虑更改网络架构,让边缘服务器处于网关的位置上.
    Firxiao
        8
    Firxiao  
       2019-09-10 13:44:25 +08:00
    首先要搞明白 3 层和 7 层
    你这个需求可以试试看 iptables 的转发功能
    balabalaguguji
        9
    balabalaguguji  
    OP
       2019-09-10 14:02:07 +08:00
    @optional #2 如果还经过代理服务器,所有的流量都经过代理服务器,带宽就受限于代理服务器了。
    snnn
        10
    snnn  
       2019-09-10 14:02:10 +08:00
    不能。
    optional
        11
    optional  
       2019-09-10 14:05:42 +08:00
    @balabalaguguji 这本身是合理的,一般 tcp 负载均衡服务器能力都很强,如果还扛不住,那么就多来几个代理服务器,用 dns 多 ip 解析做负载均衡。
    balabalaguguji
        12
    balabalaguguji  
    OP
       2019-09-10 14:12:29 +08:00
    @novaeye #6 看了下,做到了一半,能直接响应数据给客户端不经过代理了,但是请求还需要经过代理。我的需求是想要请求和响应都在分配服务器后不再经过代理。
    wsgzao
        13
    wsgzao  
       2019-09-10 14:18:07 +08:00   ❤️ 2
    @balabalaguguji #12 你想解决的需求可能比较符合使用 LVS-DR 或者 LVS-TUN 走 4 层,我最近刚好做了 LVS 和 Keepalived 相关的整理,细节就不回复了,参考最后两篇文章做下测试,过程不复杂,也许可以解决你的问题


    [LVS 和 Keepalived 的原理介绍和配置实践]( https://wsgzao.github.io/post/lvs-keepalived/)
    [LVS 原理介绍和配置实践]( https://wsgzao.github.io/post/lvs/)
    [Keepalived 原理介绍和配置实践]( https://wsgzao.github.io/post/keepalived/)
    [LVS-NAT 原理介绍和配置实践]( https://wsgzao.github.io/post/lvs-nat/)
    [LVS-DR 原理介绍和配置实践]( https://wsgzao.github.io/post/lvs-dr/)
    [LVS-TUN 原理介绍和配置实践]( https://wsgzao.github.io/post/lvs-tun/)
    balabalaguguji
        14
    balabalaguguji  
    OP
       2019-09-10 14:19:14 +08:00
    @optional #11 我的业务是很重带宽,重流量的,你可以理解为文件存储服务。我用的云服务器,上行不限带宽,下行是按带宽收费的,所以我希望下行都走那台带宽大的服务器,上行都走那些便宜的服务器(下行带宽很低,但是上行不限),这样上下行分开,读写也分开了。
    balabalaguguji
        15
    balabalaguguji  
    OP
       2019-09-10 14:27:46 +08:00
    @wsgzao #13 感谢,我看过了,这个只分离了响应数据,请求数据我的量也是很大的,同样需要分离,所以不是很适合
    lllllliu
        16
    lllllliu  
       2019-09-10 14:30:21 +08:00
    把服务拆分,费流量的单独部署。
    通过接口区分,通过域名区分,通过 DNS 负载,通过 NGINX 负载都,想干啥干啥。
    balabalaguguji
        17
    balabalaguguji  
    OP
       2019-09-10 14:34:36 +08:00
    @lllllliu #16 要是直接域名区分,那就没那么多事了,就是想让客户方便点,用同个域名,同个接口,不然用户的操作会麻烦死
    mhycy
        18
    mhycy  
       2019-09-10 14:42:14 +08:00
    做不到,用云服务器的情况下更加不可能做到
    需要路由层级介入对来源与目标 IP 做策略 NAT,工程量很大,需要路由二次开发

    另:建议把需求详细描述 ( #14 楼说明不完整
    看起来算是拍脑袋想了个不靠谱的方案想解决一个其实还有别的方案可解决的问题
    novaeye
        19
    novaeye  
       2019-09-10 14:44:42 +08:00
    @balabalaguguji 用 DNS 轮询配合上 LVS DR 模式? DNS 负责把请求解析到不同的 LVS 上, LVS 再 DR 到不同的 realserver 上然后直接返回给请求端
    gesse
        20
    gesse  
       2019-09-10 15:08:11 +08:00
    建立两个 tcp 连接?
    lllllliu
        21
    lllllliu  
       2019-09-10 15:14:20 +08:00
    @balabalaguguji 一个域名也可以呀,入口 Nginx 负载,Nginx 反向代理区分服务就好呀这是最简单的。然后服务都是内网,就可以做自己的负载策略了呀,也可以直接上 k8s 治理呀。

    资源 /文件服务可以单独做集群,其他业务返回一个 302 到这个服务到地址就好了呀,反正用户都是无感知。
    optional
        22
    optional  
       2019-09-10 15:48:18 +08:00
    @balabalaguguji tcp 是有状态的,两个 ip 地址怎么上下行分离,用 MPTCP 做手脚?
    感觉还不如服务器返回一个 301/302 去另一台服务器下载。
    justfly
        23
    justfly  
       2019-09-10 15:58:32 +08:00
    1. 魔改内核 tcp 协议栈,proxy 拿到连接后通知 real server 和 路由,从而在 real server 绕过握手产生一个连接
    2. 魔改你们公司路由器,接到 proxy 的通知后,改对该连接的包路由到 realserver

    PS. 我随便扯的,没人这么干的,我觉得你也没这能力。
    balabalaguguji
        24
    balabalaguguji  
    OP
       2019-09-10 16:37:47 +08:00
    感觉这个还是不太现实,难以做到,放弃了
    jziwenchen
        25
    jziwenchen  
       2019-09-10 16:45:03 +08:00
    换种思路

    连接正式服务器前 从代理服务器询问真实服务器地址.
    nimbus
        26
    nimbus  
       2019-09-10 16:52:02 +08:00
    真实服务器配置 loopback 地址为 nginx 的发布的代理地址,服务器的网关不走代理,回包直接用这个 loopback 地址作为源地址回包,就不经过代理了。
    cigarzh
        27
    cigarzh  
       2019-09-10 21:28:28 +08:00 via iPhone
    你这要 hack 传输层,没必要
    应用层模仿一个就好了
    balabalaguguji
        28
    balabalaguguji  
    OP
       2019-09-11 11:35:51 +08:00
    @jziwenchen #25 没认真审题,不能修改客户端,客户端不是我自己写的,如果能修改客户端,就可以跟你说的,这么简单搞定了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2692 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 06:53 · PVG 14:53 · LAX 22:53 · JFK 01:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.