1

我在 aws ecs 中运行我的 nodejs 应用程序。

我在 ecs 中创建了一个集群。集群正在运行一个运行任务的服务。在任务中,我有 nginx(端口映射:0:80 - ALB 的动态端口)和 nodejs 图像。

Dockerfile 很简单(没什么特别的):

dockerfile nginx:

FROM nginx:latest

WORKDIR /

RUN echo "deb http://ftp.debian.org/debian stretch-backports main" >> /etc/apt/sources.list

RUN apt-get -y update && \
    apt-get -y install apt-utils && \
    apt-get -y upgrade && \
    apt-get -y install nano && \
    apt-get -y clean

COPY ./nginx/nginx.conf  /etc/nginx/nginx.conf

Dockerfile nodejs 应用程序:

FROM node:latest

WORKDIR /usr/src/app

COPY ./package.json .

COPY ./app-prod-www.js .

RUN npm install

EXPOSE 3000

CMD [ "npm", "start" ]

和 nginx.conf:

user  nginx;                                                                    

worker_processes 4;

events { worker_connections 1024; }

error_log  /var/log/nginx/error.log warn;                                       
pid        /var/run/nginx.pid;                                                  

http {                                                                          
    include       /etc/nginx/mime.types;                                        
    default_type  application/octet-stream;                                     

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '   
                      '$status $body_bytes_sent "$http_referer" '               
                      '"$http_user_agent" "$http_x_forwarded_for"';             

    access_log  /var/log/nginx/access.log  main;                                

    sendfile        on;                                                         
    #tcp_nopush     on;                                                         

    keepalive_timeout  65;                                                      

    #gzip  on;                                                                  

    # include /etc/nginx/conf.d/*.conf;                                           
    # include /etc/nginx/sites-available/*.conf;                                           

    upstream prodwww {   
        least_conn;                                                                                  
        server prod-www:3000 weight=10 max_fails=3 fail_timeout=30s;
    }

    server {                                                                                                  
        listen       80;                                                                                      

        location / {                                                                                         
            proxy_pass http://prodwww;                                                                     
            proxy_http_version 1.1;                                                                          
            proxy_set_header Upgrade $http_upgrade;                                                          
            proxy_set_header Connection 'upgrade';                                                           
            proxy_set_header Host $host;                                                                     
            proxy_cache_bypass $http_upgrade;                                                                
        }                                                                                                      
    }                                                                                                         
}

集群有两个 ec2 实例。

该服务正在运行 4 个任务。

我设置了一个 ALB,它应该将流量重定向到那些 ec2 实例。

但是当我在其中一个容器中有 100% cpu 时,ALB 不会将流量重定向到空闲的 ec2 机器。

当我访问 /test 路由时,我编写了一个斐波那契代码。这将导致 100% cpu。并且 nodejs 应用程序在完成之前无法收到任何请求(并且 Fibonacci(100) 将需要很长时间)。

所以在我访问/test路由之后,我可以看到这需要很多时间才能完成。同时,我在浏览器中打开新选项卡并尝试访问/应该为文本提供服务的根路由 () App Prod WWW

但我可以看到它没有响应。这意味着 ALB 仍然将我重定向到这个 nodejs 应用程序实例。

这是为什么?如果我错过了这里的信息,请告诉我,我会更新我的问题。

这是我的应用程序:

const express = require('express');
const app = express();
const port = 3000;

console.log('app prod www nodejs started');

app.get('/', (req, res) => res.send(`App Prod WWW! ${process.pid}/${process.env.NAME}`));

app.get('/test', (req, res) => {
  console.log('in test');
  function fibonacci(n) {
    return n < 1 ? 0 : n <= 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2);
  }

  const x = fibonacci(100);
  console.log('after x');
  res.json({ x });
});

app.get('/api', (req, res) => {
  console.log('in api');
  res.json({ ok: true });
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));
4

1 回答 1

4

默认情况下,负载均衡器将仅使用循环算法在所有目标之间平均分配请求。负载均衡器将定期执行您配置的运行状况检查,以确保目标可以接受请求。

负载均衡器不会监控目标的 CPU 使用率。在目标实例的定期健康检查失败之前,目标将继续接收请求。

于 2020-01-10T13:47:59.023 回答