为啥当 cpu 为 100% 时我的负载均衡器不会重定向到可用的 ec2?

Posted

技术标签:

【中文标题】为啥当 cpu 为 100% 时我的负载均衡器不会重定向到可用的 ec2?【英文标题】:Why my load balancer doesn't redirect to avaliable ec2 when cpu is 100%?为什么当 cpu 为 100% 时我的负载均衡器不会重定向到可用的 ec2? 【发布时间】:2020-04-28 03:10:44 【问题描述】:

我在 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!`));

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

好吧,我不知道我的服务器什么时候会很忙。我需要将 ALB 设置为每 10 秒检查一次,以便从 / 获得 200? 我对您的应用程序了解得不够多,无法告诉您应该是什么。当另一个节点没有被利用时,您的一个节点真的会使用 100% 的 CPU 吗? 可以。基本上我希望不会,我写的代码一直都是异步的。但是如果cpu是100%呢?我考虑创建一个路由/health-check 只需返回 json:ok: true。并且在 aws 中为这条路线设置了健康。你怎么看这个想法? 健康检查的推荐值是多少?健康阈值、不健康阈值、超时、间隔? 您应该考虑添加自动缩放以增加实例数量,以便所有实例的平均 CPU 使用率保持在某个阈值以下。我不明白你关于“如果 cpu 是 100% 怎​​么办”的问题?你的问题可能会被问到任何曾经写过的软件。我的问题是,如果您的所有服务器之间的负载均衡,为什么其他服务器没有达到 100% 的负载?

以上是关于为啥当 cpu 为 100% 时我的负载均衡器不会重定向到可用的 ec2?的主要内容,如果未能解决你的问题,请参考以下文章

当 CPU 负载为 100%(主要使用 C++ 和 Qt)时,如何保持 UI 响应?

我的多线程游戏一直处于 100% CPU。如何管理线程活动以减少 CPU 负载?

为啥没有“Thread.sleep”的“while(true)”会在 Linux 上导致 100% 的 CPU 使用率,而在 Windows 上却不会?

为啥当我重载数组运算符时我的私有变量为零? [关闭]

为啥我的电脑用了一会CPU使用率就达到100%

为啥这个微不足道的 opengl 程序使用 100% cpu?