Trouble with Nginx and Multiple Meteor/Nodejs Apps

2020-02-17 11:02发布

问题:

I understand that multiple node.js, and I assume by extension Meteor, can be run on one server using Nginx. I've got Nginx setup and running on a Ubuntu server just fine, I can even get it to respond to requests and proxy them to one application of mine. I however hit a roadblock when trying to get Nginx to proxy traffic to the second application.

Some background:

  • 1st app running on port 8001
  • 2nd app running on port 8002
  • Nginx listening on port 80
  • Attempting to get nginx to send traffic at / to app one and traffic at /app2/ to app two
  • Both apps can be reached by going to domain:8001 and domain:8002

My Nginx config:

upstream mydomain.com {
server 127.0.0.1:8001;
server 127.0.0.1:8002;
}

# the nginx server instance
server {
listen 0.0.0.0:80 default_server;
access_log /var/log/nginx/mydomain.log;

location /app2 {
  rewrite /app2/(.*) /$1 break;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true;
  proxy_pass http://127.0.0.1:8002;
  proxy_redirect off;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}

location / {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true;
  proxy_pass http://127.0.0.1:8001;
  proxy_redirect off;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}
}

Any insight as to what might be going on when traffic goes to /app2/ I'd greatly appreciate it!

回答1:

proxy_pass http://127.0.0.1:8002/1;  <-- these should be 
proxy_pass http://**my_upstream_name**;  <--these

then

upstream my_upstream_name {  

//Ngixn do a round robin load balance, some users will conect to / and othes to /app2

server 127.0.0.1:8001;

server 127.0.0.1:8002;

}

A few tips control the proxy:

take a look here @nginx docs

then here we go:

weight = NUMBER - set weight of the server, if not set weight is equal to one. unbalance the default round robin.

max_fails = NUMBER - number of unsuccessful attempts at communicating with the server within the time period (assigned by parameter fail_timeout) after which it is considered inoperative. If not set, the number of attempts is one. A value of 0 turns off this check. What is considered a failure is defined by proxy_next_upstream or fastcgi_next_upstream (except http_404 errors which do not count towards max_fails).

fail_timeout = TIME - the time during which must occur *max_fails* number of unsuccessful attempts at communication with the server that would cause the server to be considered inoperative, and also the time for which the server will be considered inoperative (before another attempt is made). If not set the time is 10 seconds. fail_timeout has nothing to do with upstream response time, use proxy_connect_timeout and proxy_read_timeout for controlling this.

down - marks server as permanently offline, to be used with the directive ip_hash.

backup - (0.6.7 or later) only uses this server if the non-backup servers are all down or busy (cannot be used with the directive ip_hash)

EXAMPLE generic

    upstream  my_upstream_name  {
      server   backend1.example.com    weight=5;
      server   127.0.0.1:8080          max_fails=3  fail_timeout=30s;
      server   unix:/tmp/backend3;
    }
//   proxy_pass http://my_upstream_name; 

tho these is what you need:

if u just want to control de load between vhosts for one app :

 upstream  my_upstream_name{
          server   127.0.0.1:8080          max_fails=3  fail_timeout=30s;
          server   127.0.0.1:8081          max_fails=3  fail_timeout=30s;
          server   127.0.0.1:8082          max_fails=3  fail_timeout=30s;
          server   127.0.0.1:8083 backup;
//  proxy_pass http://my_upstream_name; 
// amazingness no.1, the keyword "backup" means that this server should only be used when the rest are non-responsive
    } 

if u have 2 or more apps: 1 upstream per app like:

upstream  my_upstream_name{
              server   127.0.0.1:8080          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8081          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8082          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8083 backup;  
            } 
upstream  my_upstream_name_app2  {
              server   127.0.0.1:8084          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8085          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8086          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8087 backup; 
            } 
upstream  my_upstream_name_app3  {
              server   127.0.0.1:8088          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8089          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8090          max_fails=3  fail_timeout=30s;
              server   127.0.0.1:8091 backup;  
            } 

hope it helps.



回答2:

People looking for alternative for Nginx: Install Cluster package for each Meteor app and the package will handle load balancing automatically. https://github.com/meteorhacks/cluster

How to set it up:

# You can use your existing MONGO_URL for this
export CLUSTER_DISCOVERY_URL=mongodb://host:port/db,
# this is the direct URL to your server (it could be a private URL)
export CLUSTER_ENDPOINT_URL=http://ipaddress
# mark your server as a web service (you can set any name for this)
export CLUSTER_SERVICE=web

Example setup:

{
  "ip-1": {
    "endpointUrl": "http://ip-1",
    "balancerUrl": "https://one.bulletproofmeteor.com"
  },
  "ip-2": {
    "endpointUrl": "http://ip-2",
    "balancerUrl": "https://two.bulletproofmeteor.com"
  },
  "ip-3": {
    "endpointUrl": "http://ip-3",
    "balancerUrl": "https://three.bulletproofmeteor.com"
  },
  "ip-4": {
    "endpointUrl": "http://ip-4"
  }
}