应用程序负载均衡器是不是支持 WebSockets?
Posted
技术标签:
【中文标题】应用程序负载均衡器是不是支持 WebSockets?【英文标题】:Does an Application Load Balancer support WebSockets?应用程序负载均衡器是否支持 WebSockets? 【发布时间】:2017-01-13 03:29:36 【问题描述】:我有一个最初配置为使用 Classic Load Balancer 的 Elastic Beanstalk 应用程序。我发现这在通过 WebSocket 连接时会导致错误。因此,我将应用程序配置为使用 Application Load Balancer,因为有人告诉我 ALB 支持 WebSockets。但是,它们似乎没有:尝试通过 WebSocket 连接到我的 ALB 时遇到完全相同的错误。
ALB 真的支持 WebSocket 吗? AWS 文档在这方面是矛盾的。 This page 说它只支持 HTTP 和 HTTPS。没有设置 ALB 以支持 WebSocket 的指南。
【问题讨论】:
来自官方博客:aws.amazon.com/blogs/aws/new-aws-application-load-balancer "ALB 通过 ws:// 和 wss:// 协议为 WebSocket 提供原生支持。" 尽管有 ALB 的公告和常见问题解答部分,但我在 ALB 上也遇到了同样的错误(http 状态 501 未实现) 尽管aws.amazon.com/elasticloadbalancing/applicationloadbalancer/… Socket.io 有问题,似乎不能开箱即用。 【参考方案1】:我能够让 WebSockets 与新的 Application Load Balancer (ALB) 一起使用。
首先,为您的 ALB 创建一个新的目标组。此目标组应使用与您的应用程序相同的端口,并且需要配置运行状况检查。但是,主要区别在于您必须启用粘性。
接下来,将新的侦听器规则添加到您的 ALB。此规则必须有一个路径来路由 WebSocket 设置 -- /socket.io。另外,将 Target Group Name 设置为您刚刚创建的 Target Group。
我正在为我的服务器使用 Node/Hapi/Socket.io(在派生自 Amazon Linux AMI 的实例上运行)。基本设置是:
const hapi = require('hapi');
const websocket = require('./WebSocket');
var server = new hapi.Server();
server.connection(config.Application);
websocket.Initialize(server.listener);
WebSocket.js 在哪里
var io = null;
module.exports =
Initialize: function (http)
io = require('socket.io')(http);
io.on('connection', function (socket)
console.log('Websocket ' + socket.id + ' connected.');
socket.on('disconnect', function ()
console.log('Websocket ' + socket.id + ' disconnected.');
);
);
;
我正在为我的客户端使用 Angular 1.5x,带有 socket.io-client。请务必按如下方式配置 WebSocket 客户端选项,否则您将无法连接。
(function ()
'use strict';
angular
.module('XXXXX', [])
.run(runHandler);
runHandler.$inject = ['WebSocketService'];
function runHandler(WebSocketService)
WebSocketService.Initialize();
)();
WebSocket 服务:
(function ()
'use strict';
angular
.module('XXXXX')
.factory('WebSocketService', WebSocketService);
WebSocketService.$inject = [];
function WebSocketService()
var socket = null;
function initialize()
var url = 'http://' + ALB_URL + ':5800';
socket = io(url, transports: ['websocket'], upgrade: false);
socket.on('connect', function ()
console.log('Socket connected');
);
socket.on('disconnect', function ()
console.log('Socket disconnected');
);
return
Initialize: initialize
;
)();
【讨论】:
您的健康检查配置是什么? socket.io 或您的应用程序代码是否有特殊的健康检查端点?在我的情况下,请求/
会导致 HTTP 426
响应,ALB 认为它不健康。
我在 ALB 后面有两个 VM。每个都托管一个 Node Web 服务。我在 http:ALB 支持 Websocket,但如果实例至少每隔“空闲超时”秒发送一些数据,负载均衡器可以关闭连接。
【讨论】:
【参考方案3】:应用负载均衡器支持 websocket。但是直到 2017 年 2 月 23 日才支持 websocket 健康检查。他们可能会在以后添加一个选项。当您想在 Application Load Balancer 后面使用 websocket 时,您需要为目标组设置 HTTP 或 HTTPS 运行状况检查。
来自 AWS 文档: “请注意,健康检查不支持 WebSockets。”
参考:http://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html
【讨论】:
请注意,我们在 2018 年,接近 2019 年,AWS 仍然不支持 WSS 健康检查:'(docs.aws.amazon.com/elasticloadbalancing/latest/application/… 仍然说【参考方案4】:ALB(应用程序负载平衡器)支持 websocket。你可以在这里查看https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/enter image description here
ALB 也会根据配置的空闲超时关闭连接。
SnapShot from the above blog
【讨论】:
这实际上没有帮助。【参考方案5】:就nodejs而言 当我们在客户端使用 socket io 并调用 socket.js 库时 像这样
const socket = io('domain.com');
我观察到的是,当我将 Http 指定为协议时,它会将调用重定向到 ws://domain.com 但是当我指定 https 时,它会重定向到 wss://domain.com 并且我收到此错误失败: WebSocket 握手期间出错:意外的响应代码:400 我所做的是我指定了
const socket = io(window.location.origin, reconnect: true,transports: ['websocket']);
确实解决了我的问题
【讨论】:
以上是关于应用程序负载均衡器是不是支持 WebSockets?的主要内容,如果未能解决你的问题,请参考以下文章
spark-cassandra-connector 是不是支持内置负载均衡?
如何设置我的 Elastic Beanstalk 应用程序以使用 Application Load Balancer?
在 AWS Elastic Load Balancer 后面使用 Primus.io (websockets)