monsterj
V2EX  ›  问与答

大佬们,那种 XX 天后过期改状态的需求,精确到秒,你们是咋设计的?

  •  
  •   monsterj · Apr 28, 2018 · 4252 views
    This topic created in 2965 days ago, the information mentioned may be changed or developed.

    想到几种, 1:定时器,一秒扫一次,感觉太频繁了吧; 2:mysql 定时任务+存储过程; 3:消息队列;

    26 replies    2018-04-29 11:59:04 +08:00
    nybux
        1
    nybux  
       Apr 28, 2018
    如果不涉及到查询,可以在显示的时候修改。
    monsterj
        2
    monsterj  
    OP
       Apr 28, 2018
    @nybux 后台管理肯定要涉及到查询的
    nybux
        3
    nybux  
       Apr 28, 2018
    时间是等长的嘛?
    kingname
        4
    kingname  
       Apr 28, 2018 via iPhone
    前台用 JS 做减法,后台不用频繁查,下次完全刷新的时候再更新就可以了。
    monsterj
        5
    monsterj  
    OP
       Apr 28, 2018
    @nybux 假如过期时间是 3 天
    gfreezy
        6
    gfreezy  
       Apr 28, 2018
    存在过期时间,然后状态根据过期时间算出来。
    monsterj
        7
    monsterj  
    OP
       Apr 28, 2018
    @kingname 这样只是考虑了前台用户展示的情况,有其他业务需要这个状态操作的话,就行不通
    kera0a
        8
    kera0a  
       Apr 28, 2018
    过期后
    第一个访问它的事件,触发更新操作~
    monsterj
        9
    monsterj  
    OP
       Apr 28, 2018
    @gfreezy 那就是第一种?每秒钟扫一次过期时间
    Weny
        10
    Weny  
       Apr 28, 2018 via iPhone
    延时队列 或者 定时任务 去处理
    sfree2005
        11
    sfree2005  
       Apr 28, 2018 via Android
    我的 web app 用的是 laravel 框架,用的是自带的 queue 和 schedule, 它可以将 queue 存于 Redis,每秒扫一下。因为是扫内存 所以速度快和资源占用少,感觉不错。
    monsterj
        12
    monsterj  
    OP
       Apr 28, 2018
    @kera0a 这样会代码冗余吧,还容易忘几加更新操作
    liuzelei
        13
    liuzelei  
       Apr 28, 2018
    redis ttl、mq delay exchange
    kera0a
        14
    kera0a  
       Apr 28, 2018
    @monsterj
    存过期时间的方法最好吧~
    “有其他业务需要这个状态操作的话,就行不通” ? 怎么会行不通呢? 是否过期服务器怎么用过期时间-当前时间呗,小于 0 就是过期了啊,不管什么地方都可用
    monsterj
        15
    monsterj  
    OP
       Apr 28, 2018
    @sfree2005 每秒扫内存可以接受
    monsterj
        16
    monsterj  
    OP
       Apr 28, 2018
    @kera0a 假如有一个过期时间,和一个状态,需要在过期后,修改状态,其他业务只需要查这个状态
    chenuu
        17
    chenuu  
       Apr 28, 2018
    redis 过期功能,过期会有键空间通知.
    af463419014
        18
    af463419014  
       Apr 28, 2018
    每 5 分钟扫一下
    5 分钟以内会过期的数据,每条数据启一个线程
    每个线程 sleep 对应数据的过期时间,然后修改状态为过期
    kera0a
        19
    kera0a  
       Apr 28, 2018
    @monsterj 其他业务不能查过期时间么?
    其实这个主动更新状态并不好,假如你有 N 个状态需要更新,而你的服务器运行速度慢,不能在 1 秒内更新完毕,那不就出 BUG 了。假如需求变更,需要兼容到毫秒,那就更加不好了。
    你往存过期时间这靠,如果实在靠不了,可以试试我说的懒更新,如果还靠不了
    各种定时任务框架了解一下~
    kslr
        20
    kslr  
       Apr 28, 2018
    延时队列
    watzds
        21
    watzds  
       Apr 28, 2018 via Android
    如果 Java,有定时任务 jar quartz,这点性能肯定不用担心
    msg7086
        22
    msg7086  
       Apr 28, 2018
    从面相对象的角度考虑,这个状态是由对象表达出来的,对象本身既可以从数据库中查询,也可以通过比较过期时间和当前时间得出。
    比如函数 obj.expired?,可以这样写
    def expired?
    self.expired or (self.expired = expire_date < now) and self.save
    end

    我会选择避免用面向过程的方法去思考这个问题(用第三方的线程去扫描修改状态什么的)。
    wplct
        23
    wplct  
       Apr 28, 2018
    参考 redis 过期,取值时确认该值是否过期,配合定时任务(人家 redis 的定时任务执行多久是算 cpu 时间的,学不来学不来)
    onedayonecode
        24
    onedayonecode  
       Apr 28, 2018
    数据库存储过期时间,用到的时候读出来和当前时间对比
    projectzoo
        25
    projectzoo  
       Apr 28, 2018
    我也是建议读取的时候再处理,不读取就不处理。
    liuzhaowei55
        26
    liuzhaowei55  
       Apr 29, 2018 via iPhone
    存过期时间,读取的时候判断。和 Redis 的过期判定差不多,但是没 Redis 的那么复杂。
    消息队列也有做。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1142 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 58ms · UTC 23:11 · PVG 07:11 · LAX 16:11 · JFK 19:11
    ♥ Do have faith in what you're doing.