google-app-engine - 从 ManagedVM 中公开多个端口

标签 google-app-engine websocket docker gcloud

我正在使用托管 VM 功能来运行 WebSocket 服务器,我想通过以下 URL 在任何端口(最好是端口 80)上向 Internet 公开该服务器:mvm.mydomain.com

我还没有取得太大的成功。 以下是我用来完成此任务的各种文件的相关部分:

docker 文件:

EXPOSE 8080 8081

在 Dockerfile 的末尾,启动了一个 Python 应用程序:它响应端口 8080 上的健康检查(我可以验证它是否有效)并响应端口 8081 上的 WebSocket 请求。

应用程序.yaml:

module: mvm
version: 1
runtime: custom
vm: true
api_version: 1

network:
  forwarded_ports: ["8081"]

我使用以下方法将此应用部署到云端:

$ gcloud preview app deploy .

在云控制台中,我确保传入流量接受 TCP 端口 8080 和 8081。我还观察到分配给 GCE 实例 (mvm:1) 的 IP 地址是:x.y.z.z。

$ curl http://x.y.z.z:8080/_ah/health
$ curl http://mvm.my-app-id.appspot.com/_ah/health

200 OK 回复两者。

使用一些 JavaScript 连接 WebSocket 服务器也可以:

new WebSocket('ws://x.y.z.z:8081');

到目前为止一切顺利。除了这不起作用(超时):

new WebSocket('ws://mvm.my-app-id.appspot.com:8081');

我想知道为什么上面的 WebSocket 命令不起作用。 也许在 GAE/GCE 端口转发交互中我不明白?

如果这可以以某种方式工作,我设想以下将是完成它的最后步骤。

调度.yaml:

dispatch:
  # Send all websocket traffic to the ManagedVM module.
  - url: "mvm.mydomain.com/*"
    module: mvm

我还在 mvm.mydomain.com 上设置了 GAE 自定义域 CNAME。

然后使用 JavaScript 连接 WebSocket 服务器应该像这样工作:

new WebSocket('ws://mvm.mydomain.com:8081');

最佳答案

考虑到在(相对较新的)托管 VM 发布之前,appspot.com 的端口转发很可能没有执行,唯一流向 的流量appspot.com 位于端口 80 或 443 上。我建议使用您发现有效的实例 IP 方法。

如果你不觉得完全满意,你应该去 public issue tracker for app engine并发布功能请求,让 appspot.com 路由器检测请求是否指向与托管 VM 相对应的模块,并在这种情况下尝试端口转发。

问题是,像这样将原始端口放在域的末尾意味着您的浏览器将使用您指定的端口作为 appspot.com 的连接参数,而不是查询参数,因此 appspot.com 将具有监听所有端口并在有效时重定向。这可能是不安全/低效的,因此端口号可能是查询参数或域字符串的一部分,类似于指定版本和模块的方式......

无论如何,考虑到端口的工作方式,我非常怀疑,如果您的非常简单的示例导致失败,那么应用引擎的 appspot.com 域甚至设置为处理端口目前全部转发到托管 VM 容器。

关于google-app-engine - 从 ManagedVM 中公开多个端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27638401/

相关文章:

python - 在 Jinja 模板中将 UNIX 时间转换为 datetime 对象

websocket - 错误 ServerMiddleware 应公开句柄 nuxt

windows - 用于服务发现的 Docker DNS 按名称解析 Windows 容器地址的工作效果不一致

docker - 处理克隆容器上的不同配置文件

javascript - 使用 WebSockets……高效吗?

python - 使用 docker-py 从现有容器运行 docker 容器

python - 如何将字典对象传递给 jinja2,其中 dict.keys 是标记,字典值是我想要显示的内容?

python - 使用 gae-sessions 检索存储在其他 session 中的信息

java - 当服务器在触发事件时发送电子邮件时,是否有必要在 HttpServlet 中使用serialVersionUID

ruby-on-rails - websocket-rails 聊天室