带有来自不同服务器的响应的 HTTP 请求/响应

HTTP request / response with response from a different server

在 HTTP request/response 场景中,我想响应请求的客户端并不重要(无论如何他会怎么说)。

简而言之,我想从这里开始:

Client
 ↓   ↑
 Nginx
  ↓   ↑
  ServerA
   ↓   ↑
   ServerB

对此:

Client
 ↓    ↑
 Nginx ↖
  ↓      ↖
  ServerA  ↖
   ↓      ↗
   ServerB

由于serverB已经有response,不做额外处理,所以我想绕过serverA,但如果可能的话应该通过nginx(例如使用压缩)。

具体来说,我想了解更多:

一个小示例 非常 欢迎(最好是 Clojure、Scala、Java、Node.js - 只要可读的任何语言)。

在 HTTP request/response 情况下,我唯一能看到的是通过一些 HTTP 服务器推送。问题是您将至少使用 TCP 连接进行 Client/Nignx 通信。我想您可以使用某些技术来做到这一点 "fire and forget",但是您随后需要能够打开与客户端的新连接以向其发送新数据。

在您的第一种情况下,每个服务都通过请求并等待响应来进行通信。

在第二种情况下,您可以做一些代理请求(无需等待任何响应),但有一些关于客户端的信息,以便能够在服务器 B 内联系它(打开连接)。

我不知道哪种技术最适合这个,但这是我要走的方向。

如果所有这些连接都是 HTTP 请求,除非您自己实现某种 man in the middle 场景,否则这对客户端来说很重要。

基本上,由于 TCP 连接的性质,HTTP 协议使用它在线上传输数据,客户端和服务器试图确保每条消息都传递到它的预期目标并且按顺序传递。

您可以研究 TCP 协议以更好地了解其局限性。 This 视频似乎是总体概述的良好开端。在视频中的 8:23 处,它做了一个类比,TCP 有点像 phone 对话,这就是为什么很难在中间 'conversation' 更改服务器或客户端,因为它不是那样设计的.

与在 phone 调用中一样,尽管您可以重定向请求,因此您可以使用 HTTP 重定向来实现您描述的预期效果。

我相信你的案例可以用 nginx-clojure 来实现。去年有人用 nginx-clojure 做了类似但更复杂的事情。并且serverA和ServerB之间的协议交换没有任何关系。

  1. 在 nginx 内容处理程序中,使用 hijack! 获取 NginxHttpServerChannel ch,将 ch 放入映射中,键为 req-uuid。所以我们可以使用ch稍后发送响应数据。发送nginxurl、req-uuid等数据给ServerA.
  2. ServerA向ServerB发送nginx-urlreq-uuid等数据
  3. ServerB发送req-uuid并通过另一个url响应nginx,这与第一步不同,例如'/asynNotfifyHandler'
  4. 编写另一个 nginx 内容处理程序以接收 ServerB 对位置“/asynNotfifyHandler”的响应。如果 nginx 工作进程只有一个,则在此处理程序中获取 NginxHttpServerChannel ch 并使用它来发送响应。如果我们有多个 nginx worker 进程,我们需要使用 broadcast! 来广播 repsonse 事件,并使用 on-broadcast! 在持有 NginxHttpServerChannel ch 的 nginx worker 进程中获取响应事件并使用它将响应发送给原始客户端。

Here 是关于通道 sub/pub.

的示例

顺便说一句,我们也可以使用来自 redis 的 sub/pub 而不是来自 nginx-clojure 的 broadcast!on-broadcast!。例如在第一个内容处理程序中,我们将 redis 的主题子化,然后服务器 B 将响应消息发布到相同的 redis 主题。最后使用 NginxHttpServerChannel ch 将响应发送给原始客户端。