博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小程序 缩放_缩放流星应用程序的初体验
阅读量:2528 次
发布时间:2019-05-11

本文共 32478 字,大约阅读时间需要 108 分钟。

小程序 缩放

by Elie Steinbock

埃莉·斯坦博克(Elie Steinbock)

缩放流星应用程序的初体验 (First Experiences Scaling a Meteor App)

I recently went through the challenge and ordeal of having to scale my app. It’s a project that had already been running in production for about a year. This summer the app became a lot more popular with thousands of preseason signups. My initial setup could no longer handle the load and I was faced with a scaling problem that had to be solved quickly.

我最近经历了必须扩展应用程序的挑战和磨难。 这个项目已经在生产中运行了大约一年。 今年夏天,该应用程序因成千上万的季前注册而变得越来越受欢迎。 我的初始设置无法再处理负载,并且我面临着必须Swift解决的扩展问题。

This article describes the process I went through and some of the things I learnt along the way and my hope is that it will help others that face similar challenges in the future. It will cover the basics, such as what scaling is, and how load balancing works. It will also walk you through some basic setups, and show you how to scale your Meteor app.

本文介绍了我所经历的过程以及我在此过程中学到的一些东西,我希望这将有助于将来其他面临类似挑战的人。 它将涵盖基础知识,例如扩展能力以及负载平衡的工作原理。 它还将引导您完成一些基本设置,并向您展示如何扩展Meteor应用程序。

Before the summer I didn’t have any prior experience scaling apps, and despite the fact that I had read up about the topic quite a bit, when I had to actually sit down and start dealing with the challenges myself I felt quite lost and wasn’t sure I’d be able to fix the problems. I also felt that many of the articles I had read online assumed a fair amount of knowledge that I didn’t yet have.

在夏天之前,我没有扩展应用程序的经验,尽管我已经阅读了很多有关该主题的知识,但是当我不得不坐下来开始面对自己的挑战时,我却感到很失落,没有精神我不确定我能解决这些问题。 我还觉得,我在网上阅读的许多文章都假定了我还没有的大量知识。

My hope is that this article will help bridge some of that gap. I’m far from an expert on scaling Meteor applications, but I hope this article provides value to others that find themselves in a similar situation to the one I found myself in.

我希望本文将有助于弥合这一差距。 我不是扩展Meteor应用程序的专家,但是我希望本文为那些发现自己与我遇到的情况类似的其他人提供价值。

背景 (Background)

A bit of background about the app under discussion. It’s a draft-style fantasy football game for the English Premier League (soccer). Most of the signups happen the month before the season starts. Apart from all the signups, nearly all the drafts also happen in this month. The draft is when all users in a league come online to pick their team. Users pick their football players one at a time and the entire process is live with each user having between 30 seconds and 5 minutes per player pick.

有关正在讨论的应用程序的背景知识。 这是针对英超联赛(足球)的草案式幻想足球比赛。 大多数注册都发生在赛季开始前的一个月。 除了所有的签约之外,几乎所有的草稿都在这个月内完成。 草案是联盟中的所有用户都上网选择他们的球队时的选秀。 用户一次选择一名足球运动员,整个过程是实时进行的,每个用户每次选择足球的时间为30秒至5分钟。

At peak times the site had over 500 concurrent users online and 20 simultaneously drafts running. If the server becomes unresponsive during a draft, it completely ruins the user’s experience with players being picked for him automatically that he didn’t necessarily intend on picking, so it was extremely important to avoid this.

在高峰时段,该站点有超过500个在线并发用户,同时运行20个草稿。 如果服务器在选秀期间变得不响应,则将完全破坏用户的体验,因为他会自动选择为他的玩家,因此他不一定打算进行拾取,因此避免这种情况非常重要。

那么什么是缩放? (So What Is Scaling?)

To many this might seem obvious, but not so long ago, I had no idea what this buzzword meant.

在许多人看来,这似乎很明显,但是不久之前,我不知道这个流行词是什么意思。

Scaling is what happens when your app takes off. Your server can only handle so much load. What happens when 10,000 people want to use your app at the same time? Your server won’t be able to handle it, so you either need to get a better server, or get more servers to run the app. This process is called scaling.

伸缩是您的应用起飞时发生的事情。 您的服务器只能处理这么多的负载。 如果有10,000人希望同时使用您的应用程序,该怎么办? 您的服务器将无法处理它,因此您要么需要获得更好的服务器,要么需要更多服务器才能运行该应用程序。 此过程称为缩放。

There are two ways to scale an app. One is known as vertical scaling, and the other is known as horizontal scaling. Vertical scaling involves getting a more powerful server. Horizontal scaling involves serving your site from multiple servers.

扩展应用程序有两种方法。 一种称为垂直缩放,另一种称为水平缩放。 垂直扩展涉及获得功能更强大的服务器。 横向扩展涉及从多个服务器为您的站点提供服务。

To use an analogy, if you have a shop and employ one worker and want to be able to serve more customers, you can either get a better, faster worker (vertical scaling), or you can hire more employees (horizontal scaling).

打个比方,如果您有一家商店并雇用一名工人,并且希望能够为更多的客户提供服务,则可以聘用更好,更快的工人(纵向扩展),也可以雇用更多的员工(水平扩展)。

For web apps, vertical scaling is usually easier to do. At hosting companies such as or (Amazon Web Services), you can easily upgrade your virtual private server to a stronger configuration with increased RAM, CPUs and storage.

对于Web应用程序,垂直缩放通常更容易实现。 在诸如或 (Amazon Web Services)之类的托管公司中,您可以轻松地将虚拟专用服务器升​​级为具有增加的RAM,CPU和存储的更强配置。

The problem with this approach is that there’s always a limit to how powerful you can make your server. At some point you’re going to have to scale horizontally. Using the example above, your business can only go so far with a single employee. At a certain point you’re going to have to hire more staff members.

这种方法的问题在于,使服务器的功能始终受到限制。 在某些时候,您将不得不水平缩放。 使用上面的示例,您的业务只能由一名员工完成。 在某个时候,您将不得不雇用更多的员工。

When it comes to Meteor apps, you’re going to have to scale horizontally fairly early on. A Meteor app is really just a NodeJS app and therefore runs in a single process which means it can only make use of a single processor.

当涉及到Meteor应用时,您将必须在相当早的时候进行水平扩展。 Meteor应用程序实际上只是一个NodeJS应用程序,因此在单个进程中运行,这意味着它只能使用单个处理器。

We can make use of multiple processors by running multiple instances of our app at the same time. These processors could belong to the same server or spread across multiple different servers. Running multiple instances of an app means running the same app on different IPs or ports, and spreading the load over the different instances of the app. All instances of the app still connect to the same database and all connected clients will instantly receive any database updates irrespective of the app instance they’re connected to (assuming you’re using MongoDB’s Oplog tailing feature. Otherwise the updates might take a few seconds).

我们可以通过同时运行我们的应用程序的多个实例来利用多个处理器。 这些处理器可以属于同一服务器,也可以分布在多个不同的服务器上。 运行一个应用程序的多个实例意味着在不同的IP或端口上运行同一应用程序,并将负载分散到该应用程序的不同实例上。 该应用程序的所有实例仍连接到相同的数据库,并且所有连接的客户端将立即接收任何数据库更新,而无论它们连接到的应用程序实例如何(假设您使用的是MongoDB的Oplog拖尾功能。否则,更新可能需要几秒钟的时间) )。

Whether we run multiple instances of our app on a single server with multiple cores, or run multiple instances on multiple servers, what we’ve done is horizontal scaling and things work the same way in both cases.

无论是在具有多个内核的单个服务器上运行应用程序的多个实例,还是在多个服务器上运行多个实例,我们要做的就是水平扩展,两种情况下的工作方式相同。

Each platform will have its own scaling challenges. This article is about scaling Meteor apps. On other platforms you’ll be able to get away with vertical scaling for far longer. StackOverflow runs on and could even make do with 5. That’s some serious load on each server and is mostly a case of awesome vertical scaling.

每个平台都有其自身的扩展挑战。 本文是关于扩展Meteor应用程序的。 在其他平台上,您将能够获得更长的垂直缩放比例。 StackOverflow可以在上运行,甚至可以用5 来完成。这在每台服务器上都是相当大的负载,并且大多数情况下是极好的垂直扩展。

流星应用程序的不同部分 (The Different Parts Of A Meteor App)

We can split our app up into two logical components. The first part is the server that handles users’ requests sending the appropriate data back, and performs any tasks that need to be performed. The second part is the database that stores the app’s data.

我们可以将应用程序分为两个逻辑组件。 第一部分是服务器,用于处理用户的请求,将其发送回适当的数据,并执行所有需要执行的任务。 第二部分是存储应用程序数据的数据库。

The server interacts with the database querying it and updating it on a consistent basis.

服务器与数据库进行交互,以查询并一致地对其进行更新。

We’re not going to talk too much about scaling MongoDB. It’s probably going to be a while before you reach a point at which you’ll have to scale your database. If you’d like to know more about this topic, could be a good place to start.

关于扩展MongoDB,我们不会过多谈论。 您可能需要一段时间才能达到扩展数据库的水平。 如果您想了解更多有关此主题的信息, 可能是一个不错的起点。

扩展服务器之前要做的事情 (Things To Do Before Scaling Up The Server)

A good place to start before you get down to scaling is to make sure your app is running as efficiently as possible. The recommended tool to use to check the performance of your app and which methods and publications are taking the most time to complete is . The basic plan is free so there’s really no reason not to use it. Use the articles at to work out how best to optimize your app and where to devote your energy. In general, you want to optimize the methods and publications that run most often and take a long time to complete.

在开始扩展之前,一个好的开始是确保应用程序尽可能高效地运行。 推荐使用的工具是用来检查应用程序性能以及哪些方法和出版物花费最多时间的 。 基本计划是免费的,因此实际上没有理由不使用它。 使用上的文章来确定如何最好地优化您的应用程序以及在哪里投入精力。 通常,您希望优化最常运行且需要很长时间才能完成的方法和出版物。

One thing that is absolutely necessary for good performance is to make use of MongoDB indexes. You do this in Meteor by writing:

要获得良好的性能,绝对必要的一件事就是使用MongoDB索引。 您可以通过在Meteor中编写以下代码来做到这一点:

Posts._ensureIndex({userId: 1});

Posts._ensureIndex({userId:1});

This creates an index on the userId field in the Posts collection. You can also create indexes in MongoDB itself. See more on MongoDB indexes .

这将在Posts集合的userId字段上创建一个索引。 您还可以在MongoDB本身中创建索引。 在查看有关MongoDB索引的更多 。

See by Differential for some additional performance tips.

请参见由差一些更多的性能提示。

什么时候需要开始担心扩展? (When Do I Need To Start Worrying About Scaling?)

If your Meteor app has over 100 users online at any one time, you’re probably going to have to start worrying about scaling. (Of course, you don’t know when your app is going to take off. You could jump from 5 to 500 concurrent users in a single day, so it’s worth being prepared before this happens.)

如果您的Meteor应用程序一次同时具有100多个在线用户,则您可能不得不开始担心扩展问题。 (当然,您不知道您的应用何时开始起飞。您一天可以将5个并发用户跳到500个并发用户,因此值得在此之前做好准备。)

Depending on your app, you might be able to get up to 500 concurrent users on a single DigitalOcean droplet. My app struggles with 100–150 concurrent connections, at which point it hits 100% CPU. The bottleneck for most Meteor apps seems to be CPU and not RAM, so scaling horizontally is a must. You can add all the RAM you want, but it won’t help your app. Lack of CPU is what’s going to overload your app and you can only get more CPU power by making use of multiple CPUs (or multiple servers).

根据您的应用程序,一个DigitalOcean Droplet上最多可以同时容纳500个用户。 我的应用程序难以处理100–150个并发连接,这时它的CPU使用率达到100%。 大多数Meteor应用程序的瓶颈似乎是CPU,而不是RAM,因此必须水平扩展。 您可以添加所需的所有RAM,但对您的应用程序无济于事。 缺少CPU会使您的应用程序超负荷运行,并且只能通过使用多个CPU(或多个服务器)来获得更多的CPU功能。

The following graph from Kadira shows what happens when your app is under too much pressure.

Kadira的下图显示了当您的应用承受太大压力时会发生什么。

At around 7:28 PM you can see that the average response time for publications was about 18 seconds and for methods about 7 seconds. This isn’t a good situation to be in. The high response time was caused by a big spike in CPU which hit 100% for a couple of minutes. RAM isn’t an issue because only about 500MB is being used at any one time and the VPS being used here has 1GB RAM.

在晚上7:28左右,您可以看到出版物的平均响应时间约为18秒,方法的平均响应时间约为7秒。 这不是一个好情况。响应时间过长是由于CPU的峰值在几分钟内达到100%引起的。 RAM并不是问题,因为任何时候一次仅使用大约500MB,并且这里使用的VPS具有1GB RAM。

部署方式 (Deployment)

There are multiple ways to deploy your Meteor app. Here are some of the common solutions people use for production apps:

有多种方法来部署您的Meteor应用程序。 这是人们用于生产应用程序的一些常见解决方案:

  • Self-hosted on or AWS

    在或AWS上自行托管

There’s also the , but this should only be used for development purposes. MDG also just released , but the pricing for that currently starts at $500 a month. MDG is working on providing cheaper plans for Galaxy as well as a free plan, but at the time of the writing of this article, these aren’t an option.

还有 ,但这只能用于开发目的。 MDG也刚刚发布了 ,但目前其起价为每月500美元。 MDG正在努力为Galaxy提供更便宜的计划以及免费计划,但是在撰写本文时,这些方法不是一个选择。

It’s also common for people to host the database at another provider. A popular one is .

人们通常将数据库托管在其他提供程序上。 流行的是 。

Update: You can now get hosting starting at $29 per month. Compose.io no longer has a free plan. Another Mongo hosting provider called does. When you go into production (i.e. when development is over and people are actually using your app), you do not want to be using a free plan however.

更新:现在,您可以以每月29美元的价格开始购买主机。 Compose.io不再有免费计划。 另一个名为 Mongo托管服务提供商提供。 当您投入生产时(即,开发结束并且人们实际上正在使用您的应用程序时),但是您不想使用免费计划。

My own setup is DigitalOcean + Compose.io.

我自己的设置是DigitalOcean + Compose.io。

If you’d like to read about other setups, see the deployment section on .

如果您想了解其他设置,请参阅上的“部署”部分。

My initial setup was a $10 per month droplet. This gives you a one core VPS with 1GB RAM. You also get 30GB of storage, though you probably won’t use most of it.

我最初的设置是每月10美元的滴。 这为您提供了具有1GB RAM的单核VPS。 您还可以获得30GB的存储空间,尽管您可能不会使用其中的大部分空间。

I use Compose.io’s $18 per month Elastic Deployment plan for MongoDB database hosting. You can deal with the MongoDB stuff yourself, but it’s just extra work that I didn’t want to deal with.

我将Compose.io每月$ 18的弹性部署计划用于MongoDB数据库托管。 您可以自己处理MongoDB的内容,但这只是我不想处理的额外工作。

To deploy I use a tool called Meteor Up (or Mup for short). You can take a look at it on GitHub .

要部署,我使用了一个名为Meteor Up(简称Mup)的工具。 您可以在GitHub上它。

If you deploy on Modulus.io, they’ll take care of a lot of the scaling issues for you. If you want to run multiple instances of your app, all you have to do is move a slider up and down on the Modulus website. The more instances you run, the more it will cost you, but you can scale down whenever you want too.

如果您在Modulus.io上进行部署,他们将为您解决很多扩展问题。 如果要运行应用程序的多个实例,只需在Modulus网站上上下移动滑块即可。 运行的实例越多,花费的成本就越高,但是您也可以在需要时进行缩减。

I didn’t go with Modulus for deployment because I had some problems setting it up two years ago. I assume these issues would have been ironed out by now. The other issue is cost. It’s cheaper to deploy on DigitalOcean. The downside is that it might take up more of your time. Another advantage of going with DigitalOcean is finer grained control over your server.

我没有选择Modulus进行部署,因为两年前在设置它时遇到了一些问题。 我认为这些问题现在已经解决了。 另一个问题是成本。 在DigitalOcean上部署更便宜。 缺点是,这可能会占用您更多的时间。 与DigitalOcean一起使用的另一个优点是可以对服务器进行更精细的控制。

An article comparing DO, Modulus.io and Heroku can be found .

可以在找到比较DO,Modulus.io和Heroku的文章。

那么,您实际上如何扩展Meteor应用程序? (So how do you actually scale a Meteor app?)

As noted above, my app is deployed on Digital Ocean using Meteor Up. With this setup you don’t have the luxury of using a slider to load up more instances. A standard mup.json file looks something like this:

如上所述,我的应用是使用Meteor Up部署在Digital Ocean上的。 使用此设置,您不必奢侈地使用滑块加载更多实例。 标准的mup.json文件如下所示:

{   “servers”: [     {      “host”: “123.45.678.901”,      “username”: “root”,      “pem”: “~/.ssh/id_rsa”,      “env”: {}     },     {       “host”: “333.22.444.555”,       “username”: “root”,       “pem”: “~/.ssh/id_rsa”,       “env”: {}     }   ],   “setupMongo”: false,   “setupNode”: true,   “nodeVersion”: “0.10.40”,   “setupPhantom”: true,   “appName”: “myapp”,   “app”: “/Users/arunoda/Meteor/my-app”,   “env”: {      “PORT”: 80,      “ROOT_URL”: “http://myapp.com”,      “MONGO_URL”: “mongodb://arunoda:fd8dsjsfh7@hanso.mongohq.com:10023/MyApp",      "MONGO_OPLOG_URL": "mongodb://.....",      “MAIL_URL”: “smtp://postmaster%40myapp.mailgun.org:adj87sjhd7s@smtp.mailgun.org:587/”   },   “deployCheckWaitTime”: 15}

Notice that I’ve listed two servers in the servers block. When you’re first getting started, you’ll only have one server listed. With the following setup, we’ll be deploying to ip addresses 123.45.678.901 and 333.22.444.555. After deployment, if you were to visit either of these ip addresses in your browser, you’d see the same thing and both servers would be connected to the same database.

注意,我在服务器块中列出了两个服务器。 首次上手时,只会列出一台服务器。 使用以下设置,我们将部署到ip地址123.45.678.901333.22.444.555 。 部署后,如果您要在浏览器中访问这两个IP地址中的任何一个,则会看到相同的内容,并且两台服务器都将连接到同一数据库。

负载均衡 (Load Balancing)

So we’ve deployed our site, but we don’t want users visiting the site at random ip addresses. We want them visiting our domain. So let’s say our domain name is awesomedomain.com (which is better than example.com, in my humble opinion). How do we get each of our two servers to deal with half of the requests?

因此,我们已经部署了站点,但是我们不希望用户使用随机IP地址访问站点。 我们希望他们访问我们的域。 假设我们的域名是awesomedomain.com(以我的拙见,它比example.com更好)。 我们如何让两台服务器中的每台服务器处理一半的请求?

One way of doing this is by using a tool called . From :

一种实现方法是使用称为的工具。 从 :

Nginx (pronounced “engine x”) is a web server with a strong focus on high concurrency, performance and low memory usage. It can also act as a reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer and an HTTP cache.

Nginx (发音为“ engine x”)是一种Web服务器,非常注重高并发性,性能和低内存使用率。 它还可以充当HTTP,HTTPS,SMTP,POP3和IMAP协议的反向代理服务器,以及负载平衡器和HTTP缓存。

We’re going to use it for three things:

我们将其用于三件事:

  1. As a reverse proxy

    作为反向代理
  2. As a load balancer

    作为负载均衡器
  3. For SSL support

    对于SSL支持

What this means is that we’re going to run Nginx on one of our servers on port 80. Any traffic coming into the server from the web will be received by Nginx. Nginx will then forward the traffic on to instances of our Meteor app, which could be running on the same server on a different port, or a different server. Nginx will try and balance the number of requests that are sent to each instance.

这意味着我们将在端口80上的一台服务器上运行Nginx。任何从Web进入服务器的流量都将被Nginx接收。 然后,Nginx会将流量转发到我们的Meteor应用程序实例,该实例可能在同一服务器上的不同端口或其他服务器上运行。 Nginx将尝试平衡发送到每个实例的请求数量。

Nginx being a reverse proxy means it forwards requests on to other places and then responds to the user.

Nginx是反向代理,意味着它将请求转发到其他地方,然后响应用户。

Being a load balancer means it will split (balance) the load between the different instances of the app.

成为负载平衡器意味着它将在应用程序的不同实例之间分配(平衡)负载。

We’ll also use Nginx to provide us with SSL support. SSL support means that any data transferred between the user and our servers will be encrypted. Without SSL support, our Meteor site won’t work correctly in many countries, and it will also be fairly easy for people to or read any data that is transferred. Any site that uses HTTPS has SSL support.

我们还将使用Nginx为我们提供SSL支持。 SSL支持意味着用户和我们的服务器之间传输的所有数据都将被加密。 如果没有SSL支持,我们的Meteor网站在许多国家/地区将无法正常运行,人们也很容易或读取所传输的任何数据。 任何使用HTTPS的站点都具有SSL支持。

SSL isn’t the focus of this article, but it is a must for any production app and Nginx can take care of the SSL stuff for you. To set up SSL with Nginx, see . You don’t need to use Nginx for SSL support though. Meteor Up can also handle it using a tool called stud as shown .

SSL不是本文的重点,但是任何生产应用程序都必须使用SSL,Nginx可以为您处理SSL。 要使用Nginx设置SSL,请参见 。 不过,您不需要将Nginx用于SSL支持。 流星最多还可以使用如图称为螺柱工具处理它 。

So how do we setup Nginx?

那么我们如何设置Nginx?

To do this, I recommend following the first step of this tutorial:

为此,我建议遵循本教程的第一步:

Don’t bother following the rest of the tutorial. Meteor Up will take care of all that stuff for you automatically.

不要理会本教程的其余部分。 Meteor Up会自动为您处理所有这些事情。

The article also explains how to use Nginx for SSL support.

本文还介绍了如何将Nginx用于SSL支持。

Once all of that is working for you, you should have your app running at some domain. So far, Nginx hasn’t actually done much for us (except possibly SSL support.) We’re still not making use of our second Meteor instance, but that we’re going to fix that now.

一旦所有这些都适合您,您就应该在某个域中运行您的应用程序。 到目前为止,Nginx实际上并没有为我们做很多事情(可能还包括SSL支持。)我们仍然没有使用第二个Meteor实例,但是我们现在要修复它。

To make use of more servers, you need to add the following code to the top of your Nginx file:

要使用更多服务器,您需要在Nginx文件的顶部添加以下代码:

upstream myAppName {  ip_hash;               # for sticky sessions, more below  server 123.45.678.901:3000;  # server 1  server 333.22.444.555:3000;  # server 2}

Your Nginx file should now look something similar to this:

现在,您的Nginx文件应类似于以下内容:

upstream myAppName {  ip_hash;               # for sticky sessions, more below  server 123.45.678.901:3000;  # server 1  server 333.22.444.555:3000;  # server 2}server {  listen 80;  server_name www.myapp.com  # and all other "server" directives  location / {    # the "hostname" below must be same myAppName from upstream directive above    proxy_pass http://myAppName;    # and all other "location" directives  }}

…where myAppName would be something like example.com or app.example.com.

…其中myAppName类似于example.comapp.example.com。

The above code was adapted from .

上面的代码改编自 。

If you now reload Nginx (as described in the Digital Ocean article above) using:

如果现在使用以下命令重新加载Nginx(如上面的Digital Ocean文章所述):

nginx -t # check everything is okaynginx -s reload

The load will be split among your two Meteor instances.

负载将在您的两个Meteor实例之间分配。

If you’d like to add more instances in the future, all you have to do is add another line to Nginx upstream block and restart Nginx. Here’s an example that uses 4 Meteor instances, with 2 instances running on two different servers:

如果您想在将来添加更多实例,您要做的就是向Nginx上游块添加另一行并重新启动Nginx。 这是一个使用4个Meteor实例的示例,其中2个实例在两个不同的服务器上运行:

upstream myAppName {  ip_hash;  server 10.0.0.1:3000;  # server 1, core 1  server 10.0.0.1:3001;  # server 1, core 2  server 10.0.0.2:3000;  # server 2, core 1  server 10.0.0.2:3001;  # server 2, core 2  # or whatever other appropriate combination}

Removing instances just involves removing lines from the upstream block and restarting Nginx.

删除实例仅涉及从上游块中删除行并重新启动Nginx。

负载均衡算法 (Load Balancing Algorithms)

So if you just want to get things working, then following the above steps should work, but if you want to understand a little deeper, here’s a basic explanation of what we just did.

因此,如果您只是想让事情顺利进行,那么遵循上述步骤应该可以,但是如果您想更深入地了解,这是对我们所做工作的基本解释。

We’re using Nginx as a load balancer. For each request that comes in, Nginx has to decide which server to send it to. At the same time, Nginx has to be as quick as possible in doing its job, using as few resources as possible. Nginx is capable of handling 10,000 concurrent connections and simple load balancing algorithms are part of what makes this possible.

我们正在使用Nginx作为负载均衡器。 对于每个传入的请求,Nginx必须决定将其发送到哪个服务器。 同时,Nginx必须尽可能快地完成工作,并使用尽可能少的资源。 Nginx能够处理10,000个并发连接,而​​简单的负载平衡算法是使之成为可能的一部分。

A simple algorithm that is used to decide where to send the next request is called “round robin.” In this algorithm, the load balancer sends client requests to each server in turn and once it gets to the end of the server list, starts the process again. The outcome for three servers is: 1, 2, 3, 1, 2, 3, 1, 2,…

用于确定将下一个请求发送到哪里的简单算法称为“循环”。 在这种算法中,负载平衡器将客户端请求依次发送到每个服务器,一旦到达服务器列表的末尾,它将再次开始该过程。 三个服务器的结果是:1、2、3、1、2、3、1、2…

There are many other algorithms that can also be used to decide which server to send a request to, but one constraint that Meteor requires us to follow is that each request from a user should be sent to the same instance. This is also known as “sticky sessions.” A user sticks with the same server the entire session.

还有许多其他算法也可以用来确定将请求发送到哪个服务器,但是Meteor要求我们遵循的一个约束是来自用户的每个请求都应发送到同一实例。 这也称为“粘性会话”。 用户在整个会话中都使用同一台服务器。

This means we can’t use the round robin algorithm for our Meteor app, which doesn’t take into account which server the user first connected to. Instead we use the ip_hash algorithm which is explained in the as follows:

这意味着我们不能对Meteor应用程序使用循环算法,该算法没有考虑用户首先连接到哪个服务器。 相反,我们使用ip_hash算法,该算法在中进行了如下解释:

With ip-hash, the client’s IP address is used as a hashing key to determine what server in a server group should be selected for the client’s requests. This method ensures that the requests from the same client will always be directed to the same server except when this server is unavailable.
使用ip-hash,客户端的IP地址用作哈希密钥,以确定应为客户端的请求选择服务器组中的哪个服务器。 此方法可确保将来自同一客户端的请求始终定向到同一服务器,除非该服务器不可用。

本地运行 (Running Locally)

You can try out running two instances of your app locally too. To do this open up two terminal windows and start one Meteor app on the standard port (3000) by running:

您也可以尝试在本地运行应用程序的两个实例。 为此,请打开两个终端窗口,并通过运行以下命令在标准端口(3000)上启动一个Meteor应用程序:

meteor

The database will now be running on port 3001.

数据库现在将在端口3001上运行。

In a separate terminal window run another instance of the app on port 4000 that connects to the same database by running the following:

在单独的终端窗口中,在端口4000上运行该应用程序的另一个实例,该实例通过运行以下命令连接到同一数据库:

export MONGO_URL=mongodb://localhost:3001/meteor
meteor --port 4000

You can now visit localhost:3000 or localhost:4000 in your web browser and both will make changes to the same database.

现在,您可以在Web浏览器中访问localhost:3000localhost:4000 ,并且两者都将对同一数据库进行更改。

要注意的事情 (Things to be Aware of)

There might be code in your app that you only want running once. For example, in my fantasy football game, I only want one server updating scores.

您的应用程序中可能有一些您只希望运行一次的代码。 例如,在我的梦幻足球比赛中,我只希望一台服务器更新分数。

Another issue that can come up is that certain operations can be quite expensive. Again, updating scores in the game is quite a long process and I don’t want it interfering with the basic functioning of the app.

可能出现的另一个问题是某些操作可能会非常昂贵。 同样,在游戏中更新分数是一个漫长的过程,我不希望它干扰应用程序的基本功能。

So how do you solve these problems?

那么如何解决这些问题呢?

There are multiple ways to deal with such a situation, but I’ll just outline what I did.

有多种方法可以处理这种情况,但我只概述一下我所做的事情。

I set up a new droplet on Digital Ocean that doesn’t receive any traffic from the main website. It can be accessed at its IP address, but this droplet doesn’t receive any traffic from the website’s public URL. This instance is in charge of running all background tasks and any task that should only run once.

我在Digital Ocean上设置了一个新的Droplet,它没有收到来自主网站的任何流量。 可以通过其IP地址对其进行访问,但是此Droplet不会从网站的公共URL接收任何流量。 该实例负责运行所有后台任务以及仅应运行一次的所有任务。

To make code specific to only one instance of the app, I make use of environment variables. In your local environment you can export variables in your terminal window as follows:

为了使代码仅针对该应用程序的一个实例,我使用了环境变量。 在您的本地环境中,可以按如下所示在终端窗口中导出变量:

export ENV_VAR=valueOfOurVar

We did this before for MONGO_URL.

我们之前是针对MONGO_URL这样做的

You can access environment variables in your Meteor app using:

您可以使用以下方法在Meteor应用中访问环境变量:

process.env.ENV_VAR

In my app I can do something like this if I only want one instance of the app to run certain code:

如果我只希望应用程序的一个实例运行某些代码,则可以在我的应用程序中执行以下操作:

if (process.env.RUN_BACKGROUND_TASKS === ‘true’) {   // do some task}

I could also have used a pure microservices approach, but this would have taken a bit more time for me to set up and code sharing would have been harder.

我也可以使用纯粹的微服务方法,但是这将花费我更多的时间来设置,并且代码共享会更加困难。

When using Meteor Up, you can set environment variables for a specific instance as follows:

使用Meteor Up时,您可以为特定实例设置环境变量,如下所示:

“servers”: [   {     “host”: “...”,     “username”: “...”,     “pem”: “...”,     “env”: {       “ENV_VAR”: “123”,       “RUN_BACKGROUND_TASKS”: “true”     }   } ],

There are also packages that don’t work well when running multiple instances of an app either. One package I came across that falls into this category is . This package tells you which users are online at any given time and when running multiple instances. One server will have an open connection to a specific client while the rest won’t and this package doesn’t know how to deal with such a situation. A closed connection implies a user is offline. A work around is to use the package instead.

当运行一个应用程序的多个实例时,也有一些软件包不能很好地工作。 我遇到的一个属于此类的软件包是 。 该软件包告诉您在给定时间哪些用户在线,并且在运行多个实例时 。 一台服务器将与特定客户端建立开放连接,而其余服务器则无法打开,并且该程序包不知道如何处理这种情况。 封闭的连接意味着用户处于脱机状态。 解决方法是改用包。

You don’t want cron tasks running on multiple instances either. For this you can use the package. I didn’t personally make use of it, but it looks like a good solution opting instead to restrict all cron tasks to a specific server, but it looks like a good solution.

您也不希望cron任务在多个实例上运行。 为此,您可以使用软件包。 我个人没有使用它,但是它看起来像是一个不错的解决方案,而是选择将所有cron任务限制在特定的服务器上,但这看起来像是一个很好的解决方案。

其他解决方案 (Other Solutions)

There are many ways to do what we did in this article. Using Nginx is not the only solution. For SSL support, we could have used instead as Meteor Up does. For load balancing we could have used a tool called whose sole purpose is to be a load balancer.

有很多方法可以完成本文中的操作。 使用Nginx并不是唯一的解决方案。 对于SSL支持,我们可以像Meteor Up一样使用 。 为了实现负载平衡,我们可以使用称为的工具,其唯一目的是成为负载平衡器。

Another approach to all this is to use the package. It’s simply a Meteor package which you add as follows:

所有这一切的另一种方法是使用包。 它只是一个Meteor软件包,您可以按如下所示添加它:

meteor add meteorhacks:cluster

To get see it working immediately on your own machine export the following environment variable to your terminal:

为了使它立即在您自己的机器上运行,请将以下环境变量导出到终端:

export CLUSTER_WORKERS_COUNT=2

If you now run your app, you should see two instances of your Meteor app start up. Here we made use of the cluster package’s multicore support. We can also use cluster to distribute load among multiple servers. You should look at the to set this up.

如果现在运行您的应用程序,则应该看到Meteor应用程序的两个实例正在启动。 在这里,我们利用了群集程序包的多核支持。 我们还可以使用群集在多台服务器之间分配负载。 您应该查看来进行设置。

Is it better to use MeteorHacks Cluster or Nginx?

使用MeteorHacks Cluster还是Nginx更好?

I don’t know the answer to this question. I did have problems using MeteorHacks Cluster in production when making use of its multicore support. The app would work fine under low stress conditions, but under heavy load the app would randomly crash required a manual restart to get it working again. There’s an open issue on GitHub for it . If you don’t use the multicore support this shouldn’t be an issue though.

我不知道这个问题的答案。 当使用MeteorHacks Cluster的多核支持时,我确实遇到了问题。 该应用程序在低压力条件下可以正常运行,但是在重负载下,该应用程序将随机崩溃,需要手动重启才能使其再次运行。 有GitHub上一个开放的问题,它 。 如果您不使用多核支持,那么这应该不是问题。

我的最终设置 (My Final Setup)

The database runs on Compose.io at a cost of $18/month per GB of space used.

该数据库在Compose.io上运行,每使用1 GB的空间每月需要花费$ 18。

The app currently runs on 8 droplets:

该应用程序当前可在8个小滴上运行:

($5/month droplet has 512MB RAM and 1 core, $10/month droplet has 1GB RAM and 1 core, $20/month droplet has 2GB RAM and 2 cores.)

($ 5 /月Droplet具有512MB RAM和1个核心,$ 10 /月Droplet具有1GB RAM和1个核心,$ 20 /月Droplet具有2GB RAM和2个核心。)

  • 1 $5/month droplet takes care of background tasks and doesn’t handle any user requests.

    1个每月$ 5的Droplet负责后台任务,不处理任何用户请求。
  • 1 $20/month 2-core droplet runs Nginx and 2 Meteor instances of the app.

    1个$ 20 /月2核小滴运行该应用程序的Nginx和2个Meteor实例。
  • 4 $10/month droplets (1 instance per droplet)

    4个$ 10 /月的液滴(每个液滴1个实例)
  • 2 $5/month droplets (1 instance per droplet)

    2个每月$ 5的小滴(每个小滴1个实例)

There’s also a $5/month droplet for the blog that runs on Ghost on a subdomain (this isn’t Meteor).

在子域(不是Meteor)上的Ghost上运行的博客,每月还有$ 5的小费。

I’m also working on a mobile app and this will run on other droplets and will serve a different site to visitors. The client views/logic here is different, the server logic is the same.

我也在开发一个移动应用程序,它将在其他Droplet上运行,并将为访问者提供另一个网站。 客户端视图/逻辑在这里是不同的,服务器逻辑是相同的。

选择哪些液滴? (Which Droplets To Choose?)

So you may be wondering why my droplets are different sizes. At first I only used $10/month droplets, but since my bottleneck is CPU and not RAM, I should be able to replace all my $10/month droplets with $5/month droplets, since you get the same CPU power with each.

因此,您可能想知道为什么我的液滴大小不同。 起初,我仅使用$ 10 / month的droplet,但是由于我的瓶颈是CPU而不是RAM,因此我应该能够用$ 5 / month的水滴替换我所有的$ 10 / month的水滴,因为每个设备的CPU能力相同。

I’m in the process of testing this out now and seeing how it goes. You need to be careful that you don’t run out of RAM when using 512MB droplets. If you use the package, your server can crash when a search engine indexes your site and it will cause CPU to spike to 100%. You can get around this by using instead of spiderable and/or . If you’re using React then you can use server-side rendering for search engines instead of spiderable as explained .

我正在测试中,看看它如何进行。 使用512MB的Drops时,请注意不要耗尽RAM。 如果您使用可程序包,则当搜索引擎将您的网站编入索引时,服务器可能会崩溃,这将导致CPU峰值达到100%。 您可以使用而不是Spiderable和/或来解决此问题。 如果你使用的React,那么你可以使用服务器端呈现的搜索引擎,而不是作为spiderable解释 。

自动缩放 (Autoscaling)

It would be nice to be able to automatically load up more droplets when the site is under stress and take them down when no one is using it. My site is used a lot more during the weekends for example. It would be nice if I could automatically launch more droplets whenever there’s a lot of traffic and take them down when there’s less traffic.

能够在承受压力的情况下自动加载更多的液滴,并在没人使用时将其清除,这将是很好的。 例如,在周末,我的网站被大量使用。 如果在流量大的时候我可以自动启动更多的液滴,而在流量小的时候将它们丢弃,那将是很好的。

I haven’t seen an easy solution to this yet for Meteor apps deployed on DigitalOcean, but making use of the DigitalOcean API this should be possible without too much work. It would cut down hosting costs significantly.

对于在DigitalOcean上部署的Meteor应用程序,我还没有看到一个简单的解决方案,但是使用DigitalOcean API可以做到,无需太多工作。 这将大大降低托管成本。

It seems to be quite easy to autoscale on Modulus as shown . And you can read about autoscaling on AWS and .

这似乎是很容易如图所示模自动伸缩 。 您可以在和阅读有关在AWS上自动缩放的 。

我会做不同的事情 (Things I’d do Differently)

I’d test that my app can run well on two servers at a much earlier stage in the development process. The jump from 1 server to 2 servers is fairly big if you’ve never done it before. The jump from 2 servers to 10 servers is tiny.

我将测试我的应用程序在开发过程的早期是否可以在两台服务器上正常运行。 如果您以前从未做过,那么从1台服务器跳到2台服务器就相当大。 从2台服务器跳到10台服务器的幅度很小。

有关扩展流星应用程序的其他资源 (Other Resources on Scaling Meteor Apps)

以后的增加 (Later Additions)

I really liked the following post. It has some key info on load testing, a better Nginx setup, and using a CDN:

我真的很喜欢以下帖子。 它具有有关负载测试,更好的Nginx设置以及使用CDN的一些关键信息: :

翻译自:

小程序 缩放

转载地址:http://ebyzd.baihongyu.com/

你可能感兴趣的文章
Arduino编程器 USBasp USBtinyISP FT232-ISP 对比 区别
查看>>
RDLC交叉报表动态列空白页问题
查看>>
Python学习之字典集合篇
查看>>
多分类问题中,实现不同分类区域颜色填充的MATLAB代码(demo:Random Forest)
查看>>
同事是竞合关系不是零和关系
查看>>
python 获取当前运行的 class 和 方法的名字
查看>>
centos7 重启网卡失败
查看>>
springboot(一)注解
查看>>
07 Mybatis的多表查询1----1对多和多对1
查看>>
debian和ubuntu的sh dash bash
查看>>
java9-8 局部内部类
查看>>
数据库分页
查看>>
Centos6.8源码编译安装PHP7
查看>>
012 debug调试工具的指令
查看>>
慕课网消息的接收与响应3
查看>>
第三十二讲:UML类图(下)
查看>>
linux下更改时区
查看>>
复杂链表的复制
查看>>
code vs 3376 符号三角形
查看>>
[CF193B] Xor(暴力,剪枝,异或)
查看>>