V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
mystical
V2EX  ›  程序员

忍不了,必须来吐槽一下,和我对接的同事 or 系统。

  •  
  •   mystical · 14 小时 56 分钟前 · 1469 次点击
    说在前面:为了项目、也为了同事的和睦,我也不能强制对方修改他们的代码,只能配合。

    槽点 1:请求并发发送。
    并发发送请求本质上没问题,可以减少高客户端的相应时间。但是接口有依赖关系的也使用并发发送是不是有点扯,线上天天一堆 bug 。
    例子:请求 A 返回数据 a ,请求 B 需要使用请求参数 a 请求,返回数据 b 。然后并发发送,A 发出去了,不等结果发送 B ,发现 a 参数没有,直接扔给我一个默认值。(乱七八糟什么都有可能,x ,y ,z ,喜洋洋、灰太狼)

    槽点 2: 错误码不能返回错误码
    接口返回值有标准格式 {"code":0 ,message:"success",result:"balabala"}。格式很标准,他们很认同,但是遇到异常情况,比如参数错误,数据为空,没钱了,涨价了,这种错误,code 只能用 0(阿西吧~~~~)。
    那信息怎么处理呢? 再套一层{"code":0 ,message:"success",result: {"status":1,message:"参数错误"}}

    真的头秃
    18 条回复    2025-09-12 18:43:50 +08:00
    shakukansp
        1
    shakukansp  
       14 小时 54 分钟前
    有点东西,这是第一天写项目?
    JoeJoeJoe
        2
    JoeJoeJoe  
    PRO
       14 小时 49 分钟前
    槽点 1 没问题, 这已经不是槽点了, 是逻辑错误了.

    槽点 2 也没啥问题, 但是我想引申一点我的小思考:

    我觉得前后端商量好错误码的对应表, 不要把错误信息放在返回里面是比较安全的. 这样就算有人抓接口报错了, 因为没有具体的错误信息, 会让抓接口的难度稍微高一点.
    mystical
        3
    mystical  
    OP
       14 小时 46 分钟前
    还有有个更狠的。接口重试。
    一般接口重试都要做个限制或者幂等。这可好,直接 while 循环。遇到过最离谱的一次崩溃是这样的
    客户端发送一个提交一个 A 包含数据 a 。(正常情况下服务器处理完了就处理完了,几十毫秒就能搞定的)但是那天机器的 redis 不太稳定,有那么 300ms 的延迟。。然后事情就发生了

    客户端发现 请求 A1 发送的 a 没有提交成功,就把请求 A 放入请求队列,(不知道他们怎么操作的有 2 个队列,一个请求队列,一个数据队列)
    几秒后发送了两个个请求 A1 包含数据 a 和 A2 包含数据 aa (此时服务器其实已经被别的客户端打崩溃了,肯定无法相应)
    几秒又发送了 3 个请求 请求 A1 包含数据 a 、请求 A2 包含数据 aa 请求 A3 包含数据 aaa
    然后就这么持续了很长很长时间。。。
    服务器为什么崩溃呢? 懂后端的,应该都能明白。我们的客户端设备日活几十万。请求流量突然从 50Mb/s 激增到 1000MB/s (为什么是 1000 呢?因为带宽就这么高)。流量是高峰期的 2000 倍(其实就是因为带宽不够,请求进不来)
    mystical
        4
    mystical  
    OP
       14 小时 42 分钟前
    @JoeJoeJoe 这应该是标准流程吧,一个鲁棒、安全的系统必须有的。错误码肯定都是脱敏的,只要是非法请求,统统是系统错误 or 参数错误,只有一些特殊情况,返回一些特殊数字,客户端解包进行下一步处理。
    Dalivk
        5
    Dalivk  
       14 小时 38 分钟前
    日常工作就是屎山雕花,没有 bug 后续怎么提优化需求...
    yvyvyv
        6
    yvyvyv  
       14 小时 12 分钟前
    @mystical #3 这种无限循环重试 有种自己人攻击自己人的感觉
    mystical
        7
    mystical  
    OP
       14 小时 2 分钟前
    @yvyvyv 那天我们的运维老大找我聊天,get 到问题点后,说了一句。我们拥有全球最牛逼的压测平台。
    bbbblue
        8
    bbbblue  
       14 小时 0 分钟前
    第二个有种脱了裤子放屁的美...
    本身用这种结构就是业务层面区别业务正常和异常的。。。
    litchinn
        9
    litchinn  
       13 小时 59 分钟前
    我觉得你们的系统能跑满 1G 的带宽还是有点实力的 doge
    realJamespond
        10
    realJamespond  
       13 小时 45 分钟前
    没用 swr 么?
    realkaiway
        11
    realkaiway  
       13 小时 5 分钟前
    问题一:接口相互依赖,重试,缓存,乐观更新,状态管理这类的场景让你们前端尝试下 Tanstack Query , 有效减少扯皮的空间,专注业务。

    问题二:前端项目改造下 HTTP 请求类方法就行,把 code===0 作为正确的结果返回,其它一律作为异常抛出 message 不就行了?严格来说应该优先判断 HTTP 的状态码,在辅以业务码判断,但不得不说能跑满 1G 带宽,这屎山代码还是有点实力的
    mystical
        12
    mystical  
    OP
       13 小时 0 分钟前
    @realkaiway 对方是客户端,app ,安装在用户手机里的。几十万个设备,同时这样发请求,流量能不大么。我还是不建议了,他们好像不愿意改历史代码,只在自己的模块改东西。
    mystical
        13
    mystical  
    OP
       12 小时 58 分钟前
    @litchinn 我是接收方,nginx 接受能力比较强,后代的网管和服务就惨了,cpu100%,线程池和队列全满了,根本处理不过来。nginx 上全是 500 错误。对方是客户端,几十万台手机,循环产生 1g 的请求还是比较容易的,而且还是 post ,上报数据,请求体本来就大。
    pulutom40
        14
    pulutom40  
       12 小时 54 分钟前 via iPhone
    这不是日常吗?

    1.提 bug 单督促改呗,不行就 cc 双方领导,保证自己不粘锅就行了
    2.基操基操,都是正常操作,你让他们改,他们会说他们也是调 xxx 接口转发 or 网关 xxx or 历史 xxxx ,反正就是改不了你凑合用吧,也就多写几个 if 而已,又不是不能用
    mystical
        15
    mystical  
    OP
       12 小时 49 分钟前
    @pulutom40 我只是想吐槽,cc 领导已经没啥用了。偶尔一次两次我也不会来吐槽,这么多年了经常这样。我领导也说,做好限流,别让自机的服务崩掉就行,不行加机器。。。乏了
    pulutom40
        16
    pulutom40  
       12 小时 40 分钟前 via iPhone
    @mystical cc 领导不是为了有用,而是为了甩锅,风险暴露出来让领导知道就行了,跨部门他不去沟通,出问题他背锅就行了
    Dorathea
        17
    Dorathea  
       12 小时 28 分钟前
    "例子:请求 A 返回数据 a ,请求 B 需要使用请求参数 a 请求,返回数据 b 。然后并发发送,A 发出去了,不等结果发送 B ,发现 a 参数没有,直接扔给我一个默认值。(乱七八糟什么都有可能,x ,y ,z ,喜洋洋、灰太狼)"
    不太能理解这种场景为什么也要并发
    如果请求 B 需要 A 的返回, 那么并发请求 A 和 B 性能上的好处只在于服务器处理完 A 请求且服务器收到 B 请求前的这个时间间隔吧? 能想到几种办法优化且更规范的.

    那么 OP 是怎么应对的, 最后是什么情况好像没说诶.
    mystical
        18
    mystical  
    OP
       12 小时 3 分钟前   ❤️ 1
    @Dorathea 本意是吐槽,我完整的表述一下。不便说太细,有问题可以留言

    场景:很多,比如启动预加载信息,进某个页面批量获取信息。批量调用是合理的也是正确的。

    问题: 后续加入的新 api 有依赖关系,app 框架依然使用批量调用,这扫问题点

    优化方案: 很多,举几个
    1. 最简单的就是 app 不在批量线程里执行,等待 A 的数据拿到之后再请求 B 接口
    2. 后端代理执行,前端请求 A 和 B ,B 不使用 A 的参数,后端代理客户端再请 A 一次,
    3. 后端察觉的请求数据 不对,返回客户端参数异常,等客户端拿到 A 的接口再次重试(很糟糕的方案)

    最后措施:方案 3 ,客户端依然批量执行,如果没取到,后端 api 报错,前端重试,直到成功

    last
    方案 1:其实说到最后,就是原有的批量执行方案不可修改。至于为啥不可修改我也不得而知。
    方案 2:为啥后端不代理执行,因为两个机器中间隔了一个太平洋,又完全不是一个系统,考虑到用户各种隐私都需要上报太过笨重。话说归来,问题也不是从后端引发的。
    方案 3:为啥选择重试呢? 我也想问,可能这样开发量最小吧。3 楼我提出的问题就是这样产生的。

    我做了那些事: 无非就是增加网管鲁棒性,限流,等等后端常用的技术方案

    ps: 上面打错了 流量是 1000Mb 打错单位了。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   935 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:47 · PVG 06:47 · LAX 15:47 · JFK 18:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.