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

给大家乐呵一下

  •  2
     
  •   lwldcr · 2024-05-07 11:39:48 +08:00 · 5613 次点击
    这是一个创建于 420 天前的主题,其中的信息可能已经有所发展或是发生改变。

    无名小厂,流程不规范,一般都是自己 own 一个项目,开发&上下线,QA 参与度不高。

    1. 跟他共事快 2 年,他离职后交接了 2 个项目给我,另 1 个项目给其他人

    2. 他交接给我的一个项目,是给其他团队输出数据的接口,对面的人大概每隔 1 、2 周来找我说没数据了,我不知道他在的时候是怎么维护的,这个项目在我这里不算重要而且事情也确实太多没精力细察,每次来找就重启一下。后来干脆搞了个定时重启,再没来找过了。

    3. 另一个项目是 toc 的,有一天突然没数据了。后来经过一番检查,发现他在项目里面有一些这样的设计和实现:

      • 限制全局的 goroutine 数量,超出某个值后不再接收数据而是返回 500 。这个阈值我猜测是拍脑袋想的
      • 在处理请求的函数内,用 1 个异步函数处理数据,函数内先做加锁,然后再起个 goroutine 负责超时/处理完成后解锁操作,类似于
      var lk sync.Mutex
      done := make(chan struct{})
      go func() {
      	lk.Lock()
      	go func() {
      		select {
      			case <-time.After(3 * time.Second):
      			case <-done:
      			}
      	lk.Unlock()
      	}()
      // 处理数据
      done <- struct{}{}
      }()
      

      一旦处理数据超时,就 hang 在发送 done 信号那里,导致 goroutine 数量缓慢增加,直到触发他设定的阈值。更绝的是这个问题短期内不会暴露,压测的时候资源给的也很足,没有发现。实际上线的时候,长时间运行下来导致这个问题最终暴露,拉长监控面板一看内存占用真是稳步线性增长。

    4. 近日又发现项目依赖的 db 总是高水位报警,昨天链接上去看了下,发现所有的表没有索引,而程序需要定时对表进行 select 、insert 、update 等操作。拉长面板到 90 天范围一看,占用率也是缓慢线性升高

    如何评价?别有用心还是真的就这水平。我估摸着让我来写,大概率是写不出这个不定时炸弹的。

    37 条回复    2024-05-15 09:47:11 +08:00
    pota
        1
    pota  
       2024-05-07 11:51:56 +08:00
    应该就是用心写了 bug
    zhtyytg
        2
    zhtyytg  
       2024-05-07 11:56:13 +08:00   ❤️ 4
    你开头也说了,无名小厂,招的无名打工人,水平参差不齐正常的
    wxw752
        3
    wxw752  
       2024-05-07 11:57:30 +08:00
    很正常,去年裁员接的烂摊子现在还时不时踩雷呢
    dj721xHiAvbL11n0
        4
    dj721xHiAvbL11n0  
       2024-05-07 11:58:03 +08:00
    挺恶心的
    cryboy007
        5
    cryboy007  
       2024-05-07 12:02:09 +08:00
    学到了
    jjtang11
        6
    jjtang11  
       2024-05-07 12:27:27 +08:00
    “一旦处理数据超时,就 hang 在发送 done 信号那里”这句我没理解,你的意思是超时后不但要解锁,而且还要退出 goroutine 是吗
    webcape233
        7
    webcape233  
       2024-05-07 12:53:21 +08:00 via iPhone
    不是很懂 异步处理里面锁着等待到完成才解锁? 那为什么不同步处理了
    yustation
        8
    yustation  
       2024-05-07 13:17:33 +08:00
    初学者求问,主键本身是索引列吗,如果只有主键有唯一约束,需要显式对主键建立索引吗,主用 pgs
    yustation
        9
    yustation  
       2024-05-07 13:18:30 +08:00
    @yustation pgsql - O -
    ktyang
        10
    ktyang  
       2024-05-07 13:24:19 +08:00
    学到了
    R18
        11
    R18  
       2024-05-07 13:26:10 +08:00
    @jjtang11 它的 done 是个无缓冲区的,产生就要消费(当然有缓冲区也会产生这个 bug )。异步里边要是超时代码直接退出,就少了一个消费者,就等于处理数据的那层 goroutine 最后的 `done <- struct{}{}` 会产生阻塞。
    rm0gang0rf
        12
    rm0gang0rf  
       2024-05-07 13:29:20 +08:00
    挺好的, 学到了
    tlxma
        13
    tlxma  
       2024-05-07 13:31:09 +08:00
    挺好的, 学到了
    blessingcr
        14
    blessingcr  
       2024-05-07 13:36:07 +08:00
    挺好的, 学到了
    huangyua
        15
    huangyua  
       2024-05-07 13:40:00 +08:00
    挺好的,学到了
    danhahaha
        16
    danhahaha  
       2024-05-07 13:56:47 +08:00   ❤️ 5
    挺好的,对面人稳定 1-2 周来联络下感情,这边也显示下存在感,现在好了,俩人都可有可无了
    meeop
        17
    meeop  
       2024-05-07 14:35:02 +08:00   ❤️ 1
    这个就是优秀的面相岗位开发的代码了,可以在合法的情况下做到:
    1 人在系统没事,且不增加很多维护成本
    2 人不在系统就定时失效,甚至爆炸

    学习了
    meeop
        18
    meeop  
       2024-05-07 14:42:29 +08:00
    总结一下就是设计一些缓慢进行的内存泄漏和性能劣化,同时设置到达终点就触发的炸弹

    平时通过手动或者自动方式定时重启计时,保证系统稳定

    如果人突然不在了,就会定时爆炸
    同时你还说不了啥,毕竟代码有点性能问题很正常
    Tink
        19
    Tink  
       2024-05-07 14:45:55 +08:00
    应该是水平刚好也就是这样,然后也能过 QA ,就上线了
    poembre
        20
    poembre  
       2024-05-07 14:56:54 +08:00
    防御性编程, 一旦处理数据 超过 3 秒 chan 写不进去数据。 grouting 结束不了一直占着内存。 巧的事这哥们把锁给释放了。 只要内存够用不影响下个用户。 然后就是 静静地等待,下游业务过来请客吃饭。 吃完饭服务重启 接着等下一顿饭 联络感情
    0Z03ry75kWg9m0XS
        21
    0Z03ry75kWg9m0XS  
       2024-05-07 14:58:30 +08:00
    挺好的,学到了
    hellomsg
        22
    hellomsg  
       2024-05-07 15:27:18 +08:00
    我要是你,我就默默的改 bug 了
    TrigVon
        23
    TrigVon  
       2024-05-07 15:32:40 +08:00
    挺好的,学到了
    forbreak
        24
    forbreak  
       2024-05-07 16:05:23 +08:00
    挺好的,学到了。 系统不定时出问题,老板会感觉不到你存在的价值。
    zylll520
        25
    zylll520  
       2024-05-07 16:06:57 +08:00
    这种操作真的是学到了!!!
    lambdaq
        26
    lambdaq  
       2024-05-07 16:09:28 +08:00
    这不是防御性编程啊。是面向岗位安全编程。
    zackzergzeng
        27
    zackzergzeng  
       2024-05-07 16:27:58 +08:00
    学到了,最好藏的问题就是性能问题🤪
    ahaooahaz
        28
    ahaooahaz  
       2024-05-07 16:31:04 +08:00
    @R18 要是 done 有缓冲区也会产生这个 bug ,这个没太理解,有缓冲区不是就不会阻塞了吗
    R18
        29
    R18  
       2024-05-07 16:33:32 +08:00
    @ahaooahaz 但是缓冲区也有满的时候啊,满了还是会阻塞。他这个相当于只要超时一次,就会有一个写入无法消耗。
    jerry0531
        30
    jerry0531  
       2024-05-07 16:36:37 +08:00
    挺好的 学到了
    xxxccc
        31
    xxxccc  
       2024-05-07 16:38:10 +08:00
    @jjtang11 理论上 它直接 close 那个 channel 就行了
    NoOneNoBody
        32
    NoOneNoBody  
       2024-05-07 16:43:43 +08:00
    评价是:你知道他为什么走的,但不知道他是怎么来的
    z1154505909
        33
    z1154505909  
       2024-05-07 17:08:09 +08:00
    学习了,以后可以借鉴一下
    darksword21
        34
    darksword21  
       2024-05-07 18:31:23 +08:00
    这操作真的无敌
    zong400
        35
    zong400  
       2024-05-08 08:41:34 +08:00
    这个是不是也能理解成,一个耗时操作只等 3s ,处理不完也不阻塞下一个,哈哈
    guanzhangzhang
        36
    guanzhangzhang  
       2024-05-10 12:53:49 +08:00
    要是我就直接改了,这种开发真让同事和运维心累
    Xinu
        37
    Xinu  
       2024-05-15 09:47:11 +08:00
    这个 bug 我写过,场景都类似,超时以后忘记回收协程了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6007 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:05 · PVG 10:05 · LAX 19:05 · JFK 22:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.