与多个 Chrome Docker 容器的 Websocket 通信

Websocket communication with multiple Chrome Docker containers

我有一个 Chrome 容器(使用 this Dockerfile 部署),它根据 App 容器的请求呈现页面。

基本流程是:

对于单个 Chrome 容器,这非常有效。

但我正在尝试扩大规模以在 Docker 群中拥有多个 Chrome 容器。

问题是,我认为,App 收到的 websocket url 特定于那个特定 Chrome 容器中的实例 运行,所以当它被 App 使用时(现在有多个 Chrome 容器),来自 App 的 websocket 请求不一定会路由到正确的 Chrome 容器。

处理这个问题的最佳方法是什么?

您的基本设计是正确的,但您遇到的问题是会话“粘性”。但是,与其尝试将 re-route 后续请求返回到适当的机器,不如寻找一种方法来避免 "pre" 请求。

最好的方法是让您的 Chrome docker 图片 man-in-the-middle 所有 http“升级”请求。这个 http 操作是所有 WebSocket 连接在更改协议之前发出的,包括 puppeteer 库(它只是一个 WebSocket 客户端 under-the-hood)。这样做也将避免 pre-connect 调用的需要,因为对 Chrome 的代理将在升级时发生,而不是公开 URL 供应用程序使用。这是使用 http-proxy 模块执行此操作的一个非常基本的示例:

const http = require('http');
const httpProxy = require('http-proxy');

const proxy = new httpProxy.createProxyServer();

http
  .createServer()
  .on('upgrade', async(req, socket, head) => {
      const browser = await puppeteer.launch();
      const target = browser.wsEndpoint();

      proxyy.ws(req, socket, head, { target })
  })
  .listen(3000);

这种方法还有其他好处:您可以限制诸如并发之类的事情,甚至可以稍后将脚本注入 运行。这些需要更多的准备和准备,但总体思路保持不变。这也使 load-balancing 变得微不足道,因为不需要使路由变得粘滞。

如果这是您有兴趣实现的东西,那么在 browserless repo. It even allows for things like concurrency limitations, session time limitations, and includes a feature-rich IDE. You can find more docs on that project here 中大部分工作都已为您完成。