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

如何实现限制某个文件单 IP 一小时只能下载 3 次?

  •  
  •   edis0n0 · 2022-12-22 13:46:05 +08:00 · 3229 次点击
    这是一个创建于 709 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个客户端更新原理是获取 http://example.com/latest.txt 里的数字版本号,如果大于当前版本号就后台下载 http://example.com/latest.exe ,如果下载失败就一直不停循环下载,多几个客户端循环下载服务器带宽就满了,需要实现限制这个文件单 IP 一小时只能下载 3 次,最方便的实现方法是什么?(不能用跳转,因为垃圾客户端不会追踪跳到哪里)

    最好能用服务器上有的 php+Apache ,因为服务器的系统是 CentOS4.8 ,所有东西基本都要自己编译了不说,它的 uptime 快 9 年了,我很怕因为什么关机就起不来了。

    不能读日志直接封 IP ,因为同域名下有很多 API ,旧版客户端也能用。

    第 1 条附言  ·  2022-12-22 14:29:17 +08:00
    说错了,刚看了下服务器上的是 Nginx 不是 Apache
    26 条回复    2022-12-24 00:48:32 +08:00
    zzzzzzy
        1
    zzzzzzy  
       2022-12-22 14:24:35 +08:00
    netty 限制每个客户端下载带宽
    edis0n0
        2
    edis0n0  
    OP
       2022-12-22 14:25:54 +08:00
    @zzzzzzy #1 服务器上没 java ,而且是 uptime 快 9 年的 centos4.8 我不敢装人家
    edis0n0
        3
    edis0n0  
    OP
       2022-12-22 14:26:04 +08:00
    @edis0n0 人家->软件
    CodeSorcerer
        4
    CodeSorcerer  
       2022-12-22 14:26:30 +08:00
    apache 的 qos 模块? https://mod-qos.sourceforge.net/
    XiLingHost
        5
    XiLingHost  
       2022-12-22 14:26:57 +08:00
    @edis0n0 java 不需要安装啊,你可以单独给个目录
    edis0n0
        6
    edis0n0  
    OP
       2022-12-22 14:31:06 +08:00
    @dailixin359 #4 刚看了下服务器上的是 Nginx 不是 Apache ,另外这个看起来是直接限速,不能限制一段时间内的下载次数
    PerFectTime
        7
    PerFectTime  
       2022-12-22 14:33:53 +08:00   ❤️ 1
    提供一个思路,加一台服务器放在前面用你想用的软件和编译的东西
    Lax
        8
    Lax  
       2022-12-22 15:15:45 +08:00   ❤️ 1
    nginx rate limit 可以搞。但是你这个周期偏长了,要考虑这个 location 的请求量,周期内请求量越多,会消耗越多的内存来保存限流状态。
    https://nginx.org/en/docs/http/ngx_http_limit_req_module.html
    GeorgeWai
        9
    GeorgeWai  
       2022-12-22 16:08:28 +08:00
    考虑用 iptables 试试
    nekoneko
        10
    nekoneko  
       2022-12-22 17:15:37 +08:00
    写个 nginx 插件?
    写个服务把现在的下载接管了, 在服务里面加逻辑?
    Jirajine
        11
    Jirajine  
       2022-12-22 17:47:02 +08:00
    那就直接用 php 接管那两个路由,自己实现判断逻辑
    edis0n0
        12
    edis0n0  
    OP
       2022-12-22 17:57:24 +08:00
    @Jirajine #10 不会 php ,这十几年前写的系统每个 php 都是一个入口不懂怎么加这种路由
    FrankAdler
        13
    FrankAdler  
       2022-12-22 21:21:06 +08:00 via iPhone
    用你能解决的方式实现,然后把这部分流量转发过去(用你能做到的方式)
    Jirajine
        14
    Jirajine  
       2022-12-22 22:41:03 +08:00
    @edis0n0 nginx/Apache 加个 rewrite 规则,或者弄个 latest.exe.php 这样的 filesystem based route ,具体看 cgi 怎么配的。
    yoloMiss
        15
    yoloMiss  
       2022-12-22 23:38:15 +08:00
    我理解你这个是否下载的判断是做在客户端的啊,那为什么不把这个单个小时内的下载次数限制也做在客户端呢?
    edis0n0
        16
    edis0n0  
    OP
       2022-12-22 23:53:31 +08:00
    @yoloMiss #14 有没可能客户端已经十年没发过更新了,大部分用户都在用旧版?
    zhensjoke
        17
    zhensjoke  
       2022-12-23 09:58:37 +08:00
    有没有可能把 latest.exe 改为一个语言脚本,比如 php ,
    然后在里边写代码判断请求 IP 的,符合条件的返回 exe 数据流。
    zhensjoke
        18
    zhensjoke  
       2022-12-23 10:09:19 +08:00
    配置 nginx 将*.exe 的请求交给 php 处理,
    V1Eerie
        19
    V1Eerie  
       2022-12-23 20:10:02 +08:00
    可以使用 nginx 的 limit_req 模块来实现每小时的限制下载。
    limit_req_zone $binary_remote_addr zone=one:10m rate=3r/h; 这将限制每个 IP 地址每小时进行 2=3 次下载请求。
    参考链接: http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
    可以自己在调整一下参数。
    jones2000
        20
    jones2000  
       2022-12-24 00:09:49 +08:00
    把升级包放到 CDN 上不就行了, 能用钱解决的事,不要用代码解决。回头 PPT 上写上使用分布式升级,高大上。
    edis0n0
        21
    edis0n0  
    OP
       2022-12-24 00:19:08 +08:00
    @jones2000 #19 先看下帖子“客户端下载失败就循环下载”,这样会产生天价账单
    jones2000
        22
    jones2000  
       2022-12-24 00:25:26 +08:00
    @edis0n0 用CDN可以避免下载失败。选择就近的节点下载,成功率更高。除非客户端网络有问题,或者是升级包太大了, 如果是升级包太大,把升级包切成几个小文件,下载到本地以后再合并覆盖客户端。
    jones2000
        23
    jones2000  
       2022-12-24 00:36:09 +08:00
    @edis0n0 如果是自建机房,升级服务器怎么可能是单台呢, 平时留3-4台做一个负载均衡,, 每次要上新版本是根据目前现在的客户量大致就可以算出高峰流量,提前调配好升级服务器和提升带宽,等升级高峰期过了,把多余的升级服务器下线,带宽就可以缩小。这些都是运维一个产品的基本的操作。
    edis0n0
        24
    edis0n0  
    OP
       2022-12-24 00:37:05 +08:00
    @jones2000 #21 客户端是屎山,盘满了、杀毒软件在扫描升级文件导致升级程序无法运行等一堆情况都会导致升级失败,用 CDN100%账单 6 位数
    edis0n0
        25
    edis0n0  
    OP
       2022-12-24 00:37:39 +08:00
    @jones2000 #22 非互联网企业,客户端 10 年前随便找的外包公司做的
    jones2000
        26
    jones2000  
       2022-12-24 00:48:32 +08:00
    @edis0n0
    1. 盘满了 客户端判断下,出一个提示框,然后程序退出,避免再满盘的情况下运行异常,给客户带来损失
    2. 杀毒软件,升级产品的时候把你的程序给个个杀毒软件都过审,只要过审了,就不会栏你了。
    3.上传升级失败异常信息, 如果升级失败了,上传日志给后台,可以方便开发分析。

    “客户端是屎山” 代码不行就重构,就改,天天说屎山,它是不会消失的, 只有一点一点改,最后这个屎山才能消失。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2856 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 06:49 · PVG 14:49 · LAX 22:49 · JFK 01:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.