8

I have a question about how to load balance web sockets with AWS elastic load balancer.

I have 2 EC2 instances behind AWS elastic load balancer.

When any user login, the user session will be established with one of the server, say EC2 instance1. Now, all the requests from the same user will be routed to EC2 instance1.

Now, I have a different stateless request coming from a different system. This request will have userId in it. This request might end up going to a EC2 instance2. We are supposed to send a notification to the user based on the userId in the request.

Now,

1) Assume, the user session is with the EC2 instance1, but the notification is originating from the EC2 instance2. I am not sure how to notify the user browser in this case.

2) Is there any limitation on the websocket connection like 64K and how to overcome with multiple servers, since user is coming thru Load balancer.

Thanks

user1578872
  • 7,808
  • 29
  • 108
  • 206

3 Answers3

5
  1. You will need something else to notify the browser's websocket's server end about the event coming from the other system. There are a couple of publish-subscribe based solution which might help, but without knowing more details it is a bit hard to figure out which solution fits the best. Redis is generally a good answer, and Elasticache supports it.

  2. I found this regarding to AWS ELB's limits: http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_elastic_load_balancer But none of them seems to be related to your question.

Lajos Veres
  • 13,595
  • 7
  • 43
  • 56
  • I am just trying to understand How Redis can solve this problem as the event origination and the websocket session are on two different instances. – user1578872 May 02 '17 at 18:51
  • To be honest I am not very familiar with Redis' model, but it seems to be one of the most widely used/simplest approach. Anyway in theory it should work like this: One instance can subscribe to events and the other instance can publish it. Redis will notify the subscribed instance. And 2 hopefully useful links: https://redis.io/topics/pubsub https://robots.thoughtbot.com/redis-pub-sub-how-does-it-work Otherwise I think the main point is to connect somehow the 2 servers, they have to communicate through a channel. There are some other "queue" tools. – Lajos Veres May 02 '17 at 22:18
3

Websocket requests start with HTTP communication before handing over to websockets. In theory if you could include a cookie in that initial HTTP request then the sticky session features of ELB would allow you to direct websockets to specific EC2 instances. However, your websocket client may not support this.

A preferred solution would be to make your EC2 instances stateless. Store the websocket session data in AWS Elasticache (Either Redis or Memcached) and then incoming connections will be able to access the session regardless of which EC2 instance is used.

The advantage of this solution is that you remove the dependency on individual EC2 instances and your application will scale and handle failures better.

If the ELB has too many incoming connections, then it should scale automatically. Although I can't find a reference for that. ELB's are relatively slow to scale - minutes rather than seconds, if you are expecting surges in traffic then AWS can "pre-warm" more ELB resource for you. This is done via support requests.

Also, factor in the ELB connection time out. By default this is 60 seconds, it can be increased via the AWS console or API. Your application needs to send at least 1 byte of traffic before the timeout or the ELB will drop the connection.

Steve E.
  • 9,003
  • 6
  • 39
  • 57
  • Even I cache the session using Elasticcache, will the websocket work? I thought, websocket is established with a single server. – user1578872 May 03 '17 at 14:45
  • Yes, once a connection is established it will continue to go to the same EC2 instance for the duration of that connection. In your question you refer to a _different stateless request coming from a different system_ This may be routed to a different EC2 instance as it' a new connection. If multiple connections need to share session data then Elasticcache is one way to share the session data between multiple EC2 instances. – Steve E. May 03 '17 at 22:52
  • Hi, Even the multiple connections sharing the session data, What if the stateless request is going to an instance 1 and the websocket is established with the instance 2. Here, the session data will be available in instance 1 & 2. But, How can it send the websocket notification to the instance 2 from Instance 1. – user1578872 May 04 '17 at 22:35
  • That's more tricky. For small scale projects, have the server process connected to the browser poll the Elasticache for changes and relay them. For larger scale a messaging process that tracks live connections along with a queuing service like AWS SNS and directs notifications to the right destination would be more scalable. – Steve E. May 05 '17 at 00:58
  • Am sorry. Still I am not clear here. How can notify from the other instance even with AWS SNS? I can expose a webservice from Instance 1 & 2 and call the service, but it is time consuming. Looking for a better solution. – user1578872 May 05 '17 at 06:17
1

Recently had to hook up crossbar.io websockets with ALB. Basically there are two things to consider. 1) You need to set stickiness to 1 day on the target group attributes. 2) You either need something on the same port that returns static webpage if connection is not upgraded, or a separate port serving a static webpage with a custom health check specifying that port on the target group. Go for a ALB over ELB, ALB's have support for ws:// and wss://, they only lack the health check over websockets.