Недавно у нас был всплеск трафика, который, хотя и был умеренным по размеру, привел к тому, что haproxy перегружал одно из ядер ЦП (и сервер перестал отвечать). Я предполагаю, что я делаю что-то неэффективно с конфигурацией, и поэтому хотел бы спросить всех экспертов по haproxy, не будут ли они так любезны, чтобы критиковать мой файл конфигурации ниже (в основном с точки зрения производительности).
Конфигурация предназначена для распределения между группой серверов http-приложений, группой серверов, которые обрабатывают соединения с веб-сокетами (с несколькими отдельными процессами на разных портах), и статическим файловым веб-сервером. Он работает хорошо, судя по производительности. (Некоторые детали отредактированы.)
Мы будем очень признательны за любые рекомендации, которые вы могли бы предложить!
HAProxy v1.4.8
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
daemon
maxconn 100000
log 127.0.0.1 local0 notice
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
log global
mode http
option httplog
option httpclose #http://serverfault.com/a/104782/52811
timeout connect 5000ms
timeout client 50000ms
timeout server 5h #long timeouts to stop WS drops - when v1.5 is stable, use 'timeout tunnel';
#---------------------------------------------------------------------
# FRONTEND
#---------------------------------------------------------------------
frontend public
bind *:80
maxconn 100000
reqidel ^X-Forwarded-For:.* #Remove any x-forwarded-for headers
option forwardfor #Set the forwarded for header (needs option httpclose)
default_backend app
redirect prefix http://xxxxxxxxxxxxxxxxx code 301 if { hdr(host) -i www.xxxxxxxxxxxxxxxxxxx }
timeout client 5h #long timeouts to stop WS drops - when v1.5 is stable, use 'timeout tunnel';
# ACLs
##########
acl static_request hdr_beg(host) -i i.
acl static_request hdr_beg(host) -i static.
acl static_request path_beg /favicon.ico /robots.txt
acl test_request hdr_beg(host) -i test.
acl ws_request hdr_beg(host) -i ws
# ws11
acl ws11x1_request hdr_beg(host) -i ws11x1
acl ws11x2_request hdr_beg(host) -i ws11x2
acl ws11x3_request hdr_beg(host) -i ws11x3
acl ws11x4_request hdr_beg(host) -i ws11x4
acl ws11x5_request hdr_beg(host) -i ws11x5
acl ws11x6_request hdr_beg(host) -i ws11x6
# ws12
acl ws12x1_request hdr_beg(host) -i ws12x1
acl ws12x2_request hdr_beg(host) -i ws12x2
acl ws12x3_request hdr_beg(host) -i ws12x3
acl ws12x4_request hdr_beg(host) -i ws12x4
acl ws12x5_request hdr_beg(host) -i ws12x5
acl ws12x6_request hdr_beg(host) -i ws12x6
# Which backend....
###################
use_backend static if static_request
#ws11
use_backend ws11x1 if ws11x1_request
use_backend ws11x2 if ws11x2_request
use_backend ws11x3 if ws11x3_request
use_backend ws11x4 if ws11x4_request
use_backend ws11x5 if ws11x5_request
use_backend ws11x6 if ws11x6_request
#ws12
use_backend ws12x1 if ws12x1_request
use_backend ws12x2 if ws12x2_request
use_backend ws12x3 if ws12x3_request
use_backend ws12x4 if ws12x4_request
use_backend ws12x5 if ws12x5_request
use_backend ws12x6 if ws12x6_request
#---------------------------------------------------------------------
# BACKEND - APP
#---------------------------------------------------------------------
backend app
timeout server 50000ms #To counter the WS default
mode http
balance roundrobin
option httpchk HEAD /upchk.txt
server app1 app1:8000 maxconn 100000 check
server app2 app2:8000 maxconn 100000 check
server app3 app3:8000 maxconn 100000 check
server app4 app4:8000 maxconn 100000 check
#---------------------------------------------------------------------
# BACKENDs - WS
#---------------------------------------------------------------------
#Server ws11
backend ws11x1
server ws11 ws11:8001 maxconn 100000
backend ws11x2
server ws11 ws11:8002 maxconn 100000
backend ws11x3
server ws11 ws11:8003 maxconn 100000
backend ws11x4
server ws11 ws11:8004 maxconn 100000
backend ws11x5
server ws11 ws11:8005 maxconn 100000
backend ws11x6
server ws11 ws11:8006 maxconn 100000
#Server ws12
backend ws12x1
server ws12 ws12:8001 maxconn 100000
backend ws12x2
server ws12 ws12:8002 maxconn 100000
backend ws12x3
server ws12 ws12:8003 maxconn 100000
backend ws12x4
server ws12 ws12:8004 maxconn 100000
backend ws12x5
server ws12 ws12:8005 maxconn 100000
backend ws12x6
server ws12 ws12:8006 maxconn 100000
#---------------------------------------------------------------------
# BACKEND - STATIC
#---------------------------------------------------------------------
backend static
server static1 static1:80 maxconn 40000
100 000 подключений - это много ... Вы так сильно напираете? Если да ... возможно, разделение внешнего интерфейса так, чтобы он привязывался к одному IP-адресу для статического контента и одному IP-адресу для содержимого приложения, а затем запускал варианты static и app как отдельные процессы haproxy (при условии, что у вас есть второе ядро / процессор на сервере) ...
Если ничего другого, это сузит использование до приложения или статических потоков ...
Если я правильно помню свой сетевой класс 101 ... HaProxy не должен ударить 100,000
связи с ws12:8001
или любой другой backend host: port из-за ограничения порта ~ 65536, который ближе к 28232
в большинстве систем (cat /proc/sys/net/ipv4/ip_local_port_range
). Возможно, вы исчерпываете локальные порты, что, в свою очередь, может привести к зависанию процессора, когда он ожидает освобождения портов.
Возможно, уменьшение максимального количества подключений к каждому бэкэнду до 28000 решит проблему? Или изменить диапазон локальных портов на более широкий?
Взгляните на настройку nbproc и посмотрите, помогает ли это, используя более одного ядра. Для большинства аппаратных балансировщиков нагрузки объем трафика, который вы можете обработать, ограничен вашим процессором / памятью балансировщика нагрузки.
1.5) Increasing the overall processing power
--------------------------------------------
On multi-processor systems, it may seem to be a shame to use only one processor,
eventhough the load needed to saturate a recent processor is far above common
usage. Anyway, for very specific needs, the proxy can start several processes
between which the operating system will spread the incoming connections. The
number of processes is controlled by the 'nbproc' parameter in the 'global'
section. It defaults to 1, and obviously works only in 'daemon' mode. One
typical usage of this parameter has been to workaround the default per-process
file-descriptor limit that Solaris imposes to user processes.
Example :
---------
global
daemon
quiet
nbproc 2
Вне настройки haproxy это поможет немного настроить сеть.
Одна конкретная вещь, которая может помочь, - это убедиться, что ваши сетевые интерфейсы не привязаны к одному процессору (при условии, что вы используете несколько интерфейсов). Если вы используете haproxy в Linux, вы можете проверить баланс следующим образом:
egrep CPU\|eth /proc/interrupts
Например, это показывает, что прерывания для eth0 и eth1 обрабатываются разными процессорами:
$ egrep CPU\|eth /proc/interrupts
CPU0 CPU1 CPU2 CPU3
103: 3515635238 0 0 0 IR-PCI-MSI-edge eth0
104: 0 1976927064 0 0 IR-PCI-MSI-edge eth1
Принимая во внимание, что это показывает, что они обрабатываются одним и тем же процессором:
$ egrep CPU\|eth /proc/interrupts
CPU0 CPU1 CPU2 CPU3
272: 1526254507 0 0 0 Dynamic-irq eth0
273: 4877925 0 0 0 Dynamic-irq eth1
Вы захотите включить привязку smp для этих интерфейсов. В приведенном выше примере вы можете сделать следующее:
echo 010 > /proc/irq/272/smp_affinity
echo 010 > /proc/irq/273/smp_affinity
Я предлагаю активировать «Многопоточный режим», поместив параметр nbthread в глобальный раздел. От мужчины:
Этот параметр доступен только при встроенной поддержке потоков. Он создает потоки для каждого созданного процесса. Это означает, что если HAProxy запущен на переднем плане, он создает потоки только для первого процесса.
Мы активировали «Многопоточный режим», и наш сайт стал работать на x15 быстрее. Вы можете узнать больше о многопроцессорном и многопоточном варианте здесь: https://www.haproxy.com/blog/multithreading-in-haproxy/