背景:
我正在构建一个应用程序,所提出的架构是基于微服务架构的事件/消息驱动架构。
做事情的单一方式是,我有一个 User/HTTP request
,它的行动一些命令,有一个直接的 synchronous response
。因此,响应相同的用户/HTTP 请求是“免费的”。
问题是:
用户向 用户界面服务(有多个 UI 服务)发送一个 HTTP request
,它会向队列(Kafka/RabbitMQ/any)发送一些事件。一个 N 的服务拾起事件/消息做一些魔术一路上和 然后在某个时刻,同一个 UI 服务应该获取响应,并将其返回给发出 HTTP 请求的用户。请求处理是 ASYNC
,但是 User/HTTP REQUEST->RESPONSE
是 SYNC
根据您的典型 HTTP 交互。
问题: 在这个不可知/事件驱动的世界中,我如何向发起动作的同一 UI 服务(通过 HTTP 与用户交互的服务)发送响应?
目前为止我的研究 我一直在观察,似乎有些人正在用 WebSocket 解决这个问题。
但是复杂性层是需要一些映射 (RequestId->Websocket(Client-Server))
的表,这些表用于“发现”网关中哪个节点具有针对某些特定响应的 websocket 连接。但是即使我理解了这个问题和复杂性,我仍然找不到任何文章来告诉我如何在实现层解决这个问题。这仍然不是一个可行的选择,因为第三方集成,如支付提供商(世界支付) ,期望 REQUEST->RESPONSE
-特别是在3DS 验证。
所以我不愿意认为 WebSockets 是一个选项。但是,即使 WebSocket 适用于面向 Web 的应用程序,对于连接到外部系统的 API 来说,也不是一个很好的架构。
我不知道你在说什么
即使长轮询是使用 202 Accepted
a Location header
和 retry-after header
的 WebService API 的一种可能的解决方案,它也不适用于高并发性和高能力的网站。
想象一下,大量的人试图获得每个请求的事务状态更新,你不得不使 CDN 缓存失效(现在就去解决这个问题吧!哈)。
但是最重要的和我的案例相关的是我的第三方 API,比如支付系统,3DS 系统有自动重定向,由支付提供商系统处理,他们期望一个典型的 REQUEST/RESPONSE flow
,因此这个模型对我不起作用,套接字模型也不起作用。
因为这个用例,HTTP REQUEST/RESPONSE
应该按照典型的方式进行处理,其中我有一个哑客户机,它期望在后端处理进程的复杂性。
因此,我正在寻找一种解决方案,其中外部我有一个典型的 Request->Response
(SYNC) ,并且状态的复杂性(系统的 ASYNCrony)在内部 处理
这是一个长轮询的例子,但是这个模型不适用于第三方 API,比如 3DS Redirects
上不在我控制范围内的支付提供商。
POST /user
Payload {userdata}
RETURNs:
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Date: Mon, 27 Nov 2018 17:25:55 GMT
Location: https://mydomain/user/transaction/status/:transaction_id
Retry-After: 10
GET
https://mydomain/user/transaction/status/:transaction_id