Websocket 适用于 EC2 url,但不适用于 ElasticBeanstalk URL

Posted

技术标签:

【中文标题】Websocket 适用于 EC2 url,但不适用于 ElasticBeanstalk URL【英文标题】:Websocket works on EC2 url but not on ElasticBeanstalk URL 【发布时间】:2018-02-11 21:06:06 【问题描述】:

背景

我有反向代理 (nginx) 指向 ElasticBeanstalk (ELB),它是一个单一实例环境类型并创建一个 EC2 实例 (EC2 )。我正在使用一个 dockerized nodejs 应用程序。 nginx 是我们基础架构的入口点。

说明

从浏览器中,我可以直接调用 EC2 和 ELB 的 Websocket URL,结果相同:

欢迎使用 SockJS!

对于 nginx 我使用以下配置 (nginx conf.d/my.conf) 我只更改 EC2 或 ELB在proxy_pass开头的那一行:

location /stomp 
      proxy_pass <EC2_URL/stomp OR ELB_URL/stomp>;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    

EC2 URL 上的 Websocket 工作正常。

ELB URL 上的 Websocket 将错误状态返回给我的客户端:

代码:1002, 原因:“无法连接到服务器”

最奇怪的是,我的 nginx 服务器甚至不记录 ELB 的请求。

问题

为什么 ELBnginx 配置中不起作用?如何纠正?

我尝试了什么?

我检查了question 和blog,他们建议覆盖位于located in /tmp/deployment/config/etc#nginx#nginx.conf 中的00_elastic_beanstalk_proxy.conf 等nginx 配置文件。但是我的服务器在文件系统上没有任何 nginx 配置文件...

【问题讨论】:

那么在你的情况下,nginx 在哪里运行? 您通过哪个端口连接?默认负载均衡器设置可能只接收来自端口 80 或端口 443 的流量。如果您使用的是 SSL,您是否使用 ElasticBeanstalk 设置了证书?如果您从未在 Nginx 端收到请求,那么您可能永远不会从负载均衡器转发。要查看您的负载均衡器,您应该转到 AWS 面板上的 EC2 -> 负载均衡器。 @jonzlin95 我们通过端口 80 连接。EC2 → Load Balancers 中没有列出负载均衡器,但这并不奇怪。因为我们只使用 SingleInstance 环境类型的 ELB。 @TarunLalwani nginx 是我们基础设施的入口点。它将流量重定向到 ELB(或直接到 EC2)。 删除这个proxy_set_header Host $host;,然后再试一次,看看它是否有效 【参考方案1】:

该问题与您的proxy_set_header Host $host; 有关。问题在于不同服务器对主机名标头的反应方式。

在浏览器中打开以下网址时请考虑

http://ec2-52-59-53-38.eu-central-1.compute.amazonaws.com/stomp http://stag-ws-server.eu-central-1.elasticbeanstalk.com/stomp

一个是 EC2,一个是 ELB。当您向 ec2 发送请求时,主机名将作为 ec2-52-59-53-38.eu-central-1.compute.amazonaws.com 发送。现在,如果您有直接或通过 docker 侦听端口 80 的服务。它正在监听 80 端口,并不关心流量是如何到达的。

它只知道如果有人以任何方式到达服务器,我们就会做出响应。现在,如果你在那个 EC2 上有一个 nginx,它只监听一个特定的虚拟主机并且不响应任何其他主机名,那么如果你发送它 ec2-52-59-53-38.eu-central-1.compute.amazonaws.com 并且它希望看到 abc.mydomain.com 那么 nginx 不会响应请求。

您的 ELB 服务器也是如此。您在某个域名 abc.domain.com 上托管 nginx,并使用 proxy_pass 将流量传递给 ELB。但是使用proxy_set_header Host $host;,将主机名设置为abc.domain.com,ELB 无法理解该主机的位置。所以它不会服务器请求,因此错误

【讨论】:

以上是关于Websocket 适用于 EC2 url,但不适用于 ElasticBeanstalk URL的主要内容,如果未能解决你的问题,请参考以下文章

AWS Elastic Beanstalk Tomcat 适用于 .war 但不适用于 .zip

file_exists 或 getimagesize 仅适用于本地、绝对文件路径,但不适用于 PHP 中的 URL

JSF 2.2 webapp适用于本地计算机,但不适用于服务器

Lambda 不适用于具有自动缩放功能的 ec2

RewriteCond 适用于 HTTP,但不适用于 HTTPS 虚拟主机

.htaccess 适用于 Apache 服务器,但不适用于 FTP 目录