Download pdf - Pro Meteor Book

Transcript
Page 1: Pro Meteor Book

Pro Meteor

Arunoda Susiripala

Introduction to Pro Meteor

Pro Meteor is a guide that has been created as a reference for building aproduction-quality Meteor apps. Main focus of this guide is to show you on howto scale Meteor apps and maintain them with existing web proven technologies& services.

The guide assumes that its reader has a basic understanding of Meteor, butfor readers that need a better introduction, Discover Meteor comes highlyrecommended.

Good Luck & Happy Reading!

Arunoda Susiripala

Hacker at MeteorHacks

Understanding Meteor Internals

This section is an introduction to Meteor’s internals, and serves as the foundationfor the Pro Meteor guide.

Meteor Internals: Meteor as a Server and a Client

A Meteor application is seen by browsers, proxy servers, routers and othernetwork components as a typical web application. Yet Meteor is comprised oftwo main components: a part that runs inside the browser and another partthat runs inside the server. These two parts are configured to communicatewith each other in a way that’s similar to modern web applications

e.g. Gmail and Trello

Meteor allows developers to build applications without worrying about thecomplexities of client-server connectivity.

1

Page 2: Pro Meteor Book

Figure 1: Meteor has 2 parts, which run on the browser and the server

Meteor Handles Three Different Types of Requests

Underneath its surface, Meteor handles 3 types of requests. They are:

• Static Files• DDP Messages• HTTP Requests

Static Files

Static files are images and other resources inside the /public folder. Meteorserves these files automatically when the app starts.

Additionally, Meteor minifies and concatenates all JavaScript (including tem-plates, which are pre-compiled as JavaScript) and CSS files, and serves them asstatic files.

DDP Messages

DDP is the protocol Meteor uses to communicate between client and server.All client-side subscription data, method calls and MongoDB operations arecommunicated as DDP messages. This is a very lightweight protocol. Thesemessages can be inspected with a handy tool called ddp-analyzer.

2

Page 3: Pro Meteor Book

HTTP Requests

While there is no official documentation, Meteor can handle HTTP Requestssimilar to other traditional applications. For example, file uploads to a Meteorapp are sent as HTTP Requests. See this StackOverflow question for details onhow to manually handle HTTP requests.

Meteor has Two Types of Servers

Although Meteor runs on a single port, internally it works as two separateservers:

• HTTP Server• DDP Server

Figure 2: Meteor Server is a combination of a HTTP Server and a DDP Server

HTTP Server

The HTTP server is used to serve static files and HTTP requests. Meteor usesthe connect Node.js module for this purpose.

DDP Server

The DDP server handles all publications, MongoDB operations and Meteormethods. Meteor uses SockJS as the transport protocol. In actuality, the DDPserver is a SockJS server customized for Meteor.

3

Page 4: Pro Meteor Book

Future guides will detail how to scale these two servers separately.

MongoDB and Meteor

It’s possible to scale Meteor’s HTTP and DDP servers by running multipleinstances of Meteor connected to the same database, but the result isn’t ideal.Because of the way Meteor polls MongoDB for changes, if one Meteor instanceupdates MongoDB, it may take several seconds for other instances to detect thechange and propagate it to connected users.

To illustrate this further, think of two Meteor instances (A and B, with theirrespective HTTP and DDP servers) serving the same chat app. In front ofthese, a reverse proxy randomly connects users to one of these instances. Whensomeone connected to server A posts a chat, users connected to server B won’tsee the chat in real-time, as they would have to wait a few seconds before serverB recognizes the change and pushes the chat to its users’ browsers.

In later sections, I’ll show you how to configure both Meteor and MongoDB toget rid of this issue.

This polling logic is very expensive for production use, and it wouldbe better to use a solution based around the MongoDB Oplog.Meteor 1.0 comes with a such driver, but you can use Smart Collec-tions until 1.0 comes.

Now you have a better understanding of Meteor internals, particularly when itcomes to scaling. Let’s start our journey.

Fibers, Event Loop and Meteor

Meteor’s use of Fibers allows it to do many great things. In fact, Meteor’spopularity may be a direct result of its use of Fibers, though you wouldn’t knowit without a deep understanding of Meteor’s internals.

It’s a bit hard to understand how Fibers works, and how it relates to Meteor. Butonce you do, you’ll have a better understanding of how Meteor works internally.

Event Loop and Node.js

Meteor is built on top of Node.js, so we can’t forget the Event Loop. Node.js runson a single thread, and thanks to the Event Loop and event-driven programming,program execution isn’t blocked by I/O activities (network and disk, mainly).

4

Page 5: Pro Meteor Book

Instead, we provide a callback function that is run after the I/O completes, andthe rest of the program continues to run.

Here’s a psuedo-code example showing two different tasks.

// Call functions.fetchTwitterFollowers('arunoda');createThumbnail('/tmp/files/arunoda.png', '/opt/data/arunoda.thumb.png');

// Define functions.function fetchTwitterFollowers(username) {

TwitterAPI.getProfile(username, function(){Model.setFollowers(profile.username, profile.followers, function() {

console.log('profile saved!');});

});}

function createThumbnail(imageLocation, newLocation) {File.getFile(imageLocation, function(err, fileData) {

var newImage = ImageModule.resize(fileData);File.saveFile(newLocation, function() {

console.log('image saved');});

});}

Now let’s see how the above two functions get executed over time.

Tasks in fetchTwitterFollowers are marked in green, and tasksin createThumbnail are marked in orange. Dark colors show CPUtime, and light colors show I/O time.The Blue Bar shows waitTime in the queue and the Red Bar showsidleTime.

Observations

The diagram above shows us a few interesting things. First, there is no particularprogram execution order. I/O activities can take any amount of time to complete,and they won’t block the program from executing other tasks. For example,ImageModule.resize does not need to wait for Twitter.getProfile to becompleted before it can be run.

Second, CPU-bound activities do block program execution. In the middle of thediagram you can see a blue bar where Model.setFollowers cannot get started

5

Page 6: Pro Meteor Book

Figure 3: Understanding Event Loop

6

Page 7: Pro Meteor Book

even though TwitterAPI.getProfile has completed. ImageModule.resize isthe reason for that. It is a CPU-bound task, so it blocks the Event Loop. Asmentioned earlier, Node.js runs in a single thread. That’s why Node.js is not thebest choice for CPU-bound activities like image processing and video conversion.

You can also see there are three red bars indicating idleTime. If our app hadmore functionality, it could use this time to execute it.

Fibers

Now you know how the Event Loop works, and how efficient it is. But there isa problem: Callbacks. Callbacks make Node.js code difficult to reason about(some describe it as callback soup). Error handling and nested callbacks areuncomfortable to write, and their existence makes code difficult to maintain andscale. That’s why some say Node.js is hard to learn (and use).

Luckily, several techniques exist to overcome this issue. Fibers, Promises, andGenerator-based coroutines are some of them.

Meteor uses Fibers, and implements APIs on top of it. But before going into itany further, let’s see how Fibers works. See the diagram below.

Fibers provides an abstraction layer for the Event Loop that allows us toexecute functions (tasks) in sequence. It allows us to write asynchronous codewithout callbacks. We get the best of both worlds–asynchronous efficiency withsynchronous-style coding. Behind the scenes, Fibers takes care of dealing withthe Event Loop.

Fibers is really good if you use it correctly (Meteor does it well). Also, theoverhead caused by Fibers is negligible.

How Meteor Uses Fibers

Meteor abstracts Fibers with its APIs, allowing you to write your app withoutcallbacks. The best part is that you can write your code this way and becompletely oblivious to Fibers. It just works.

Meteor creates a new Fiber for each and every request (DDP Request) madefrom the client. By default, Meteor executes one request at a time for each client,meaning one Fiber for each client at a time. But you can change that.

Fibers is the one of the best reasons Meteor is so popular. Since it allows usto write Node.js apps without callbacks, it has attracted many developers whohated Node.js for that reason.

7

Page 8: Pro Meteor Book

Figure 4: Understanding Fibers

8

Page 9: Pro Meteor Book

How To Use Async Functions With Meteor

We can’t satisfy 100% of our needs with Meteor’s API–sometimes we need touse NPM modules to get things done. But how can we do this if we don’t knowhow to use callbacks with Meteor?

For example, say you need to use the Github NPM module to get your user’spublic profile. It needs to be done inside a Meteor method, and we need toreturn the profile from the method. Okay, let’s try to implement this.

var GithubAPI = Meteor.require('github');var ghapi = new GithubAPI({version: "3.0.0"});

Meteor.methods({getProfile: function(username) {

ghapi.user.getFrom({user: username}, function(err, profile) {// How to return?

});

// We need to return the profile from here.}

});

We can’t use callbacks like above. We can’t return the profile to the client fromthe callback, because the Meteor method won’t wait for the callback beforereturning. Now we need to learn how to deal with Fibers. Or do we?

Meteor foresaw this problem and provided us with a very simple API to getaround it. It’s not documented yet, but here’s how you can use it.

meteor-npm also comes with a set of async-utilities to work withnpm modules.

function getUserProfile(req, callback) {ghapi.user.getFrom(req, callback);

}var wrappedGetProfile = Meteor._wrapAsync(getUserProfile);

Meteor.methods({getProfile: function(username) {

return wrappedGetProfile({user: username});}

});

The code above is simple to understand. We wrapped the ghapi.user.getmethod in a function, and called that function with Meteor._wrapAsync to

9

Page 10: Pro Meteor Book

make it Fibers aware. Now we can use it inside Meteor methods and otherMeteor APIs.

If you know how bind works, you can do the wrapping in a single line as shownbelow.

var wrappedGetProfile = Meteor._wrapAsync(ghapi.user.getFrom.bind(ghapi.user));

Finally

Now you have a better knowledge of the Event Loop, Fibers, and how Meteoruses Fibers. And you know how to use asynchronous functions with Meteor usingMeteor._wrapAsync. It’s time to supercharge your app with this knowledge.

Additional Notes

If you are looking to learn more about Fibers and related technology, pleaserefer to the following great screencasts by EventedMind.

• Introducing Fibers• Using Futures• Meteor._wrapAsync• Understanding Event Loop Async and Fibers

Does Meteor Scale?

Most people considering Meteor for a production deployment are wondering if itcan scale. Some say Meteor is a good framework for prototyping, but not forproduction. After you read this, you’ll be able to decide for yourself.

Scaling Myth

With the emergence of cloud computing (and specifically Heroku), many havecome under the impression that scaling means adding more instances of anapplication. That’s not completely true.

Routing, sessions, job processing, static file serving, and database optimizationare key concerns when it comes to scaling, among other things. Any Meteor appthat intends to deploy into production needs to address–or at least consider–theseissues. On top of that, Meteor has its own issues.

10

Page 11: Pro Meteor Book

Issues Unique to Meteor

Meteor isn’t like Ruby on Rails, Express (the Node.js framework), or PHP. It’sa special framework with its own issues, many of which have been solved outsideof the Meteor community already. We just need to figure out how to fit themtogether and apply them correctly to Meteor. So, let’s have a look at these issuesfirst.

Use of SockJS

Meteor uses SockJS as the transport layer for communicating between clientand server. SockJS needs sticky sessions, which means that all the requests fora particular client must be served from a single server for a specific amount oftime.

Hot Code Reloading

Meteor apps are single-page apps, which are long-lived in the browser. Single-page apps can sometimes experience conflicts between the server and client dueto a version mismatch–especially when new code is pushed often, which is notso rare these days. Fortunately, Meteor features hot code reload, which identifiesany code changes on the server and asks the browser to reload. Additionally,Meteor is smart enough to preserve session information through the reload.

Due to the default hot code reload logic, a Meteor client app needs to connect(via DDP) to the same server it was loaded from.

Polling for Changes in MongoDB

Meteor is all real-time, which it currently achieves by fetching and comparingdocuments after every database write operation. Meteor also polls the databasefor changes every 10 seconds. These are the main bottlenecks when scalingMeteor, and they introduce two main issues:

1. The polling and comparing logic takes a lot of CPU power and networkI/O.

2. After a write operation, there is no way to propagate changes to otherMeteor instances in real-time. Changes will only be noticed the next timeMeteor polls (~10 seconds).

See how Meteor identifies database changes with polling:

11

Page 12: Pro Meteor Book

Figure 5: Real-time Changes with MongoDB Polling

How We Can Solve Meteor’s Scaling Issues

There is nothing which cannot be solved. Continue reading to learn how to solvethe above-mentioned issues with Meteor, and some other common scaling issues.The next few sections will discuss the full implementation of these solutions.

Sticky Session Enabled Load Balancing

When serving requests to Meteor instances, a load balancer needs to be ableto handle the issues presented by SockJS and hot code reload. These issues arenot hard to solve so long as the load balancer can be configured to use stickysessions–and the sticky sessions need to apply to static content, at least for thefirst HTML page.

Meteor with MongoDB oplog

As mentioned above, Meteor’s bottleneck to scaling exists in the way it pollsthe database and runs an algorithm to detect and patch in any changes to therest of the app. But we can get much more performance out of Meteor using theMongoDB oplog. An oplog-based solution works with multiple Meteor instances

12

Page 13: Pro Meteor Book

without much effort. You can even write directly to the database outside ofMeteor, and Meteor will notice the changes.

Oplog integration removes the bottleneck of MongoDB polling.

MongoDB’s oplog is a log that records every database write operation. It’s soreliable that it’s used for MongoDB replication (Replica Sets). Also, the oplogis a capped collection, which can be configured to have a fixed size and can betailed. Oplog tailing can be used to capture database changes in real-time.

See following illustration to see how Meteor gets database changes with the oplog.

Smart Caching

It’s a good idea to put a caching server in front of Meteor. This will reduce theload on Meteor to serve static content. Node.js (where Meteor runs) does notwork well when it comes to static file serving, so using a caching server improvesperformance.

The caching server shouldn’t cache the first HTML page loaded from Meteorinto the browser. This is the only HTML content Meteor loads, and it containsa JavaScript variable called serverId that is used to compare versions in hot codereload logic.

Improved Application & MongoDB Performance

Fixing the most common performance issues helps a lot in the scaling process.The first thing to optimize is database indexes. Meteor doesn’t auto-magicallyadd indexes–they need to be added explicitly. Indexes can provide a largeperformance gain.

13

Page 14: Pro Meteor Book

Subscriptions and queries can also be optimized, with notable performance gains.

Scaling MongoDB

MongoDB is a core component of Meteor, so it needs to be prioritized wherescaling and performance are concerned. Generally, MongoDB performs quitewell. It supports both vertical and horizontal scaling. It can be run on a morepowerful server, or use MongoDB sharding to scale horizontally.Although MongoDB comes with good sharding tools, care needs to be takenwhen using sharding.

Use of a CDN

If your application is heavy on static content like images and video, you mustnot host these files using Meteor. Nowadays, using a CDN (Content DeliveryNetwork) is standard practice, and it’s not very hard.

Okay, Does Meteor Scale?

Now you can decide if Meteor scales or not! In the next section, you’ll learn howto use commonly available tools and services to scale Meteor.

How to Scale Meteor?

In the previous section, we looked at the problems and possible solutions forscaling Meteor applications. But I did not show you how to scale an app inpractice. So, this section covers that.

Scaling Set-up

Our component diagram is:There are three Meteor servers, one MongoDB server and a HaProxy server asthe load balancer. For SSL support, we will use Stud in front of HaProxy.Let’s discuss these components and configurations.

Configuring MongoDB

I’m using a single-server replicaSet for MongoDB, which supports the oplog. Itis better to use a multiserver replica set, but I will be using a single server tokeep things simple.

14

Page 15: Pro Meteor Book

Figure 6: Meteor Scaling Setup - Components

Configuring a Single-Server Replica First, we need to start our MongoDBserver with replicaSet aware. Use the following command to start MongoDBwith replicaSet meteor:

mongod --replSet meteor

Then, open a Mongo shell and add the following to configure the single-serverreplicaSet:

var config = {_id: "meteor", members: [{_id: 0, host: "127.0.0.1:27017"}]}rs.initiate(config)

It is wise to run a 3 node MongoDB ReplicaSet for your app. I highlyrecommend using MongoHQ Dedicated Servers, if you don’t havethe expertise.

Access Control Since we are using a separate MongoDB server, we need toprevent unauthorized access of it. We can configure a firewall or use MongoDB’srole-based access control. To make the set-up simple, I assume we’ve configuredthe firewall properly. If it is not possible to configure a firewall, try usingMongoDB’s role-based access control.

We’ll be using app as the database for our Meteor app. For the oplog integration,we will be using the local database that contains the oplog.

15

Page 16: Pro Meteor Book

Configuring Meteor

We need to keep an eye on a few things when we are planning a scalable Meteordeployment. I’ll show these in this section.

Oplog Support

I already mentioned in the previous section how oplog can help Meteor to scalehorizontally.

All you’ve to do is, simply expose the MongoDB URL of your local database asMONGO_OPLOG_URL.

MONGO_OPLOG_URL=mongodb://localhost/local

(Of course, you need to set MONGO_URL as usual)

IE 8 and 9 Sticky Session Support

IE 8 and 9 do not send cookies with Ajax requests; so this breaks our loadbalancer, which we’ll be exploring in the next section. Fortunately, SockJS hasa solution for that, but it is turned off by default with Meteor. To turn it on,you need to export the following environmental variable:

export USE_JSESSIONID=1

Selecting Servers

It is very important that you choose identical servers for Meteor. They should bein the same data center and the performance, operating systems and architectureshould also all be the same; otherwise we’ll have an unbalanced load across ourMeteor servers.

In this setup, I am using only a single process on the server. So a server withmultiple cores will not be much help. So try to pick single core server instances.I’ll cover this further in the next section.

Deploying

It is very important to deploy your Meteor app correctly and configure theservers carefully. If possible, try consulting someone who knows how. Otherwiseyou can use Meteor Up, which I built to deploy production-quality Meteor apps.

16

Page 17: Pro Meteor Book

Configuring the Load Balancer (HaProxy)

I’m using HaProxy as the load balancer for our Meteor app. It is something verystable and used in production by many companies. Also, HaProxy has built-insupport for sticky sessions and some of the other configurations that we will beusing.

Sticky Session Support

There are a couple of ways we can implement sticky sessions. We can implementsticky sessions with cookies, hashing source IP information or customized URLs.There are some other ways, but these are the common ones.

Hashing source IP is the easiest to implement, but it does not balance the loadproperly. We can’t trust the IP information and transparent proxy servers (verycommonly used by ISPs) hide the original IP information, which means oneserver will get many requests and the others won’t.

A customized URL path is a very good option and it is very well supportedby SockJS. But for this, we’ll need some custom logic in the load balancer andfurther configuration on Meteor.

The cookie-based solution is ideal for us, since it can balance the load properlyand it is easy to set up.

Load-Balancing Algorithm

It is very important to choose a good load-balancing algorithm. HaProxy comeswith a bunch of algorithms. The roundrobin algorithm is recommended in thedocs. roundrobin is very good for stateless webapps built with Ruby on Railsor PHP.

However, Meteor is stateful and it has long-lasting connections, so it is better touse the leastconn algorithm. It sends new connections to the server that hasthe lowest number of connections. This balances the load equally, even if a servergoes down and comes back. If we use roundrobin, we’ll have an unbalancedload.

Configuration

See how you can configure HaProxy using the following configuration file:

defaultsmode httptimeout connect 5s

17

Page 18: Pro Meteor Book

timeout client 10stimeout server 10s

frontend public#binding port 80bind *:80default_backend apps

backend apps#load balancing algorithmbalance leastconn

#using JSESSIONID as the cookiecookie JSESSIONID insert nocache

#adding serverserver host1 host1.example.com cookie host1server host2 host2.example.com cookie host2server host3 host3.example.com cookie host3

I’ve removed some parts of the config file to keep it simple. You can get the fullconfig file from here.

SSL with Stud

Running your app with SSL is a must in production. Unfortunately the stableversion of HaProxy does not support SSL. But we can use Stud in front ofHaProxy to terminate SSL. It is better to deploy Stud on the same server asHaProxy.

Make sure to install Stud from the source. The version you wouldget with apt-get is outdated.

You can use the following configuration file:

#bind to defualt SSL portfrontend = "[*]:443"

#haproxy host and portbackend = "[localhost]:80"

#location of the .pem filepem-file = "/path/to/ssl.pem"

18

Page 19: Pro Meteor Book

Click here to get the complete configuration file.Stud needs your SSL certificate and the private key in a single .pem file. Seethese instructions for how to create a .pem file.

Enjoy

I hope this section will help you to scale your Meteor app horizontally.

Run Meteor on Multiple CPUs

You already know that Node.js has a single-process, single-threaded executionmodel. Since Meteor is built on top of Node.js, it shares the same model.So, even if your hosting environment supports multiple CPUs (or multiple cores),you cannot take advantage of more than one by default.

I’ll be using the term multiple CPUs to address the scenario ofboth multiple cores and multiple CPUs.

Why not the Node.js cluster module?

Node.js has provided a solution to this limitation with its Cluster module. Let’shave a look at it.Cluster spawns multiple processes of your app at your command. Then, whenyour app receives a new HTTP request, it passes the raw socket to one of thoseprocesses randomly. Cluster is not a proxy–it simply forwards the raw socket toanother process, and that process takes care of the processing. This makes itvery efficient. Unfortunately, Cluster’s routing algorithm doesn’t support stickysessions, which we need (as discussed in the previous section), so we can’t useCluster directly with Meteor.There has been an attempt to add sticky session support to Cluster, but it’s basedon source IP information. There are better ways to implement sticky sessions,such as using cookies or HTTP path (URL), but they are nearly impossible toimplement into Cluster due to the way it works. Cluster doesn’t read the contentof the raw socket–such as cookies and other HTTP information–it just forwardsit before anything is read on the server.

Using a separate load balancer

So, how do we take advantage of multiple CPUs? The only solution is to use aseparate load balancer. We talked about load balancers and how to use HaProxywith Meteor in our last section. We can use the same technique here.

19

Page 20: Pro Meteor Book

Figure 7: How cluster works

Make sure to add a different cookie name for the load balancer usedhere and the load balancer used for scaling.

Cloudflare Meets Meteor

If you have not yet heard about Cloudflare, it’s a must-have item for yourweb toolbox. It offers many services for web apps—primarily for increasedperformance and security. Here is a list of services Cloudflare offers (in orderedof my personal preference).

• Simple DNS Management• SSL Support• Caching Proxy (with CDN) for your static files• Optimize HTML and static files for faster loading• Web Application Firewall• DDOS Protection

In addition to these features, Cloudflare’s pricing model is extremely attractive.Cloudflare does not charge for the usage: instead, it offers an affordable per-application flat fee. Of course, a free tier is offered as well.

20

Page 21: Pro Meteor Book

Using Meteor with Cloudflare is a bit tricky, as Meteor’s DDP connection usesWebSockets, which is not supported by Cloudflare yet. But with few simpletweaks, you will be able to use Meteor with Cloudflare.

This is not a guide on how to use Cloudflare’s features, but on howto use Cloudflare with Meteor

DDP and Cloudflare

Cloudflare runs on top of a customized nginx server but it does not yet supportWebSockets. If you’ve just added Cloudflare support to your Meteor app, you’llfind issues connecting to the DDP server. You have two options here.

Option 1: Disable WebSockets

Figure 8: Using Cloudflare with Disabling WebSockets

This is the simplest and the best option. All you have to do is export thefollowing environment variable before starting your Meteor app.

export DISABLE_WEBSOCKETS=1

Option 2: Use a separate subdomain for the DDP connection

With this option, you can continue to use WebSockets with your Meteor app,but you will not be able to use some of the Cloudflare’s features. All you needto do is add a separate DDP connection to your Meteor app, which will bypassCloudflare. Follow the steps below:

• Add a CNAME or A record called “ddp” pointing to the your Meteor App

21

Page 22: Pro Meteor Book

Figure 9: Using Cloudflare with WebSockets

• Bypass Cloudflare by not clicking the cloud icon on the DNS manager. (Itneeds to be grey.)

• Add the above subdomain as your default DDP connection by exportingthe following environmental variable before starting your Meteor app.

export DDP_DEFAULT_CONNECTION_URL=http://ddp.yourdomain.com

Now your DDP connection is bypassing Cloudflare and your Meteor can useWebSockets.

What are the benefits for using Cloudflare with Meteor?

Now it’s time to explore how Cloudflare helps Meteor with Cloudflare’s features.However, not all of the features help Meteor; some of them need to be turned offor to be used with care.

As a Caching Proxy with CDN

As I’ve mentioned before, it is not wise to use Meteor to serve static content.Cloudflare proxies all of the static content, such as CSS, JavaScript. and Imagesby default. As such, your Meteor app is not directly serving any static content,which is exactly what we need. Also, Cloudflare acts as a CDN, so you gain thatbenefit, too.

However, Cloudflare does not cache any HTML content. That helps us to loadbalance our Meteor app correctly with sticky sessions.

22

Page 23: Pro Meteor Book

As your SSL terminator + SSL provider

As I’ve also previously mentioned, NodeJS is not good at serving SSL, andMeteor has no option to configure SSL. Therefore, we need to use a separateSSL terminator such as stud or nginx.Cloudflare has a very interesting SSL service that acts as both an SSL certificateprovider and as an SSL terminator. Simply put, you don’t need to buy an SSLcertificate and make any configurations; you just need to click a button.Unfortunately, if you’ve used Option 2 to allow DDP support, you can’t enjoythis feature, as now your DDP connection is bypassing Cloudflare.

To use SSL support, you need to use the Cloudflare Pro subscriptionplan

Turn off Minification and the Rocket Loader

Meteor does already minify all your JS and CSS files. There is therefore noreason to do so inside Cloudflare. However, minifying multiple times does notbreak anything.Cloudflare also has a feature called RocketLoader, which loads JavaScript asyn-chronously. But Meteor’s JavaScript (just a single file) needs to be loadedsynchronously, so you will need to turn this off.Cloudflare has some security options, which asks users to enter a CAPTCHAbefore entering the site. This is used to block malicious users. Sometimes,your users may be using a shared Internet connection, or the ISP is using atransparent proxy or something similar. This might cause Cloudflare to triggerthe CAPTCHA, which might confuse the users of your app.I really can’t say whether it is a good option to turn this off or not. But keep inmind that there is a situation like this also.

DDOS Protection

First of all, if you are considering this, your app is popular :)Cloudflare does a good job at handling DDOS, and it has prevented some majorattacks. This is how you can gain its benefitTo obtain the DDOS protection, you need to hide the IP address (or directaccess) to your Meteor app from the public. This relates to both your mainwebsite and the DDP connection.If you are using Option 1 with disabling WebSockets, you are already behindCloudflare, and direct access to your Meteor app is hidden from the public. Sowhenever you need DDOS protection, you can simply turn it on.

23

Page 24: Pro Meteor Book

But if you are using Option 2 with a separate DDP connection, your DDPconnection is exposing direct access to your site. This allows the attacker tobypass Cloudflare and directly attack your app. If you are keep using this option,and if you decided to use DDOS protection at a later point, migrate your app(or load balancer) into a new server. Then apply Option 1 and turn on theDDOS protection.

Hope this section helps you to use Cloudflare with Meteor correctly and handoversome responsibilities to it and keep focus on building your app.

Finally

Now, you’ve learn about How Meteor actually works and how it can run as aproduction deployment.

This is not the end, there are some other topic which will be available later.Make sure you are subscribing to the Pro Meteor guide on MeteorHacks.

24