Using AWS Elastic Beanstalk

I’ve recently setup Elastic Beanstalk with websocket and sticky sessions.

It is basically impossible with AWS ELB.
but there are some hints in meteorhacks and I decide to test and setup.
I had to switch the client’s DDP connection’s port when it fails to connect as a websocket.
It was successful anyway, and I’d like to share because I have never heard using AWS for Meteor with web socket and sticky sessions.

I am new to Meteor and not sure switching DDP port such like that is good to do or not.
Could you guys tell me some advice for that?

here comes some details.

As you may know, Meteor needs sticky sessions for non web socket clients.
And web socket needs TCP settings in AWS ELB rather than HTTP setting.
but AWS ELB does not support session stickness on TCP.
so we need to setup another port for web socket connection.
it will be port 8443 (SSL).

so, it use HTTP(80) port to forward all to HTTPS(443) port and SSL(8443) for web socket.
but the same thing can be done with HTTP(80) port and TCP(8080) for web socket if you don’t use HTTPS.

I published dummyData and
in client/main.js,
added some code for switching port when it failed to connect the web socket like…

Meteor.subscribe('dummyData', function () {
  if (!checked) {
    checked = true;
    console.log(Meteor.connection._stream.socket.protocol);
    if (Meteor.connection._stream.socket.protocol != 'websocket') {
      console.error('Failed to connect as a websocket', Meteor.connection._stream.rawUrl);
      let pollingUrl =  Meteor.connection._stream.rawUrl.split(':');
      if (pollingUrl[0].indexOf("http") == 0) {
        Meteor.disconnect();
        pollingUrl = pollingUrl[0] + ":" + pollingUrl[1];
        if (Meteor.settings.public.pollingUrl) {
          pollingUrl = Meteor.settings.public.pollingUrl;
        }
        Meteor.connection._stream.rawUrl = pollingUrl;
        console.log('switching DDP to', Meteor.connection._stream.rawUrl);
        Meteor.reconnect();
      }
    }
  }
}); 

Elastic Beanstalk also needs other settings such as

  • patching nginx proxy like…
    http://gist.github.com/adamgins/f99635447a1239289460
  • loading setting.json like…
    http://stackoverflow.com/questions/34761577/how-to-config-meteor-on-aws-ebs-using-meteor-settings-environment-variable

and manual dual port ELB settings as following.

Environment variables

add it in Elastic Beanstalk console (https://aws.amazon.com/elasticbeanstalk/home), environment name, Configuration, Software Configuration.
It can be done from .ebextension , but I prefer manual since it can be changed after deployment.

  • DDP_DEFAULT_CONNECTION_URL
    https://domain:8443/
  • MONGO_URL
    mongodb://<user>:<pw>@<ip_addr>:27017/db_name
  • ROOT_URL
    https://domain/

ELB

DDP connection will be set to :8443 by default by DDP_DEFAULT_CONNECTION_URL.
and Clients should change their DDP connection port to normal (443) for session stickness when websocket is not available.

add a TCP(SSL) port to ELB

in the Load balacers tab in EC2 console (https://console.aws.amazon.com/ec2/v2/home),
select appropriate Listeners tab.
and add SSL, 8443, TCP, 80.
and input SSL Certificate name and paste private key (.key) and public key(.crt).
or use existing one and Save.

add a rule for TCP port in Security Group

and then, go to Description tab and in the Security tab,
click sg-0xxxx link to go to VPC console.
there you need to add an Inbound Rules for 8443 port.

Edit, Add another rule,
select or input like HTTPS* (8443), TCP (6), 8443, 0.0.0.0/0

turn on session stickness

in the Elastic Beanstalk console (https://aws.amazon.com/elasticbeanstalk/home), environment name, Configuration, Load balancer.
Turn on session stickiness at Sessions section with expiration period like 600
turn on HTTPS and select certificates input above.


Actually AWS has announced their new Application Load Balancer 11 Aug 2016.
and I think it will support websocket and stickysessions at the same time.
but it is not available for Elastic Beanstalk yet.

https://aws.amazon.com/about-aws/whats-new/2016/08/announcing-application-load-balancer-for-elastic-load-balancing/

** sorry, since I’m a new user, I couldn’t add more than 2 links and 1 image.

Brother, if you are new to Meteor and are set on Meteor, why in the world would you start with DDP and not Apollo? If you want to stay current, you’re just going to have to rewrite your application when Livedata/DDP goes away a year or so from now…

If you’re not set on Meteor and are evaluating tech for use on a project/company, and want maximum flexibility, then look at Feathers.js – its where Meteor is headed anyhow. Here is a podcast with the founders hosted by the reputable @joshowens.

1 Like

Though I’m new to Meteor, my project is one year old roughly and moving to AWS.
Anyway, Thank you for the link. I’ll have a look. I like new things as well.

How can you start using apollo? I have the same concern as kenny, looking for replacing our old php framew to Meteor but we rely heavily on AWS, what to do?

Have you given this a read? @chulian

Thanks diac! the main problem is mongo, RDS doesnt support mongo, just dynamodb and using a 3rd party mongo provider increases the price substantially

I can’t login to the forum, so I reply in mail.

@chulian, do you have a concern about using websocket with Elastic
Beanstalk?

You might be able to use Application Load Balancer to the autoscaling group
directly.
Though I haven’t tried it, since it is layer 7 load blalancer, it should be
working for websocket and sticky session at the same time.

actually I’ve ended up to set up dual port ELB and added some client code
for selecting port for DDP.
as introduced below.
https://meteorhacks.com/load-balancing-your-meteor-app.
html#aws-elastic-load-balancer-elbhttpawsamazoncomelasticloadbalancing

@chulian you can set up your own mongo db replica set with Cloudformation.
I’ve edited official sample script for reducing cost.
have a look if youre interested.

Thanks @kennyhyun ! this isvery close to what I’m looking for but that cloud formation script doesn’t set up a scalable cluster, only static, do you know about one that scales?

Replica set is horizontally scalable for reads. but not for writes.
but you can scale it up vertically since any of nodes can be replaced one by one.