title: How do I set up global load balancing using Digital Ocean DNS and Nginx?
body: <blockquote>
    <p><strong>UPDATE:</strong> See the answer I've provided below for the solution I eventually got set up on AWS.</p>
  </blockquote>
  
  <p>I'm currently experimenting with methods to implement a global load-balancing layer for my app servers on Digital Ocean and there's a few pieces I've yet to put together.</p>
  
  <p><strong>The Goal</strong></p>
  
  <p>Offer highly-available service to my users by routing all connections to the closest 'cluster' of servers in SFO, NYC, LON, and eventually Singapore.</p>
  
  <p>Additionally, I would eventually like to automate the maintenance of this by writing a daemon that can monitor, scale, and heal any of the servers on the system. Or I'll combine various services to achieve the same automation goals. First I need to figure out how to do it manually.</p>
  
  <p><strong>The Stack</strong></p>
  
  <ol>
  <li>Ubuntu 14.04</li>
  <li>Nginx 1.4.6</li>
  <li>node.js</li>
  <li>MongoDB from <a href="http://www.compose.io" rel="noreferrer">Compose.io</a> (formerly MongoHQ)</li>
  </ol>
  
  <p><strong>Global Domain Breakdown</strong></p>
  
  <p>Once I rig everything up, my domain would look something like this:</p>
  
  <pre><code>**GLOBAL**
  global-balancing-1.myapp.com
  global-balancing-2.myapp.com
  global-balancing-3.myapp.com
  
  **NYC**
  nyc-load-balancing-1.myapp.com
  nyc-load-balancing-2.myapp.com
  nyc-load-balancing-3.myapp.com
  
  nyc-app-1.myapp.com
  nyc-app-2.myapp.com
  nyc-app-3.myapp.com
  
  nyc-api-1.myapp.com
  nyc-api-2.myapp.com
  nyc-api-3.myapp.com
  
  **SFO**
  sfo-load-balancing-1.myapp.com
  sfo-load-balancing-2.myapp.com
  sfo-load-balancing-3.myapp.com
  
  sfo-app-1.myapp.com
  sfo-app-2.myapp.com
  sfo-app-3.myapp.com
  
  sfo-api-1.myapp.com
  sfo-api-2.myapp.com
  sfo-api-3.myapp.com
  
  **LON**
  lon-load-balancing-1.myapp.com
  lon-load-balancing-2.myapp.com
  lon-load-balancing-3.myapp.com
  
  lon-app-1.myapp.com
  lon-app-2.myapp.com
  lon-app-3.myapp.com
  
  lon-api-1.myapp.com
  lon-api-2.myapp.com
  lon-api-3.myapp.com
  </code></pre>
  
  <p>And then if there's any strain on any given layer, in any given region, I can just spin up a new droplet to help out: <code>nyc-app-4.myapp.com</code>, <code>lon-load-balancing-5.myapp.com</code>, etc…</p>
  
  <p><strong>Current Working Methodology</strong></p>
  
  <ul>
  <li><p>A (minimum) trio of <code>global-balancing</code> servers receive all traffic.
  These servers are "DNS Round-Robin" balanced as illustrated in this
  (frankly confusing) article: <a href="https://www.digitalocean.com/community/tutorials/how-to-configure-dns-round-robin-load-balancing-for-high-availability" rel="noreferrer">How To Configure DNS Round-Robin Load
  Balancing</a>.</p></li>
  <li><p>Using the <a href="https://nginx.org/en/docs/http/ngx_http_geoip_module.html" rel="noreferrer">Nginx GeoIP
  Module</a> and
  <a href="https://www.maxmind.com/en/geolocation_landing" rel="noreferrer">MaxMind GeoIP Data</a>
  the origin of any given request is determined down to the
  <code>$geoip_city_continent_code</code>.</p></li>
  <li><p>The <code>global-balancing</code> layer then routes the request to the least
  connected server on the <code>load-balancing</code> layer of the appropriate
  cluster: <code>nyc-load-balancing-1</code>, <code>sfo-load-balancing-3</code>,
  <code>lon-load-balancing-2</code>, etc.. This layer is also a (minimum) trio of
  droplets.</p></li>
  <li><p>The regional <code>load-balancing</code> layer then routes the request to the
  least connected server in the app or api layer: <code>nyc-app-2</code>,
  <code>sfo-api-1</code>, <code>lon-api-3</code>, etc…</p></li>
  </ul>
  
  <p>The details of the Nginx kung fu can be found in this tutorial:
     <a href="https://gpeev.blogspot.ca/2013/02/setting-up-nginx-with-gslbreverse-proxy.html?m=1" rel="noreferrer">Villiage Idiot: Setting up Nginx with GSLB/Reverse Proxy on
     AWS</a>. More general info about Nginx load-balancing is available
     <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-load-balancing/" rel="noreferrer">here</a>
     and
     <a href="http://subprint.com/blog/nginx-load-balancer-and-reverse-proxy-for-node.js-applications-on-digital-ocean" rel="noreferrer">here</a>.</p>
  
  <p><strong>Questions</strong></p>
  
  <p><strong>Where do I put the <code>global-balancing</code> servers?</strong></p>
  
  <p>It strikes me as odd that I would put them either all in one place, or spread that layer out around the globe either. Say, for instance, I put them all in NYC. Then someone from France hits my domain. The request would go from France, to NYC, and then be routed back to LON. Or if I put one of each in SFO, NYC, and LON then isn't it still possible that a user from Toronto (Parkdale, represent) could send a request that ends up going to LON only to be routed back to NYC?</p>
  
  <p><strong>Do subsequent requests get routed to the same IP?</strong></p>
  
  <p>As in, if a user from Toronto sends a request that the <code>global-balancing</code> layer determines should be going to NYC, does the next request from that origin go directly to NYC, or is it still luck of the draw that it will hit the nearest <code>global-balancing</code> server (NYC in this case).</p>
  
  <p><strong>What about sessions?</strong></p>
  
  <p>I've configured Nginx to use the <a href="https://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash" rel="noreferrer">ip_hash;</a> directive so it will direct the user to the same <code>app</code> or <code>api</code> endpoint (a node process, in my case) but how will global balancing affect this, if at all?</p>
  
  <p><strong>Any DNS Examples?</strong></p>
  
  <p>I'm not exactly a DNS expert (I'm currently trying to figure out why my CNAME records aren't resolving) but I'm a quick study when provided with a solid example. Has anyone gone through this process before and can provide a sample of what the DNS records look like for a successful setup?</p>
  
  <p><strong>What about SSL/TLS?</strong></p>
  
  <p>Would I need a certificate for every server, or just for the three <code>global-balancing</code> servers since that's the only public-facing gateway?</p>
  
  <p>If you read this whole thing then reward yourself with a cupcake. Thanks in advance for any help.</p>