wa8n
V2EX  ›  Java

Java http 请求中如何处理外部回调?

  •  1
     
  •   wa8n · Jun 23, 2021 · 3834 views
    This topic created in 1963 days ago, the information mentioned may be changed or developed.

    我的服务(A)部分功能依赖于外部服务(B),A 向 B 发送 http 请求时,B 会立即返回“提交成功”,等 B 处理完成后才会回调 A 返回我想要的数据。
    B 服务不具备修改为同步返回的条件。 当用户访问 A 时,我想返回 B 回调的结果,请问怎么实现? 目前想到两种方式:

    • 1.在 A 请求 B 过程中,A 阻塞等待 B 返回结果,然后返回用户。
    • 2.A 请求 B 后直接返回用户结果,然后用户再使用轮询方式从 A 获取结果。

    或者还有没有其他更好的方式?写惯了同步代码,现在换种方式不知道咋搞了

    Supplement 1  ·  Jun 24, 2021

    感谢各位大佬出谋划策,汇总下解决方案:

    1. A使用阻塞的方式直到获取到B的回调才返回
      • 逻辑简单,变异步为同步
      • 响应时间不确定,影响用户体验
    2. A调用完成后直接返回用户“提交成功”,之后由用户侧进行轮询
      • 响应迅速,实现简单
    3. A调用完成后直接返回用户“提交成功”,B回调后通过http2/websocket方式通知用户侧
      • 响应迅速
      • 实现难度较2大
    18 replies  •  2021-06-24 13:51:23 +08:00
    zm8m93Q1e5otOC69
    zm8m93Q1e5otOC69
    Jun 23, 2021❤️1
    1
    B 是异步的呗?方法 1 吧,连接不断等着 B 返回真正的结果
    hdiwhsg
    hdiwhsg
    Jun 23, 2021❤️1
    2
    建议用户轮询方式获取结果
    illuz
    illuz
    Jun 23, 2021 via Android❤️1
    3
    1 用户体验不行,一般用轮询。
    如果执行结果 A 需要记录,不要等用户端轮询再去调用 B,最好还是在 A 服务器自己做轮询,这样用户响应也比较快。
    dbpe
    dbpe
    Jun 23, 2021❤️1
    4
    (业务上一定要同步的堵塞住么?优雅点不应该是消息通知么
    yitingbai
    yitingbai
    Jun 23, 2021❤️1
    5
    如果时间就几秒钟建议用方法 1, 这样逻辑也简单
    hdiwhsg
    hdiwhsg
    Jun 23, 2021
    6
    如果非要做成同步的也不是不行,可以把用户轮询改成 A 系统替用户轮询,具体怎么轮询?
    1.A 系统调用 B 系统的接口之后,可以去轮询一个 redis 的占位符。
    2.B 系统回调 A 系统的过程中,A 系统的逻辑就是更新这个占位符,把占位符的状态更新成已有结果。
    3.第一步的逻辑这时候就轮询到这个占位符的状态是已有结果,就可以返回给用户了
    Puteulanus
    Puteulanus
    Jun 23, 2021❤️1
    7
    轮询吧,类似接入第三方支付的,虽然也可以支付成功之后那边回调这边,不过我看他们文档好像都写的这种不保险,建议自己轮询支付状态,至少混合
    ikas
    ikas
    Jun 23, 2021❤️1
    8
    你这个其实与 b 没有关系,如果 A 提供的一个长时服务,也会这样.
    1.可以用轮询通知
    2.可以用 http2 推送
    3.A 使用使用异步连接,当 A 拿到数据后,找到其对应的连接,写回,这种一般我们做设备相关连接经常用
    jeffxjh
    jeffxjh
    Jun 23, 2021❤️1
    9
    websocket 你值得拥有
    LuckyLight
    LuckyLight
    Jun 23, 2021❤️1
    10
    用户和服务 A 之前使用长轮询,服务 A 收到服务 B 的回调后返回给用户结果
    Jirajine
    Jirajine
    Jun 23, 2021 via Android❤️1
    11
    一般来说由用户端轮询,因为网络环境不确定,各种推送通知不一定可靠。
    rockyliang
    rockyliang
    Jun 23, 2021❤️1
    12
    不建议使用第一种方法,假设 B 服务回调需要等 1 分钟,难道你要用户在那里干等 1 分钟什么事情都不能做吗,体验太差了,而且时间拖太久的话,也会引发前端超时
    strawberryBug
    strawberryBug
    Jun 23, 2021 via Android❤️1
    13
    你们没有中间件吗? B 处理完发 mq,A 订阅 ma 拿处理结果,好处就是解耦,后续接入其他服务直接订阅消息就行。或者 B 处理完直接回调 A 的接口
    nvkou
    nvkou
    Jun 24, 2021 via Android❤️1
    14
    跟 b 没关系
    a 阻塞客户不现实。直接返回提交成功就是
    回调来了再推送通知或更新状态等用户下次查询

    为啥非要及时主动给用户信息,这是业务问题吧。跟查快递一样
    zifangsky
    zifangsky
    Jun 24, 2021❤️1
    15
    websocket 的典型用途
    wa8n
    wa8n
    OP
    Jun 24, 2021
    16
    @beichenhpy #1 B 是异步的,处理完后回调 A 。这种方式逻辑最简单,达到了异步变同步的效果,但是确实会有楼下说的问题,阻塞时间不确定,影响体验。

    @dbpe #4 不一定是同步,达到效果就行,综合下来看 websocket/http2 推送是个不错的选择。

    @hdiwhsg #6 这个确实是最直接的方式,我先试试。

    @rockyliang #12 我确实忽略了还有这种情况了。

    @strawberryBug #13 因为 B 是外部服务,不受我控制,现在确实也是 B 处理完以后回调 A 的。

    @nvkou #14 同步方式写代码先入为主了,我的思路有问题。
    a719031256
    a719031256
    Jun 24, 2021
    17
    这里的用户体验应该是指用户想获取到的服务,而不是响应速度
    正确的做法我认为应该按 1 来处理是很合适的,等待信息的过程可以让前端做得更漂亮点就行
    shangfabao
    shangfabao
    Jun 24, 2021
    18
    @hdiwhsg 是个方案,用户查询的时候去查 redis 处理也是可以的,消耗也比较少
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1844 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 75ms · UTC 09:19 · PVG 17:19 · LAX 01:19 · JFK 04:19
    ♥ Do have faith in what you're doing.