V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Recommended Services
Amazon Web Services
LeanCloud
New Relic
ClearDB
laters
V2EX  ›  云计算

多台负载均衡的服务器上传文件后如何确定文件在哪台静态服务器上

  •  
  •   laters · 2023-10-20 11:13:35 +08:00 · 5403 次点击
    这是一个创建于 425 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有两台后端服务器做负载均衡,上传文件时就可能会上传到任意一台服务器,这边上传完存储了一个静态地址,访问时就不知道访问哪台服务器的静态地址。目前想了三个方案都不太可行 1.上传时把服务器地址也记录下来,但如果后期服务器 IP 变更即失效 2.通过挂载的形式统一两台服务器的静态地址,但这个只适用 linux 服务器,如果是 windows 服务器则不支持 3.文件同步的方式,这种方式有同步失败的风险,最终也被 pass 掉。

    请问有没有别的合理方式或解决方案?

    66 条回复    2023-10-21 11:00:22 +08:00
    m3ops2021
        1
    m3ops2021  
       2023-10-20 11:18:42 +08:00
    看看 fastdfs ?
    laters
        2
    laters  
    OP
       2023-10-20 11:20:03 +08:00
    @m3ops2021 支持内网吗, 目前我们都是内网
    28Sv0ngQfIE7Yloe
        3
    28Sv0ngQfIE7Yloe  
       2023-10-20 11:20:55 +08:00
    感觉是不是需要一个分布式文件系统
    laters
        4
    laters  
    OP
       2023-10-20 11:22:18 +08:00
    @Morii 有好的工具或解决方案吗 ?
    zkl2333
        5
    zkl2333  
       2023-10-20 11:23:04 +08:00
    oss
    seers
        6
    seers  
       2023-10-20 11:24:04 +08:00 via Android
    你需要一个分布式文件系统+1 ,win 可以挂载 nfs 或者 smb
    GoRoad
        7
    GoRoad  
       2023-10-20 11:24:16 +08:00
    minio 可破
    laters
        8
    laters  
    OP
       2023-10-20 11:24:29 +08:00
    目前只能是内网,如何能做到
    28Sv0ngQfIE7Yloe
        9
    28Sv0ngQfIE7Yloe  
       2023-10-20 11:27:31 +08:00
    @laters #4 我想了下,简单的话 你直接 hash 文件名 决定进哪台服务器,取的时候再 hash 下判断文件再哪台服务器上,拼接下静态地址就行了吧?

    分布式的话上个 minio 就差不多了
    opengps
        10
    opengps  
       2023-10-20 11:29:15 +08:00
    回话类,文件类服务不适合使用负载均衡。你们为啥会把文件服务器放在负载均衡后面?即使要用也得用服务去唯一关联起来。直接买 oss 这种服务就可以
    Worldispow
        11
    Worldispow  
       2023-10-20 11:29:43 +08:00
    我们是专门弄个文件服务器,开个 ftp 、sftp 就行。
    mightybruce
        12
    mightybruce  
       2023-10-20 11:30:11 +08:00
    各种分布式文件系统自己部署一下就好了,fastdfs 完全可以。fastdfs 大致分成两部分
    Tracker Server
    Storage Server
    Tracker server 跟踪服务器,负责文件访问的调度和负载均衡,负责管理所有的 Storage Server 和 group 组/卷,

    Storage Server
    存储服务器,负责文件存储,文件同步/备份,提供文件访问接口,文件元数据管理。以 group 为单位,每个 group 内可以有多台 Storage Server ,数据互为备份,达到容灾的目的。每个 Storage 在启动以后会主动连接 Tracker ,告知自己所属 group 等存储相关信息,并保持周期性心跳。
    dongfangyihaolan
        13
    dongfangyihaolan  
       2023-10-20 11:30:46 +08:00
    最好的方案肯定是分布式文件系统,oss 对象存储服务,用阿里腾讯都可以,或者自建 minio 也行。
    如果不想用分布式,就想用题中描述的,以下方案或许可破:
    返回静态地址前,给地址拼一个参数,表明上传的是节点 1 还是 2, 然后 nginx 利用地址中的这个参数做转发,导向正确的节点。
    laters
        14
    laters  
    OP
       2023-10-20 11:34:34 +08:00
    @opengps 只能内网 而且最好不花钱 -.-
    tomczhen
        15
    tomczhen  
       2023-10-20 11:34:42 +08:00 via Android
    最简单的办法是用同步软件把文件同步一下完事。

    又不是不能用.jpg
    laters
        16
    laters  
    OP
       2023-10-20 11:35:11 +08:00
    @dongfangyihaolan OSS 不得花钱吗。。。 只能内网 而且最好不花钱 -.- 公司内网自己用
    laters
        17
    laters  
    OP
       2023-10-20 11:35:40 +08:00
    @tomczhen 想稳定点。。怕同步软件不太行
    coderxy
        18
    coderxy  
       2023-10-20 11:36:08 +08:00
    多台机器之间做文件同步。 一般也不需要多台,两台互备就行了
    wuwukai007
        19
    wuwukai007  
       2023-10-20 11:40:05 +08:00
    自定义 404 错误处理:
    首先,为 404 错误配置一个自定义处理程序。这个处理程序会检查其他后端服务器,以查看它们是否有请求的文件。

    编写脚本进行检查:
    当触发自定义 404 错误处理时,该脚本会遍历所有其他的后端服务器以检查文件是否存在。你可以使用如 curl 或其他 HTTP 客户端来进行这个检查。

    重定向到正确的服务器:
    如果脚本发现文件存在于其他服务器上,它可以返回一个 302 重定向响应给客户端,指向正确的服务器和文件位置。

    以 Nginx 和一个简单的 Bash 脚本为例:

    在你的 Nginx 配置中,为 404 错误添加自定义处理:
    gwbw
        20
    gwbw  
       2023-10-20 11:41:18 +08:00
    正式方案还是需要分布式文件系统或对象存储服务。想一切从简的话有个野路子,直接尝试取从本地取,取不到就把 get 文件请求带上[本次请求为内部转发]参数转发到另一台服务器,再取不到就报错
    victimsss
        21
    victimsss  
       2023-10-20 11:41:36 +08:00
    现成方案就 minio ,楼上也说了。
    Achilless
        22
    Achilless  
       2023-10-20 11:42:28 +08:00
    简单点 NFS 或 SMB 就行了,可靠性强点的话就 Minio
    wyhooo
        23
    wyhooo  
       2023-10-20 11:47:47 +08:00   ❤️ 1
    @Livid 19 楼 GPT ,给的方案贼蠢,还用图片发代码,忍不了了 :)
    laters
        24
    laters  
    OP
       2023-10-20 11:50:07 +08:00
    @Morii 大佬,你好!你说的是 nginx 上面配置 ip_hash 么,这种不是只固定访问一台后端服务器了么,失去了负载均衡的意义。能具体说下这个方案么,不是很清楚
    laters
        25
    laters  
    OP
       2023-10-20 11:53:33 +08:00
    @dongfangyihaolan 大佬,你说的不分布式的方案我这边也想过,记录当时上传的具体节点,但是如果服务器 Ip 变了就访问不了了
    yuanfa
        26
    yuanfa  
       2023-10-20 12:04:37 +08:00
    1 方案,用 DNS 服务器,上传的时候,记录服务器的域名,不要用 IP 。
    tomczhen
        27
    tomczhen  
       2023-10-20 12:23:34 +08:00 via Android
    @laters 这就搞笑了。就算改变负载策略,记录了上传的服务器又怎么样?当一个节点挂掉,上面的文件始终都是无法访问到的。既然基于负载的方案都能接受风险,同步文件怎么就不行了?
    aru
        28
    aru  
       2023-10-20 12:24:34 +08:00
    内网共享存储就行了
    在其中一台机器开一个 nfs 或 samba 共享,两台机器都加载这个共享,往里面写文件
    仅有 linux 就 nfs 共享,既有 windows 又有 linux 就用 samba
    当然,你搞个 minio 也行
    ryd994
        29
    ryd994  
       2023-10-20 12:32:04 +08:00 via Android
    @wuwukai007 首先,proxy_pass 是这么用的吗?这么个四不像的 cgi ,还用 GPT ?
    然后,你这样碰到不存在的文件不就死循环了吗?


    @laters 路径 hash 配合 proxy pass 就好了
    hash 值可以对半分,分到 1 或者 2 上
    如果 1 服务器拿到 hash 1 的请求,那就本地处理,有就有,没有就是 404.
    如果拿到 hash 2 的请求,那就 proxy pass 给 2 ,2 说有就是有。

    缺点就是只有一半的请求可以本地处理。

    -----

    但是,按这个思路再进一步,说明你用的负载均衡错了。你用 4 层负载均衡当然就是随机分配。但是如果你用 7 层的负载均衡,比如 Nginx 或者 haproxy 之类的,本来就支持根据 URL hash 分流,也就不存在以上问题。
    nuII
        30
    nuII  
       2023-10-20 12:38:48 +08:00
    现在的问题是每个负载服务器都有各自的存文件的地方,那你把他们都存在一个地方不就可以了吗,每个服务器去连接这个存储地址。这就是分布式文件系统,多节点读写模式,楼上提到的传统方案 nfs 、smb 都支持,linux 上直接用包管理器安装就行,windows 开一下 feature 就有了,很简单
    dongfangyihaolan
        31
    dongfangyihaolan  
       2023-10-20 13:11:11 +08:00
    @laters 首先,minio 好像是免费的吧?
    kingme
        32
    kingme  
       2023-10-20 13:12:40 +08:00
    fastdfs ,简单好用
    Livid
        33
    Livid  
    MOD
       2023-10-20 13:13:41 +08:00   ❤️ 4
    @wyhooo 谢谢,那个账号已经被彻底 ban 。
    dongfangyihaolan
        34
    dongfangyihaolan  
       2023-10-20 13:13:53 +08:00
    @laters 变了也没关系,返回的资源地址里只追加节点编号,不放 ip 。编号和 ip 的对应关系,你在 nginx 里体现好就行,如果节点的 ip 变了,只要编号没变就行。
    不过折腾这干嘛,直接就用 minio 呗,随着业务发展,到后面很可能还是得上。
    dddd1919
        35
    dddd1919  
       2023-10-20 13:19:49 +08:00
    简单的 搞个 ftp
    paranoiagu
        36
    paranoiagu  
       2023-10-20 13:43:29 +08:00 via Android
    nfs 之类的同时挂载到不同服务器最简单。也可以用其他的 oss 之类的。
    n0bin0bita
        37
    n0bin0bita  
       2023-10-20 13:46:11 +08:00
    两边存放上传文件的服务器都挂载同一个 NFS 或类似的共享存储,就不用管他发到那台机器了
    zx9481
        38
    zx9481  
       2023-10-20 14:03:38 +08:00
    挂载一下不久可以了嘛
    gxm44
        39
    gxm44  
       2023-10-20 14:07:41 +08:00
    minio, 或挂载 NFS 之类的
    dzdh
        40
    dzdh  
       2023-10-20 14:18:05 +08:00
    最简单的 go-fastdfs 搞定

    https://www.oschina.net/p/go-fastdfs
    dode
        41
    dode  
       2023-10-20 14:28:25 +08:00
    后端文件存储独立处理出来,提供多种方式网络共享,Linux 挂载 nfs ,Windows 挂载 smb
    luomao
        42
    luomao  
       2023-10-20 14:32:41 +08:00
    部署个 nas 把 用 nfs 的方案,我们目前也是大量再用文件服务,目前这个方案没出什么问题
    cheng6563
        43
    cheng6563  
       2023-10-20 14:35:01 +08:00
    其实,可以全部服务器查一遍的。。
    Huelse
        44
    Huelse  
       2023-10-20 14:36:33 +08:00
    原则上应该建个数据库记录的,无论是查询或是后期做容灾备份都必不可少
    nothingistrue
        45
    nothingistrue  
       2023-10-20 14:38:57 +08:00
    请注意:常规的自动负载均衡策略下,要求多个节点完全一样,包括后期上传的文件。「上传文件时就可能会上传到任意一台服务器」,这个行为本身就是一个 BUG 。

    方案上面已经给了:用其他同步措施,把多个节点的后期上传文件,做同步。这个虽然是最简单的,同时也是绝大多数情况下最合理的。

    当然如果你要更合理的话,那也有稍微复杂点的方案:
    首先,将上传和下载路径的前段部分(含绝对路径),都做成可配置的(而不是自动获取当前服务所在目录);
    然后,不管是哪个节点,上传文件都保存到一个位置,这个位置与后端服务节点不绑定,而是与宿主服务器的文件系统和 Nginx 绑定;
    最后,给 Nginx 配个映射,让上传文件能通过 Nginx 直接访问。
    pigspy
        46
    pigspy  
       2023-10-20 14:41:33 +08:00
    应当有一台高性能存储主机作为文件服务器用来专门存储文件,负载均衡只针对上传文件的接口,上传文件接口需要把文件传输到这台文件服务器上,下载文件的接口应当直接指向这台负责存储文件的服务器上
    Fooooo0
        47
    Fooooo0  
       2023-10-20 14:46:22 +08:00
    好像大家不知道 nginx 的`try_file`可以实现,

    当然推荐还是用分布式文件系统。
    yongp
        48
    yongp  
       2023-10-20 14:55:40 +08:00
    上传还放在单独的服务器上,不应该搞个共享存储,或者对象存储吗?
    Features
        49
    Features  
       2023-10-20 14:56:14 +08:00
    负载均衡一般不是每个节点数据都一样吗?
    不然负载均衡有啥意义呢?
    所以应该在上传的时候,同步复制到所有节点上吧
    yufeng0681
        50
    yufeng0681  
       2023-10-20 15:13:58 +08:00
    @tomczhen #27 说得对, 上传的文件和数据库其实是一个类型,不可能跟着集群多少来走的
    题主可能希望一套代码打天下了,增加新的服务,虚拟一个文件管理服务,都增加了他的研发成本,运维也复杂, 未来因为集群引发的新问题,他也没去想,见招拆招(最小成本)。

    -- nfs/smaba ,不靠谱:不方便后端的集群扩展,性能也是瓶颈,单点故障,nfs 也没法弄集群
    -- nginx 配套固定规则上传, 不靠谱: 扩展集群规则歇菜,后台服务器的单点故障问题
    -- minio , 靠谱: 其实就是要加个文件服务器,起步 1 台,如果遇到单点故障、上传性能的痛点,就弄 minio 集群
    flashBee233
        51
    flashBee233  
       2023-10-20 15:15:30 +08:00
    之前我们也是遇到了这个问题,尝试了文件自动同步,最后还是上了 OSS ,这里楼主可以使用 minio
    hallDrawnel
        52
    hallDrawnel  
       2023-10-20 15:16:27 +08:00
    如果你只有两台服务器而且业务看起来不怎么增长的话,最简单的方案就是做一个中间服务取的时候两台服务器都去访问一下。
    wheat0r
        53
    wheat0r  
       2023-10-20 15:17:58 +08:00
    用 docker 随便跑一个单节点 minio 试试就好了
    IsaacYoung
        54
    IsaacYoung  
       2023-10-20 15:33:00 +08:00
    就两台 都查一遍问题不大
    goodryb
        55
    goodryb  
       2023-10-20 15:43:10 +08:00
    内网不花钱简单啊,A 、B 两个服务器,在 A 上面启动一个 smb 服务,B 挂载这个 smb 服务, 配置 A 、B 都读写相同 smb 目录,主要不是高并发业务,自己业务用用也足够了。

    总计成本 :耗费运维 30 分钟时间。
    corningsun
        56
    corningsun  
       2023-10-20 16:52:12 +08:00
    看起来你们服务可用性要求很低,那直接下掉一台后端服务器不就行了。
    还能节省一半的服务器成本。
    yc8332
        57
    yc8332  
       2023-10-20 16:59:47 +08:00
    1. 要么分布式存储
    2. 要么就是直接是带域名的地址,这样就不会有问题了
    Masoud2023
        58
    Masoud2023  
       2023-10-20 17:15:48 +08:00
    minio 非常好的选择,不然就自己手搓一个文件服务?
    hahahasnoopy
        59
    hahahasnoopy  
       2023-10-20 17:27:48 +08:00
    你都负载均衡了,文件还是分开存储的,那均衡有啥用。直接用文件服务器管理文件吧,应用服务器通过内网连接文件服务器
    fionasit007
        60
    fionasit007  
       2023-10-20 18:28:56 +08:00
    内网搭建一个文件管理系统吧,文件上传后再上传到这个文件系统,走内网的话也没有什么损耗的,你要是这种分开管理,记录在那个服务器倒是好说,但是不方便文件整合和管理啊
    rtx3
        61
    rtx3  
       2023-10-20 18:34:55 +08:00
    多台机器都挂同个 nas 就行了
    Quarter
        62
    Quarter  
       2023-10-20 20:02:47 +08:00 via Android
    推荐使用 minio 或者分布式文件系统,minio 会比较简单一点
    kisick
        63
    kisick  
       2023-10-20 22:46:35 +08:00 via iPhone
    最简单的方式:挂载一个共享盘
    kirory
        64
    kirory  
       2023-10-21 01:05:03 +08:00
    NFS mount
    yangfan1999
        65
    yangfan1999  
       2023-10-21 06:25:28 +08:00 via Android
    简单省事的话,用 nfs 挂载就行。及时做好备份。
    chfight
        66
    chfight  
       2023-10-21 11:00:22 +08:00
    nfs +1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2034 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 00:01 · PVG 08:01 · LAX 16:01 · JFK 19:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.