我们使用 AWS 来托管 Magento。我们在同一区域的不同可用区中拥有 3 台 c4.4xlarge 服务器,作为运行 HHVM 和 Nginx 的后端 Web 服务器。每台服务器都连接到一个多可用区 RDS 实例以用于其数据库。
在后端服务器前面,我们尝试了几种选项来平衡服务器负载:AWS 应用程序负载均衡器、AWS 经典负载均衡器、HAProxy 和 Nginx。我们要求 AWS 预热经典负载均衡器,因为通常流量几乎为零。
我们原本打算将 HAProxy 放在 t2.medium 服务器上,但也尝试将其放在 c4.large 服务器上,以确保这不是瓶颈。HAProxy、sysctl 和 Nginx 配置如下。我们原本打算使用内部 IP,但也尝试过使用弹性 IP。
HAProxy 配置
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
maxconn 100000
tune.bufsize 16384 # Tried without
tune.maxrewrite 1024 # Tried without
tune.maxaccept -1 # Tried without
nbproc 4 # Tried without
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
defaults
log global
mode http # Tried tcp
balance roundrobin # Tried leastconn
option httplog
option abortonclose
option redispatch # Added
option dontlognull
option dontlog-normal # Added
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
stats enable
stats uri /haproxy?stats
stats realm redacted
stats auth redacted
option http-server-close
option forwardfor
option redispatch
frontend www-http
bind 0.0.0.0:80
reqadd X-Forwarded-Proto:\ http
default_backend www-backend
acl admin_tag path_beg /index.php/redacted
acl admin_tag path_beg /redacted
use_backend www-admin-backend if admin_tag
frontend www-https
bind 0.0.0.0:443 ssl crt /etc/ssl/private/redacted.pem
reqadd X-Forwarded-Proto:\ https
default_backend www-backend
acl admin_tag path_beg /index.php/redacted
acl admin_tag path_beg /redacted
use_backend www-admin-backend if admin_tag
backend www-backend
redirect scheme https if !{ ssl_fc }
cookie SERVERID insert indirect nocache
server redacted redacted:80 check cookie web1
server redacted redacted:80 check cookie web2
server redacted redacted:80 check cookie web3
backend www-admin-backend
redirect scheme https if !{ ssl_fc }
cookie SERVERADMINID insert indirect nocache
server redacted redacted:80 check cookie web1
Nginx 配置
upstream backend {
least_conn;
keepalive 8;
server redacted max_fails=3 fail_timeout=10s;
server redacted max_fails=3 fail_timeout=10s;
server redacted max_fails=3 fail_timeout=10s;
}
server {
listen 443 default_server;
server_name _;
ssl on;
ssl_certificate /redacted/cert_chain.crt;
ssl_certificate_key /redacted/private.key;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Sysctl 配置
fs.file-max = 10000000
fs.nr_open = 10000000
net.ipv4.tcp_mem = 786432 1697152 1945728
net.ipv4.tcp_rmem = 4096 4096 16777216
net.ipv4.tcp_wmem = 4096 4096 16777216
net.ipv4.netfilter.ip_conntrack_max = 50000
net.ipv4.ip_local_port_range = 1024 65000
在每种配置(不同的负载均衡器实例、不同的负载均衡器应用程序/服务、不同的配置)下,我们每秒只能获得 50 个请求。1/3 核心的 CPU 使用率约为 30%,因此总体约为 10%。
我们已经使用外部服务器上的 Apachebench 验证了这一点(从 120 个并发连接开始,然后是 160 个和 200 个 - 响应时间变慢,吞吐量几乎相同)。我们还使用 blitz.io 验证了这一点,我们从 200 个用户开始,慢慢爬升到 1600 个 - 吞吐量相同,CPU 使用率相同,响应时间变慢。
我们还尝试直接对后端服务器进行负载平衡,并且我们能够在一台后端服务器上处理大约每秒 50 个请求,CPU 使用率显然更高。
任何日志(Nginx、haproxy、任何服务器上的内核)中都没有任何内容。我还与 AWS 支持人员进行了交流,他们告诉我没有网络速率限制。
我是不是漏掉了什么?似乎负载均衡器与后端服务器之间的连接存在瓶颈,但我不知道我们还没有测试过什么。