现有老大需求, 原先同步的接口改为异步的基于消息队列改造的接口, 这意味着一个原先的查询接口不能实时地返回数据, 现在问题是,前端查询页面是否得定时去抓未来可能的查询结果?是否得 ajax 轮询才能实现?
1
opengps 2020-08-27 15:55:15 +08:00
用消息队列提供查询结果??这个操作有点迷,你怎么确定 A 查询的结果 不是从队列里消费的 B 的查询结果?
|
2
rainbirda 2020-08-27 15:59:05 +08:00 via Android
可以开个 websocket,等消息队列消费后,向 websocket 返回数据,应该是可行的
|
3
killergun 2020-08-27 16:01:58 +08:00
看对实时性的要求,没有要求就轮询呗,有的话就需要实时通知了
|
4
awesomelei OP @opengps 生产的时候加个唯一字段, 然后消费的时候带上这个字段值来保证对应关系,哈哈哈
|
5
littlewing 2020-08-27 16:05:35 +08:00 via iPhone
异步也不需要消息队列啊
|
6
awesomelei OP @opengps 就是一个老接口改成 2 个消息系统 topic, 一个请求, 一个响应
|
7
dzdh 2020-08-27 16:09:48 +08:00
输出任务 id 然后轮询 id 结果?
|
8
kiracyan 2020-08-27 16:11:13 +08:00
看你业务咯 有实时要求就 Websocket 没有就轮询
|
9
opengps 2020-08-27 16:19:24 +08:00
@awesomelei 你消费了之后,比如说 A 消费了 B,那么 B 再去消费的时候就没有 B 的结果了
|
10
676529483 2020-08-27 16:36:16 +08:00
感觉应该是基于缓存去查询,基于消息队列去同步变化的数据
|
11
Rush9999 2020-08-27 16:37:59 +08:00
关键字 你用的消息队列+Request-Reply
如 nats 的 https://docs.nats.io/nats-concepts/reqreply rocketmq 的 https://github.com/apache/rocketmq-spring/wiki/Request-reply-message-exchange-pattern |
12
Varobjs 2020-08-27 17:06:05 +08:00
这样搞?
------------------------------------------------------------------ 接口每次查询缓存是否有数据 有:直接返回 没有:发送刷新缓存的消息,返回空? 消息消费进程收到消息,请求 db | api 获取数据,丢进缓存 ------------------------------------------------------------------ |
13
xuanbg 2020-08-27 17:57:04 +08:00
在接口响应特别慢的前提下,是应该先返回一个任务 id,然后用这个 id 轮询另一个接口获取数据。
|
14
oneisall8955 2020-08-27 22:50:13 +08:00 via Android
额,我司用的骚操作。整个流程如下:前端 A 调用后端 B,B 后端发异步消息给 C,C 接口很慢,C 有结果再异步发回给 B 。A 如何得到结果呢,前端说不能 ajax 轮询,也不能用 websocket,又不允许 B 阻塞
目前解决办法是:A 分两次请求,第一次请求使用 requestId 请求 B 的预查询接口,B 用消息中使用这个 ID 发消息给 C,C 结果消息再返回这个 ID,B 得到结果存带过期时间的缓存。 A 发完第一次请求后立即使用 ID 请求 B 的获取结果接口,B 用谷歌的重试库,10 秒内自动随机 10 次从缓存中获取结果,获取不到就是失败。 重试次数和时间都需要按照业务来估计,觉得这个方案还是很复杂。。。说到底第二次请求 B 也阻塞最多 10 秒了吧只是自动重试而已 |
15
no1xsyzy 2020-08-28 14:09:26 +08:00
@opengps #1 #9 转 token-based CPS 就行了,A 根本消费不到 B,甚至不知道还有 B
实践上可以是单独设置 topic,或者根据每个前端设置 topic @awesomelei #0 经典四种:轮询、长轮询、SSE 、WebSocket opendota 的分析请求就是轮询。 |