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

请教大家一个接口延时处理的问题~

  •  
  •   godleon · 2022-05-18 20:19:23 +08:00 · 2134 次点击
    这是一个创建于 680 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求

    前 vue 后 springboot jdk1.8

    前端用户调后端一个生产数据的接口,这个接口要模拟延时操作,例如:要生产 100 条数据,我必须要让他 10 分钟以后才产出 100 条,但是页面请求完,不需要等待我的返回结果,可以随意操作页面其他功能,所以想请教一下,这种需求怎么满足一下,尽量不要给目前工作增加过多的代码量,如:配置 socket 建立连接等..
    

    ps:我是一个前端的小白~

    21 条回复    2022-05-19 13:52:26 +08:00
    vchroc
        1
    vchroc  
       2022-05-18 20:22:26 +08:00
    当然不是 setTimeout(fn, 10min)
    可以走延迟队列
    godleon
        2
    godleon  
    OP
       2022-05-18 20:25:33 +08:00
    @vchroc 相当于前端其实就是走异步,后端把接口加到延时队列里,是这个样子不
    vchroc
        3
    vchroc  
       2022-05-18 20:33:24 +08:00
    后端发送延迟队列,10min 后收到消息,生产 100 条数据
    Neil66
        4
    Neil66  
       2022-05-18 20:53:37 +08:00
    感觉跟使用消息队列一样。

    1. 前端调用接口,接口把这个任务放到消息队列中并返回状态码 202Accepted 和监控的 url 地址(无需监控任务状态,可省略监控 url 地址),表示任务已经添加到队列。
    2. 另一个程序轮训消息队列里的任务,处理符合条件的队列任务
    3. 任务处理成功后,反写最终状态(一般在第 1 步创建任务的时候会往数据库任务表里新建一条任务数据,待处理完任务后根据消息 id 反写任务最终状态)
    4. 如果需要获取任务的最终状态,前端通过另一个接口(监控的 url 地址)查询任务状态就可以。不需要获取监控任务状态这步可省略

    至于楼上说的延迟队列,可能跟消息队列差不多吧,只是可以将延迟时间作为条件筛选符合条件的队列任务,供 op 参考。

    对于延迟队列不了解,如有错误请各位指正。
    sunwei0325
        5
    sunwei0325  
       2022-05-18 20:58:48 +08:00
    redis zset
    aitaii
        6
    aitaii  
       2022-05-18 21:22:44 +08:00 via Android   ❤️ 1
    Redis key 十分钟消失,监听消失时间,异步处理
    aitaii
        7
    aitaii  
       2022-05-18 21:23:13 +08:00 via Android
    @aitaii 事件
    potatowish
        8
    potatowish  
       2022-05-18 21:42:57 +08:00 via iPhone
    后端维护一个对象,包含首次调用接口的时间戳和生产出的数据,调用接口时判断当前时间与时间戳之差大于等于 10min 则返回数据。
    godleon
        9
    godleon  
    OP
       2022-05-18 22:05:59 +08:00
    谢谢大家回复
    sparky
        10
    sparky  
       2022-05-18 23:01:10 +08:00 via Android
    ScheduledThreadPoolExecutor
    buxudashi
        11
    buxudashi  
       2022-05-18 23:07:38 +08:00
    走 websocket 啊。让它一直在线,时间到了再返回数据呗。有了数据再关掉 websocket 。
    marcojbk
        12
    marcojbk  
       2022-05-19 07:51:57 +08:00 via iPhone
    8 楼的和我思路一样,做两个接口,第一个接口记录开始时间,第二个查询大于设定时间的
    jifengg
        13
    jifengg  
       2022-05-19 09:25:56 +08:00
    说实话,楼主你的描述我看不出来你是要满足什么需求。
    你是想知道怎么模拟 10 分钟后产出 100 条数据?
    还是想知道怎么让前端能拿到这 100 条数据?
    还是其他的?
    godleon
        14
    godleon  
    OP
       2022-05-19 09:40:05 +08:00
    @jifengg 详细需求就是
    1.前端请求后端接口, 接口有两个操作 a.修改一个表的字段 b.生成 100 条数据插入到表里。
    2.前端请求完后,我的接口是会先改表状态,然后状态改完,延迟 10 分钟生产数据,在插入到表
    jifengg
        15
    jifengg  
       2022-05-19 09:44:03 +08:00
    @godleon 你业务的需求我了解。我问的是,你发这个帖子的“需求”是什么,你是碰到什么问题不懂要解决呢?
    你是想知道怎么模拟 10 分钟后产出 100 条数据?
    还是想知道怎么让前端能拿到这 100 条数据?
    还是其他的?
    litchinn
        16
    litchinn  
       2022-05-19 09:46:39 +08:00
    单机的话 java.util.concurrent.DelayQueue 就可以
    Felldeadbird
        17
    Felldeadbird  
       2022-05-19 10:41:12 +08:00
    我认为最简单做法:

    1. 用户发起请求后,你和后端沟通好,保留一个浏览器一次性的全局 token 。

    2. 不论用户切换到任何页面。ajax 带上 token 定时去查询上述数据。

    3. 当后端数据生成完毕了,你就在前端当前页面弹出一个对话框,告知用户刚才 10 分钟前请求的东西完成了。

    这里关键就是 setInterval 和 setTimeout 你怎么定义了。稳一点就用 websocket 等等技术。
    bthulu
        18
    bthulu  
       2022-05-19 10:59:09 +08:00
    10 分钟后需要告知前端吗? 不需要的话, 你就假装你延时生产了 100 条数据, 实际你啥都没干就行.
    xuelu520
        19
    xuelu520  
       2022-05-19 11:04:44 +08:00
    setTimeout 10 分钟后才请求接口,假装耗时 10 分钟。。。
    正常是走个延时队列就行了。这要看你们后端了。
    wangtian2020
        20
    wangtian2020  
       2022-05-19 13:16:05 +08:00
    业务问题

    前端接口通知后端立即执行操作
    后端接口立即返回前端,“我知道了,我在做了”

    界面弹窗,操作处理中,请等待约 10 分钟后刷新页面查看
    mosliu
        21
    mosliu  
       2022-05-19 13:52:26 +08:00
    DelayQueue 足以
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1092 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:52 · PVG 02:52 · LAX 11:52 · JFK 14:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.