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 的请求。
问题
为什么 ELB 在 nginx 配置中不起作用?如何纠正?
我尝试了什么?
我检查了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适用于本地计算机,但不适用于服务器